Skip to content

Python Debugger

Kai Meinhard edited this page Dec 30, 2020 · 2 revisions

Overview:

This repository contains a Python script that opens a CLI that implements methods to debug a RISC-V core connect over the AXI to JTAG module. It is not a replacement for a traditional debugger like GDB. Instead it acts an example on how to use the register map of the AXI to JTAG converter module. Additionally it is a showcase how to access register of the RISC-V debug module and the RISC-V core connected to it.

In order to understand why certain debug commands might fail it is important to know the components that can be accessed with it. There are the following 4 levels of components that can be accessed with this debugger:

  1. AXI to JTAG Converter
  2. JTAG Slave of the RISC-V Core
  3. Registers of the Debug Module
  4. Registers of the RISC-V Core itself

When the access to a module does not return reasonable values, all following levels will not do that either. Reasonable values usually means non zero values but it this dependent on the state of the hardware.

Example:

This Python debugger can be useful when a RISC-V binary never finishes and the line of code where the RISC-V core is stuck is required. Or it can be used to used to determine the state of a program in a line of code by setting a breakpoint. Currently the only way to set a breakpoint is to insert an EBREAK instruction into the RISC-V binary. This can be done by inserting asm("EBREAK"); into the C-Code.

Usually registers of the RISC-V Core matter the most for debugging. Those can be accessed with read_register XXXX and write_register XXXX. If those commands fail it might be useful to verify the functionality of all previous components:

  1. AXI to JTAG Converter:
    • Execute readDTM 0, this should read 0xABBA in the most significant bits
  2. JTAG Slave of the RISC-V Core
    • Execute readDTM 1, this should read the IDCODE of the JTAG slave
    • The value of IDCODE is either hard coded, a parameter or an input value to the JTAG slave
  3. Registers of the Debug Module
    • Execute read abstractcs the field in the lowest 4 bit reads the number of data register which is at least 1
    • Also possible is read all which will read all relevant registers of the Debug Module (Cam potentially be 0)
    • It might be necessary to activate the DM by executing activate_dm
  4. Registers of the RISC-V Core itself
    • Depending on the RISC-V Core it might be required to halt it with halt_req
    • Either execute read_gprs for all GPRs or read register 7b1 which will read the PC
    • Important here is that reading registers can cause exceptions visible with detail_abstractcs that has to be cleared in order to execute commands again (clear_cmderr)

List of commands:

The command line interface of the python script is created with the cmd package and supports therefore only explicitly implemented methods. A list of all possible commands can be acquired by typing ?.

Accessing AXI_to_JTAG module and JTAG slave module:

  • readDTM
  • reset_core
  • reset_rv

Accessing Debug Module:

  • read XXXX: Place holder can be either all or a DM register name

Accessing RISC-V Core:

  • read_register XXXX
  • write_register XXXX
  • read_gprs