Debugging - timvideos/litex-buildenv GitHub Wiki

Quickstart to debugging VexRiscv:

  1. 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)
  1. Ensure your device is available via some litex bridge (UART, Ethernet, or PCIe.)
  2. Run litex_server to connect to it. This is the same bridge used to access CSRs, so verify that it works.
  3. 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
  1. Connect gdb:
riscv64-unknown-elf-gdb -ex 'target remote localhost:3333' ./build/software/bios/bios.elf

Notes:

  1. 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.
  2. Watchpoints don't work. Yet.
  3. It should be more stable now! If it crashes, that's a bug.
  4. It is possible to load code via gdb! This is done via the "load" command.
  5. You can reset the board with "mon reset halt" followed by "continue".