An instruction tracer records the sequence of instructions that the CPU executes. Since the required bandwidth to record every instruction directly and stream it out through some interface is immense, that’s why we employ a few compression techniques, most notable a method called branch tracing. In branch tracing we only record changes in the control flow which are unpredictable by looking at the executed binary. In RISC-V that boils down to branches, jumps which depends on some registry value and exceptions. Every time the CPU hits such a discontinuity, we emit a packet which contains enough information to describe the changes. Such a sequence of packages and the binary which as used to produced it can be used to reconstruct the original sequence of executed instructions, as long as we don’t have any self-modifying code.
If one is interested in not only the instructions but also their operand values, such as the read and written data and their address, then one would have to do data tracing. Drawbacks are that bandwidth rises dramatically compared to plain instruction tracing and that the implementation becomes more complicated, but this solves the self-modying code problem.
On the PULP platform we rarely deal with the self-modying code issue except for the interrupt vector table, which gets populated during runtime. This problem can be solved withouth employing data tracing by emitting additional packets during an exception, so as to record the first instruction of the exception handler.
This project currently contains an instruction tracer for the RISCY core of the PULP platform (RTL model), a C model of the tracer and C routines to decompress recorded traces in the packet format.
The used packet format is described here.
. |-- doc |-- driver Trace debugger driver for the PULP platform |-- include |-- rtl RTL model of the trace debugger |-- tb Testbench, uses the C model as golden model |-- trdb Decompression routines and C model |-- waves |-- LICENSE |-- Makefile |-- README.org This file `-- src_files.yml Configuration file to use it as an IP in the PULP platform
Make sure that the environment variables VSIM
and RISCV
point to your
simulator and RISC-V toolchain respectively. Checkout the repository like
by calling
git clone --recurse https://github.com/pulp-platform/trace_debugger.
Build the tests by calling
make generate-tests-64
This will fetch spike and riscv-tests and put them into trdb/
. These are
then run and the instruction traces captured which in turn can be fed to the
rtl testbench by finally calling
make test
If everything works out the test should print ALL TESTS PASSED
.
Trdb is a command line tool which can produce the same output has the hardware trace debugger given a stimuli file, decompress received packets given the original binary and also show objdump like disassembly of the reconstructed instruction sequence. More information on usage and examples can be found here.
Make sure you have setup the PULP SDK as described there and have put in in
your $PATH$
environment variable. Then run make driver-all
.
Run make TAGS
to generate etag files for emacs.
There is no documentation for the hardware yet.