Debugging - timvideos/litex-buildenv GitHub Wiki
Quickstart to debugging VexRiscv:
- When you instantiate your CPU core, set a
cpu_variant
of"debug"
and register the debug bus on Wishbone:
SoCSDRAM.__init__(self, platform, clk_freq,
cpu_type="vexriscv",
cpu_variant="debug",
**kwargs)
self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu_or_bridge.debug_bus, 0x10)
- Ensure your device is available via some litex bridge (UART, Ethernet, or PCIe.)
- Run
litex_server
to connect to it. This is the same bridge used to access CSRs, so verify that it works. - Build and run
openocd
:
git clone https://github.com/SpinalHDL/openocd_riscv.git
cd openocd_riscv
wget https://github.com/m-labs/VexRiscv-verilog/raw/ef0011d4ffc9ab4efe2f8499c39fc325d56667ad/cpu0.yaml
sudo apt-get install -y libyaml-dev libtool autoconf build-essential git pkg-config pkgconf # or other equivalent command
./bootstrap
./configure --enable-dummy --disable-werror
make
./src/openocd -c 'interface dummy' \
-c 'adapter_khz 1' \
-c 'jtag newtap lx cpu -irlen 4' \
-c 'target create lx.cpu0 vexriscv -endian little -chain-position lx.cpu -dbgbase 0xF00F0000' \
-c 'vexriscv cpuConfigFile cpu0.yaml' \
-c 'vexriscv networkProtocol etherbone' \
-c 'init' \
-c 'reset halt'
You should get an output that looks like the following. This means it's working as intended, and is ready to debug:
~/openocd_riscv$ ./src/openocd -c 'interface dummy' \
> -c 'adapter_khz 1' \
> -c 'jtag newtap lx cpu -irlen 4' \
> -c 'target create lx.cpu0 vexriscv -endian little -chain-position lx.cpu -dbgbase 0xF00F0000' \
> -c 'vexriscv cpuConfigFile cpu0.yaml' \
> -c 'vexriscv networkProtocol etherbone' \
> -c 'init' \
> -c 'reset halt'
Open On-Chip Debugger 0.10.0+dev-00298-g00a8603 (2018-06-25-09:35)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter speed: 1 kHz
lx.cpu0
Info : clock speed 1 kHz
Info : TAP lx.cpu does not have IDCODE
Info : TAP auto0.tap does not have IDCODE
Info : TAP auto1.tap does not have IDCODE
Info : TAP auto2.tap does not have IDCODE
Info : TAP auto3.tap does not have IDCODE
Info : TAP auto4.tap does not have IDCODE
Info : TAP auto5.tap does not have IDCODE
Info : TAP auto6.tap does not have IDCODE
Info : TAP auto7.tap does not have IDCODE
Info : TAP auto8.tap does not have IDCODE
Info : TAP auto9.tap does not have IDCODE
Info : TAP auto10.tap does not have IDCODE
Info : TAP auto11.tap does not have IDCODE
Info : TAP auto12.tap does not have IDCODE
Info : TAP auto13.tap does not have IDCODE
Info : TAP auto14.tap does not have IDCODE
Info : TAP auto15.tap does not have IDCODE
Info : TAP auto16.tap does not have IDCODE
Info : TAP auto17.tap does not have IDCODE
Info : TAP auto18.tap does not have IDCODE
Info : TAP auto19.tap does not have IDCODE
Warn : Unexpected idcode after end of chain: 21 0xfffff800
Error: double-check your JTAG setup (interface, speed, ...)
Error: Trying to use configured scan chain anyway...
Error: lx.cpu: IR capture error; saw 0x0f not 0x01
Warn : Bypassing JTAG setup events due to errors
- Connect gdb:
riscv64-unknown-elf-gdb -ex 'target remote localhost:3333' ./build/software/bios/bios.elf
Notes:
- Breakpoints work, as long as they're in RAM. That means that you can't add breakpoints in the bios, but you can add breakpoints in the firmware.
- Watchpoints don't work. Yet.
- It should be more stable now! If it crashes, that's a bug.
- It is possible to load code via gdb! This is done via the "load" command.
- You can reset the board with "mon reset halt" followed by "continue".