Build the debugger (this will place the executable in target/release/debugger):
cargo build --release
To run the debugger:
./dbg <path_to_vcd>
This will actually search in multiple places and add the .vcd extension if it doesn't exist; for example
./dbg cpu
will try to find cpu.vcd or build/cpu.vcd.
To run the debugger locally, replace the above ./debugger with cargo run, e.g.
cargo run <path_to_vcd>
To display individual module screens, the debugger relies on certain signals inside of the
SystemVerilog modules to be present. Examples of these are: dbg_this_is_cpu for the cpu module, dbg_this_is_dcache for the dcache module, etc. If these signals are present, the debugger will attempt to render hardcoded data structures of our design, looking for keys defined in the code (src/headers.rs). If your design doesn't use the same data structures as ours, however, the debugger will likely panic. As such, the debugger will likely not work well out of the box for other processors. It will still show a basic screen and allow you to watch arbitrary signals, but most/all tables will not work.
The debugger is also not very memory-efficient. Performance will likely degrade on .vcd files larger than 30MB.
The code here is admittedly not great. However, here is a brief description of the repository structure:
src/main.rsis the entry point of the program, and is the first thing called. Initializes the Ratatui app as well as argument parsing and logging setup.src/app.rsis where app logic is; the implementations here describe how the main app functions and renders things. This also handles keyboard events.src/snapshots.rsis where the logic for parsing, storing, and handling queries to the vcd file is. It defines aSnapshotsstruct, which stores objects that hold the values of every variable at every point in time. It also stores an index that keeps track of which snapshot is currently shown, and defines where helper functions likeget_varget their values from.src/var_index.rsdefines a struct which parses all the variables in a header and stores them in an index object for quick lookup and fuzzy search.src/structures/defines the various tables for the different data structures we define in the processor (ROB, RS, etc.), and the top-level module defines how to render these/initializes them.
Disclaimer: This guide is for Apple Silicon Macs (tested on M3 MacBook Air). If you have a different system, you will need to find out how to cross compile to x86 Linux.
To cross-compile to CAEN, you will need to install the rust tool chain for targeting Linux:
rustup target add x86_64-unknown-linux-gnu
You will also need to install a linker for x86_64:
brew install SergioBenitez/osxct/x86_64-unknown-linux-gnu
Then, you can run the compilation command:
TARGET_CC=x86_64-unknown-linux-gnu cargo build --release --target x86_64-unknown-linux-gnu
To transfer to CAEN:
scp target/x86_64-unknown-linux-gnu/release/debugger <your uniqname>@login.engin.umich.edu:~/eecs470/p4-w25.group1
Remember to change the username and path for your CAEN credentials and desired path!