In the previous post I added a fork of the RISC-V ISA simulator. In this post you can see how it can be used.
The source code for this example is on github, here: https://github.com/five-embeddev/riscv-scratchpad/tree/master/baremetal-vcd-trace.
This small program handles the
mti and trap interrupts and updates some global variables when interrupts occur.
main.c program sets up a vectored interrupt handler and a 1Mhz
machine timer interrupt. Each time the core wakes from
wfi it calls
ecall to trigger the exception handler. Various global variables are
updated inside of the interrupt handlers so the status can be
// Global to hold current timestamp, written in MTI handler. static volatile uint64_t timestamp = 0; // Some variables that can be traced and be of interest static volatile uint8_t count_123 = 0; static volatile uint64_t wakeup_count = 0; static volatile uint64_t ecall_count = 0; // Count each interrupt static volatile uint32_t mti_count = 0; static volatile uint32_t msi_count = 0; static volatile uint32_t mei_count = 0;
run_sim.cmd sets up a trace for the global variables and asserts the
e.g. Trace some variables:
trace timestamp trace count_123 trace wakeup_count trace mei_count trace mti_count trace msi_count trace ecall_count
e.g. assert interrupts
interrupt 0 raise mei run 100 interrupt 0 clear mei ... run 300 interrupt 0 raise msi run 10 interrupt 0 clear msi
- A RISC-V GCC Cross Compiler: https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/tag/v12.1.0-2/
- A forked riscv-isa-sim to run the simulation: https://github.com/five-embeddev/riscv-isa-sim/tree/vcd_trace
- GTKWave to view the results: https://github.com/gtkwave/gtkwave
Running a Simulation
run_sim.sh and set
SPIKE=../../riscv-isa-sim/spike to the path of the RISC-V ISA Simulator.
make source ./run_sim.sh vcd2fst vcd-trace.vcd vcd-trace.fst gtkwave vcd-trace.fst vcd-trace.gtkw
The trace below shows:
- Global variables update over time, particularly after interrupts.
- Interrupt strobes.
- CSR changes to setup and process interrupts.
- Processor registers (pc, ra, gp, sp)
In this case you can see clearly an external interrupt
entered repeatedly, blocking the CPU as the ISR does not service the
external source. This sort of error is hard to see using a debugger,
but clear on a waveform trace.