Skip to main content

[RISC-V] [HW-Designer] Instruction/data cache handling in TRACE32 - Knowledgebase / FAQs by core architecture / RISC-V - Lauterbach Support

[RISC-V] [HW-Designer] Instruction/data cache handling in TRACE32

Unfortunately, the RISC-V debug specification does not define an explicit, standardized way to handle instruction- or data caches. Nevertheless, in some scenarios a debugger and/or the debug IP need to be able to trigger certain cache operations, such as cache flushes.

Example #1:

Let's assume an SoC with a single RISC-V core with instruction cache. The core's instruction memory contains a RISC-V instruction 'A'. The RISC-V core gets halted some instructions before the execution of 'A'. The core has not executed 'A' yet, however it has already loaded 'A' into its instruction cache, and into its instruction pipeline. Now the debugger sets a software breakpoint onto 'A', which means it (temporarily) replaces 'A' with an 'EBREAK' instruction. After that, the debugger lets the core resume again. In order to achieve that the core will execute the new 'EBREAK' instruction instead of the originally cached 'A' instruction, the debugger needs to flush the core's instruction cache and instruction pipeline before letting the CPU resume.

Example #2:

Let's assume an SoC with multiple RISC-V cores with data caches. Each core is halted. Each core has already cached the memory data 'X' of an address 'B' in their respective data cache. Now, the debugger uses the direct system bus access to write new data 'Y' into the data memory at address 'B'. When the debugger resumes the cores now, it needs to make sure that each core's data cache does not contain a the old/outdated data 'X' any more. That is why the debugger needs to flush each core's data cache before letting the cores resume, or before reading any memory content from the perspective of one of the cores.


In order to solve the above example scenarios and other scenarios, the debugger uses the program buffer execution of the 'FENCE' and/or 'FENCE.I' instructions. According to the RISC-V ISA specification, these instructions must ensure that a cache and/or pipeline flush (or an equivalent chip-specific operation) will happen, if applicable to the respective chip and if needed in the respective scenario.


The following points show example scenarios in which the debugger usually uses the FENCE and FENCE.I instructions. Of course, the described behavior may not always be applicable, and may also change in future debugger versions.

  1. Resume core: Before the debugger lets a core resume, it will execute both a 'FENCE' and 'FENCE.I' instruction via program buffer.
  2. Read memory via core: Before the debugger reads memory from perspective of a core (via program buffer or 'access memory' abstract command), it will execute a 'FENCE' instruction via program buffer.
  3. Write memory via core: After the debugger has written memory from perspective of a core (via program buffer or 'access memory' abstract command), it will execute a 'FENCE' instruction via program buffer.

The above actions by the debugger are only possible if the hardware's debug IP does have a program buffer with sufficient size. In that case, the debugger will execute the described steps independent of whether the respective core does have any caches or not.

If the hardware's debug IP does however NOT have any program buffer (or a program buffer of insufficient size), then the debugger must assume that the debug IP will automatically handle all respective scenarios itself.

Helpful Unhelpful

2 of 2 people found this page helpful