rv_tracer

April 10, 2026 ยท View on GitHub

rv_tracer

SHL-0.51 license

rv_tracer is developed as part of the PULP project, a joint effort between ETH Zurich and the University of Bologna.


License

Unless specified otherwise in the respective file headers, all code checked into this repository is made available under a permissive license. All hardware sources and tool scripts are licensed under the Solderpad Hardware License 0.51 (see LICENSE) or compatible licenses, except for files contained in the img directory, which are licensed under the Creative Commons Attribution-NoDerivates 4.0 International license (CC BY-ND 4.0).
The file generate_do.py is licensed under Apache 2.0 license.


Short summary

Supported features
FeatureImplemented
Branch Trace
Delta address mode:white_check_mark:
Full address mode:white_check_mark:
Implicit exception mode:x:
Sequentially inferable jump mode:x:
Implicit return mode:x:
Branch prediction mode:x:
Jump target cache mode:x:
Instruction Trace Interface
Single-retirement:white_check_mark:
Multiple-retirement:white_check_mark:
Trigger unit:white_check_mark:
Data Trace:x:
Instruction Trace Output Packets
Time:x:
Context:x:

Testing progress
ModuleTested
rv_tracer:white_check_mark:
te_branch_map:white_check_mark:
te_filter:white_check_mark:
te_packet_emitter:white_check_mark: (no format 0 packets)
te_priority:white_check_mark:
te_reg:white_check_mark:
te_resync_counter:white_check_mark:

How to run it

After downloading the repo, move inside the repo:

cd rv_tracer

Then run the simulation:

make run

Between one run and the other launch:

make clean

Design

The modules defined are the following:

  • te_reg: stores configuration data, produces clock signal for the other modules;
  • te_resync_counter: counts packets emitted or clock cycles and asks for a resynchronization packet;
  • te_branch_map: counts the branches and keeps track if they were taken or not;
  • te_filter: declares input blocks as "qualified" - they can be processed by the next modules - based on user-defined values read from te_reg;
  • te_priority: determines which packet needs to be emitted and performs a simple compression on the address that is put inside the payload;
  • te_packet_emitter: populates the payload and can reset both the te_resync_counter and te_branch_map.

High level rv_tracer architecture

Figure 1: high level rv_tracer architecture


te_reg

This module stores the user and non-user definable parameters.

The user-definable parameters are the following:

  • trace_activated
  • nocontext
  • notime
  • encoder_mode
  • configuration
  • lossless_trace
  • shallow_trace
  • parameters necessary for the te_filter module

The clock_gated signal depends on the trace_activated signal.

te_reg internal architecture

Figure 2: te_reg internal architecture

APB Protocol

To access the registers, an APB interface is required.

Signal NameSourceWidthDescription
PCLKClock1Clock
PADDRRequesterADDR_WIDTHAddress
PSELxRequester1Select
PENABLERequester1Enable
PWRITERequester1Direction
PWDATARequesterDATA_WIDTHWrite data
PREADYCompleter1Ready
PRDATACompleterDATA_WIDTHRead data

te_branch_map

The te_branch_map module keeps track of branches using a counter and a branch map.

te_branch_map internal architecture

Figure 5: te_branch_map internal architecture


te_filter

The te_filter filters input blocks to trace specific portions of code.

te_filter internal architecture

Figure 6: te_filter internal architecture


te_priority

Determines which packet needs to be emitted.

Flow chart determining packet type

Figure 7: flow chart determining packet type


te_packet_emitter

The te_packet_emitter module populates the payload according to inputs from te_priority.

te_packet_emitter internal architecture

Figure 11: te_packet_emitter internal architecture


te_resync_counter

Counts emitted packets or elapsed clock cycles and signals when resynchronization is required.

te_resync_counter internal architecture

Figure 12: te_resync_counter internal architecture


Multiple Retirement Support

Many RISC-V cores can retire up to N instructions per cycle.

Multiple Retirement: Branches Only

Figure 13: rv_tracer architecture for up to N branches in the same cycle


Multiple Retirement: Not Only Branches

Figure 14: rv_tracer architecture for up to N discontinuities in the same cycle


Cite this work

If you use rv_tracer in your research, please cite:

@article{laghi2025efficient,
  title={Efficient Trace for RISC-V: Design, Evaluation, and Integration in CVA6},
  author={Laghi, Umberto and Manoni, Simone and Parisi, Emanuele and Bartolini, Andrea},
  journal={arXiv preprint arXiv:2504.01972},
  year={2025}
}