Overview

This document specifies the processor debug system. The debug system implements run-control debug and bus access functionality according to the RISC-V Debug Specification 0.13.2. It can be accessed over JTAG (IEEE Std 1149.1-2013).

Features

  • Run-control debug functionality according to the RISC-V Debug Specification version 0.13.2, which includes all standard debug features: breakpoints, stepping, access to the CPU's GPRs and arbitrary memory locations.
  • Implementation following the Execution Based method as outlined in Section A.2 of the RISC-V Debug Specification. This allows the execution of arbitrary instructions on the core and requires minimal changes to the core.
  • JTAG Debug Transport Module (DTM) according to the RISC-V Debug Specification.
  • System Bus Access with generic 32 or 64 bit bus interface.
  • Support for up to 2^20 harts through one Debug Module
  • Support for arbitrary memory location of DM
  • Support for one debug scratch register if the DM is located at the zero page.

Description

The debug system described in this document consists of two modules, which are implemented according to the RISC-V Debug Specification: The Debug Module (DM) implemented with a Program Buffer, and a JTAG Debug Transport Module (DTM).

Compatibility

The debug system is compatible with the RISC-V Debug Specification 0.13.2. The specification marks some features as optional. The status of these features is visible from the table below.

FeatureSupport
External triggers (Section 3.6)Not supported at this time.
Halt groups (Section 3.6)Not supported at this time.
Hardware triggersNot supported at this time. Triggers read 0 according to the specification.
System Bus Access (SBA) (Section 3.10)Supported with generic 32 or 64 bit wide interface.
AuthenticationNot supported at this time.
Non-intrusive access to core registersNot supported at this time. All registers must be accessed through the program buffer.

Theory of Operations

The functionality of the debug system is implemented according to the RISC-V Debug Specification. Refer to this document for more information.

Block Diagram

Block diagram of the debug system

Debug Module Registers

An external debugger performs all interaction with the Debug Module through a register interface, accessed over a dedicated bus, the Debug Module Interface (DMI). The registers are called “Debug Module Registers” and defined in the RISC-V Debug Specification, Section 3.14. Our implementation only provides a single Debug Module on the DMI bus mapped to base address 0, hence all addresses below can be considered absolute.

AddressNameImplementation Notes
0x04Abstract Data 0 (data0)
0x0fAbstract Data 11 (data11)
0x10Debug Module Control (dmcontrol)see table below
0x11Debug Module Status (dmstatus)see table below
0x12Hart Info (hartinfo)
0x13Halt Summary 1 (haltsum1)
0x14Hart Array Window Select (hawindowsel)
0x15Hart Array Window (hawindow)
0x16Abstract Control and Status (abstractcs)
0x17Abstract Command (command)
0x18Abstract Command Autoexec (abstractauto)
0x19Configuration String Pointer 0 (confstrptr0)
0x1aConfiguration String Pointer 1 (confstrptr1)
0x1bConfiguration String Pointer 2 (confstrptr2)
0x1cConfiguration String Pointer 3 (confstrptr3)
0x1dNext Debug Module (nextdm)
0x1fCustom Features (custom)
0x20Program Buffer 0 (progbuf0)
0x2fProgram Buffer 15 (progbuf15)
0x30Authentication Data (authdata)
0x32Debug Module Control and Status 2 (dmcs2)
0x34Halt Summary 2 (haltsum2)
0x35Halt Summary 3 (haltsum3)
0x37System Bus Address 127:96 (sbaddress3)
0x38System Bus Access Control and Status (sbcs)
0x39System Bus Address 31:0 (sbaddress0)
0x3aSystem Bus Address 63:32 (sbaddress1)
0x3bSystem Bus Address 95:64 (sbaddress2)
0x3cSystem Bus Data 31:0 (sbdata0)
0x3dSystem Bus Data 63:32 (sbdata1)
0x3eSystem Bus Data 95:64 (sbdata2)
0x3fSystem Bus Data 127:96 (sbdata3)
0x40Halt Summary 0 (haltsum0)

dmcontrol (0x10)

FieldAccess(Reset) ValueComment
haltreqWARZ
resumereqW1
hartresetWARL0Not implemented, reads constant 0
ackhaveresetW1
haselWARL0Hart array masks are not supported
hartselloR/W
hartselhiR/W
setresethaltreqW1-Writing this register is a no-op. Halt-on-reset is not implemented, as indicated by dmstatus.hasresethaltreq.
clrresethaltreqW1-Writing this register is a no-op. Halt-on-reset is not implemented, as indicated by dmstatus.hasresethaltreq.
ndmresetR/W
dmactiveR/W

dmstatus (0x11)

FieldAccess(Reset) ValueComment
impebreakR0No implicit ebreak is inserted after the Program Buffer.
allhaveresetRHart array masks are not supported; identical to anyhavereset.
anyhaveresetRHart array masks are not supported; identical to allhavereset.
allresumeackRHart array masks are not supported; identical to anyresumeack.
anyresumeackRHart array masks are not supported; identical to allresumeack.
allnonexistentRHart array masks are not supported; identical to anynonexistent
anynonexistentRHart array masks are not supported; identical to allnonexistent
allunavailRHart array masks are not supported; identical to anyunavail.
anyunavailRHart array masks are not supported; identical to allunavail.
allrunningRHart array masks are not supported; identical to anyrunning.
anyrunningRHart array masks are not supported; identical to allrunning.
allhaltedRHart array masks are not supported; identical to anyhalted.
anyhaltedRHart array masks are not supported; identical to allhalted.
authenticatedR1Authentication is not implemented, reads always 1.
authbusyR0Authentication is not implemented, reads always 0.
hasresethaltreqR0Halt-on-reset is not implemented, reads always 0.
confstrptrvalidR0Configuration strings are not supported.
versionR2Specification version 0.13

Customization

The debug system can be configured at synthesis time through parameters.

Parameter NameValid valuesDefaultDescription
NrHarts1..2^201Number of connected harts
BusWidth32, 6432Bus width (for debug memory and SBA busses)
SelectableHarts1Bitmask to select physically available harts for systems that don't use hart numbers in a contiguous fashion.

In addition to these parameters, additional configuration is provided through top-level signals, which are expected to be set to a fixed value at synthesis time.

Signal NameData TypeWidthDescription
hartinfohartinfo_tNrHartsValue of the hartinfo DM register, see the RISC-V Debug Specification v0.13, Section 3.14.2 for details. nscratch: Number of debug scratch registers. Must be set to 2. dataaccess: Must be set to 1. (The data register are shadowed in the hart's memory.) datasize: Must be set to dm::DataCount. dataaddr: Must be set to dm::DataAddr (0x380).

SystemVerilog definition of the hartinfo_t structure

typedef struct packed {
  logic [31:24] zero1;
  logic [23:20] nscratch;
  logic [19:17] zero0;
  logic         dataaccess;
  logic [15:12] datasize;
  logic [11:0]  dataaddr;
} hartinfo_t;

Hardware Interfaces

The debug system interacts with multiple components, which are described in this section. The Debug Module interacts the debugged hart(s) through the core interface, with the system bus through its bus host and device, and with system management and reset functionality, and with the Debug Transport Module through the Debug Module Interface (DMI).

The JTAG Debug Transport Module interacts with the host PC through JTAG, and with the Debug Module through the Debug Module Interface (DMI).

System Interface

SignalDirectionDescription
clk_iinputclock. All components of the debug module and the DMI are synchronous to this clock, except for the JTAG components, which are clocked with the external TCLK.
rst_niinputasynchronous, active low reset.
testmode_iinputnot used currently
ndmreset_ooutputNon-Debug Mode reset (ndmreset). ndmreset is triggered externally through JTAG, e.g. by a debugger, and should reset the whole system except for the debug system. See the RISC-V Debug Specification v0.13, Section 3.2 (Reset Control) for more details.
dmactive_ooutputdebug module is active

SystemVerilog interface definition

input  logic                  clk_i,
input  logic                  rst_ni,
input  logic                  testmode_i,
output logic                  ndmreset_o,
output logic                  dmactive_o

Core Interface

The debug system is compatible with any RISC-V compliant CPU core, given that it support execution based debugging according to the RISC-V Debug Specification, Section A.2.

Debug Request Interrupt

The debug request interrupt is a level-sensitive interrupt. It is issued by the Debug Module to the hart(s).

SignalDirectionDescription
debug_req_o[NrHarts-1:0]outputLevel-sensitive debug request interrupt

The Debug Module issues the debug request to request the core to enter its debug mode. In consequence, the core is expected to

  • jump to the halt address in the Debug ROM,
  • save pc in dpc,
  • update dcsr.

Auxiliary Signalling

SignalDirectionDescription
unavailable_i[NrHarts-1]inputSet to 0 to mark the hart has unavailable (e.g.: power down). This information is made available to the debugger through the dmstatus.allunavail and dmstatus.anyavail fields.

Debug Control and Status Register (CSRs)

Four debug-specific CSRs must be supported by the core, as described in the Debug Specification Section 4.8.

AddressNameAccessDescription
0x7b0dcsrfield-dependent; check specDebug Control and Status
0x7b1dpcRW from Debug Mode onlyDebug PC
0x7b2dscratch0RW from Debug Mode onlyDebug Scratch Register 0
0x7b3dscratch1RW from Debug Mode onlyDebug Scratch Register 1 (only required if DM is not located at address 0x0)

DRET Instruction

To return from debug mode the DRET instruction must be supported by the core according to the Debug Specification Section 4.7.

JTAG

The JTAG Debug Transport Module (JTAG DTM) provides a standard IEEE 1149.1 JTAG connection.

SignalDirectionDescription
tck_iinputTest Clock
tms_iinputTest Mode Select
td_iinputTest Data In (host to debug system)
td_ooutputTest Data Out (debug system to host)
tdo_oe_ooutputTDO output enable
trst_niinputTest Reset (active low). Usage of TRST is optional, but recommended for reliable reset functionality.

Bus Interface

The Debug Module connects to the system bus as device, exposing the debug memory (the Program Buffer and the Debug ROM), and as host for the System Bus Access (SBA) functionality. The same generic bus interface is used in both cases. The bus width is configurable to be 32 or 64 bit using the BusWidth parameter.

Host (Master) Interface

The bus host interface is compatible to the instruction and data interfaces of Ibex.

SignalWidth (bit)DirectionDescription
req1outputRequest valid, must stay high until gnt is high for one cycle
addBusWidthoutputAddress, word aligned
weBusWidthoutputWrite Enable, high for writes, low for reads. Sent together with req
be1outputByte Enable. Is set for the bytes to write/read, sent together with req
wdataBusWidthoutputData to be written to device, sent together with req
gnt1inputThe device accepted the request. Host outputs may change in the next cycle.
r_valid1inputr_rdata hold valid data when r_valid is high. This signal will be high for exactly one cycle per request.
r_rdataBusWidthinputData read from the device

No error response is currently implemented.

SystemVerilog interface definition (host side)

output logic                  req_o,
output logic [BusWidth-1:0]   add_o,
output logic                  we_o,
output logic [BusWidth-1:0]   wdata_o,
output logic [BusWidth/8-1:0] be_o,
input  logic                  gnt_i,
input  logic                  r_valid_i,
input  logic [BusWidth-1:0]   r_rdata_i

SystemVerilog interface definition (device side)

input  logic                  slave_req_i,
input  logic                  slave_we_i,
input  logic [BusWidth-1:0]   slave_addr_i,
input  logic [BusWidth/8-1:0] slave_be_i,
input  logic [BusWidth-1:0]   slave_wdata_i,
output logic [BusWidth-1:0]   slave_rdata_o

OBI Bus Interface (optional)

A wrapper (called dm_obi_top) is provided which wraps the Debug Module (dm_top) and makes it OBI compliant. This wrapper can be ignored (and dm_top can be used directly instead) in case of non OBI compatible systems.

The OBI (Open Bus Interface) specification is at https://github.com/openhwgroup/core-v-docs/blob/master/cores/cv32e40p/.

The Debug Module connects to the system bus as device, exposing the debug memory (the Program Buffer and the Debug ROM), and as host for the System Bus Access (SBA) functionality. The bus interface is according to the OBI specification in both cases. The bus width is configurable to be 32 or 64 bit using the BusWidth parameter. The transfer identifier width is configurable using the IdWidth parameter.

Host (Master) OBI Interface

Compared to dm_top the slave interface of dm_obi_top has the following additional signals: slave_gnt_o, slave_rvalid_o, slave_aid_i, slave_rid_o. Compared to dm_top the master interface of dm_obi_top has some renamed signals (master_addr_o, master_rvalid_i, master_rdata_i instead of master_add_o, master_r_valid_i, master_r_rdata_i).

Both interfaces are OBI compliant.

SignalWidth (bit)DirectionDescription
req1outputRequest valid, must stay high until gnt is high for one cycle
addrBusWidthoutputAddress, word aligned
weBusWidthoutputWrite Enable, high for writes, low for reads. Sent together with req
be1outputByte Enable. Is set for the bytes to write/read, sent together with req
wdataBusWidthoutputData to be written to device, sent together with req
gnt1inputThe device accepted the request. Host outputs may change in the next cycle.
rvalid1inputr_rdata hold valid data when r_valid is high. This signal will be high for exactly one cycle per request.
rdataBusWidthinputData read from the device

No error response is currently implemented.

SystemVerilog interface definition (host side)

output logic                  master_req_o,
output logic [BusWidth-1:0]   master_addr_o,
output logic                  master_we_o,
output logic [BusWidth-1:0]   master_wdata_o,
output logic [BusWidth/8-1:0] master_be_o,
input  logic                  master_gnt_i,
input  logic                  master_rvalid_i,
input  logic [BusWidth-1:0]   master_rdata_i

SystemVerilog interface definition (device side)

input  logic                  slave_req_i,
output logic                  slave_gnt_o,
input  logic                  slave_we_i,
input  logic [BusWidth-1:0]   slave_addr_i,
input  logic [BusWidth/8-1:0] slave_be_i,
input  logic [BusWidth-1:0]   slave_wdata_i,
input  logic [IdWidth-1:0]    slave_aid_i,
output logic                  slave_rvalid_o,
output logic [BusWidth-1:0]   slave_rdata_o,
output logic [IdWidth-1:0]    slave_rid_o

The Debug Module Interface (DMI)

The Debug Module Interface is a bus connecting the JTAG Debug Transport Module (DTM) with the Debug Module (DM). The Debug Specification does not require a specific implementation or hardware interface of the DMI bus. Our implementation is inspired by the implementation used by the Rocket Chip Generator.

Transfers on the DMI are performed on two channels, a request and a response channel. A valid and a ready signal on each channel is used for handshaking.

DMI Request Channel

A DMI request is issued from a DMI host to a DMI device.

SignalWidth (bit)DirectionDescription
addr7host -> deviceAddress of a debug module register (c.f. Section 3.14 of the RISC-V Debug Specification)
op2host -> devicePerformed operation: DTM_NOP = 2‘h0, DTM_READ = 2’h1, DTM_WRITE = 2'h2
data32host -> devicewrite data
valid1host -> devicehandshaking: request is valid
ready1device -> hosthandshaking: transaction processed

SystemVerilog interface definition (host side)

typedef enum logic [1:0] {
  DTM_NOP   = 2'h0,
  DTM_READ  = 2'h1,
  DTM_WRITE = 2'h2
} dtm_op_e;

typedef struct packed {
  logic [6:0]  addr;
  dtm_op_e     op;
  logic [31:0] data;
} dmi_req_t;

output logic     dmi_req_valid_o,
input  logic     dmi_req_ready_i,
output dmi_req_t dmi_req_o

DMI Response Channel

SignalWidth (bit)DirectionDescription
resp2device -> hostResult of the operation. DTM_SUCCESS = 2'h0
data32device -> hostrequested read data
valid1device -> hosthandshaking: response is valid
ready1host -> devicehandshaking: transaction processed

SystemVerilog interface definition (host side)

typedef struct packed  {
  logic [31:0] data;
  logic [1:0]  resp;
} dmi_resp_t;

input  dmi_resp_t dmi_resp_i,
output logic      dmi_resp_ready_o,
input  logic      dmi_resp_valid_i

Protocol

A DMI transaction consists of a request and a response. A DMI host issues a request on the request channel. The request is transmitted as soon as both ready and valid are high. After some time, the device sends the answers the request on the response channel. The response is considered sent as soon as ready and valid of the response channel are both high. A transaction is completed as soon as the response is received by the host. Only one transaction may be active at any given time.

The following timing diagram shows two DMI transactions.

A READ transaction, reading address 0x12 successfully, the value 0x1234 is returned. A WRITE transaction, writing the value 0xabcd to address 0x34 successfully.

DMI protocol

System Bus Access

The system bus and all attached peripherals, including the memories, can be accessed from the host system through the System Bus Access (SBA) component. A typical use case is writing the program memory through this interface, or verifying its contents. The implementation conforms to the RISC-V Debug Specification v0.13, refer to this document for further information.

Debug Memory

The Debug Module exposes a 16 kB memory over its device bus interface. This memory is called the Debug Memory. It consists of a ROM portion, containing the Debug ROM, multiple memory-mapped control and status registers, and a RAM portion, the Program Buffer. The Debug Memory should only be accessible from the CPU if it is in debug mode.

Debug Memory Map

The memory map is an implementation detail of the Debug Module and should not be relied on when using the Debug Module.

AddressDescription
0x0 to 0x0ffunused
0x100Halted. Write to this address to acknowledge that the core is halted.
0x104Going. Write to this address to acknowledge that the core is executing.
0x108Resuming. Write to this address to acknowledge that the core is resuming non-debug operation.
0x10cException. An exception was triggered while the core was in debug mode.
0x300WhereTo
0x338 to 0x35fAbstractCmd
0x360 to 0x37fProgram Buffer (8 words)
0x380 to 0x388DataAddr
0x400 to 0x7ffFlags
0x800 to 0x1000Debug ROM
0x800HaltAddress. Entry point into the Debug Module. The core must jump to this address when it was requested to halt.
0x804ResumeAddress. Entry point into the Debug Module. Jumping to this address instructs the debug module to bring the core out of debug mode and back into normal operation mode.
0x808ExceptionAddress. Entry point into the Debug Module. The core must jump to this address when it receives an exception while being in debug mode.

(Note: The debug memory addressing scheme is adopted from the Rocket Chip Generator.)