<<<
:sectnums:
== On-Chip Debugger (OCD)

The NEORV32 Processor features an _on-chip debugger_ (OCD) implementing the **execution-based debugging** scheme
compatible to the **Minimal RISC-V Debug Specification**. A copy of the specification is available in `docs/references`.
The on-chip debugger is implemented via the <<_processor_top_entity_generics, `OCD_EN`>> processor top generic.

**Key Features**

* standard 4-wire JTAG access port
* full control of the CPU: halting, single-stepping and resuming
* indirect access to all core registers and the entire processor address space (via program buffer)
* compatible with upstream OpenOCD and GDB
* optional trigger module for hardware breakpoints
* optional authentication for increased security

.Hands-On Tutorial
[TIP]
A simple example on how to use NEORV32 on-chip debugger in combination with OpenOCD and the GNU debugger is shown in
section https://stnolting.github.io/neorv32/ug/#_debugging_using_the_on_chip_debugger[Debugging using the On-Chip Debugger]
of the User Guide.

**Section Structure**

* <<_debug_transport_module_dtm>>
* <<_debug_module_dm>>
* <<_debug_authentication>>
* <<_cpu_debug_mode>>
* <<_trigger_module>>

The NEORV32 on-chip debugger is based on five hardware modules:

.NEORV32 on-chip debugger complex
image::neorv32_ocd_complex.png[align=center]

[start=1]
. <<_debug_transport_module_dtm>>: JTAG access tap to allow an external  adapter to interface with the _debug module (DM)_.
. <<_debug_module_dm>>: RISC-V debug module that is configured by the DTM. From the CPU's perspective this module behaves as
another memory-mapped peripheral that can be accessed via the processor-internal bus. The memory-mapped registers provide an
internal _data buffer_ for data transfer from/to the DM, a _code ROM_ containing the "park loop" code, a _program buffer_ to
allow the debugger to execute small programs defined by the DM and a _status register_ that is used to communicate _exception_,
_halt_, _resume_ and _execute_ requests/acknowledges from/to the DM.
. <<_debug_authentication>>: Authenticator module to secure on-chip debugger access. This module implements a very simple
authentication mechanism as example. Users can modify/replace this default logic to implement arbitrary authentication mechanism.
. <<_cpu_debug_mode>> ISA extension: This ISA extension provides the "debug execution mode" as another operation mode that is
used to execute the park loop code from the DM. This mode also provides additional CSRs and instructions.
. CPU <<_trigger_module>>: This module provides a single _hardware_ breakpoint.

**Theory of Operation**

When debugging the system using the OCD, the debugger (like GDB) issues a halt request to the CPU to make the it enter
_debug mode_. In this mode the application-defined architectural state of the system/CPU is "frozen" so the debugger
can monitor it without interfering with the actual application. However, the OCD can also modify the entire architectural
state at any time. While in debug mode, the debugger has full control over the entire CPU and processor operating at
highest-privileged mode.

While in debug mode, the CPU executes the "park loop" code from the code ROM of the debug module (DM).
This park loop implements an endless loop, where the CPU polls a memory-mapped <<_status_register>> that is
controlled by the DM. The flags in this register are used to communicate requests from the DM and to acknowledge
them by the CPU: trigger execution of the program buffer or resume the halted application. Furthermore, the CPU
uses this register to signal that the CPU has halted after a halt request or to signal that an exception has been
raised while being in debug mode.


<<<
// ####################################################################################################################
:sectnums:
=== Debug Transport Module (DTM)

The debug transport module "DTM" (VHDL module: `rtl/core/neorv32_debug_dtm.vhd`) provides a standard 4-wire JTAG test
access port ("tap") via the following top-level ports:

.JTAG top level signals
[cols="^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Name          | Width | Direction | Description
| `jtag_tck_i`  | 1     | in        | serial clock
| `jtag_tdi_i`  | 1     | in        | serial data input
| `jtag_tdo_o`  | 1     | out       | serial data output
| `jtag_tms_i`  | 1     | in        | mode select
|=======================

.Maximum JTAG Clock
[IMPORTANT]
All JTAG signals are synchronized to the processor's clock domain. Hence, no additional clock domain is required for the DTM.
However, this constraints the maximal JTAG clock frequency (`jtag_tck_i`) to be less than or equal to **1/5** of the processor
clock frequency (`clk_i`).

.JTAG TAP Reset
[NOTE]
The NEORV32 JTAG TAP does not provide a dedicated reset signal ("TRST"). However, the missing TRST is not a problem,
since JTAG-level resets can be triggered using with TMS signaling.

.Maintaining JTAG Chain
[NOTE]
If the on-chip debugger is disabled the JTAG serial input `jtag_tdi_i` is directly
connected to the JTAG serial output `jtag_tdo_o` to maintain the JTAG chain.

JTAG accesses are based on a single 5-bit _instruction register_ `IR` and several _data registers_ `DR`
with different sizes. The individual data registers are accessed by writing the according address to the instruction
register. The following table shows the available data registers and their addresses:

.JTAG TAP registers
[cols="^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Address (via `IR`) | Name     | Size (bits) | Description
| `00001`            | `IDCODE` | 32          | identifier, version and part ID fields are hardwired to zero, manufacturer ID is assigned via the <<_processor_top_entity_generics, `JEDEC_ID`>> generic
| `10000`            | `DTMCS`  | 32          | debug transport module control and status register (see below)
| `10001`            | `DMI`    | 41          | debug module interface: 7-bit address, 32-bit read/write data, 2-bit operation (`00` = NOP; `10` = write; `01` = read)
| others             | `BYPASS` | 1           | default JTAG bypass register
|=======================

.`DTMCS` - DTM Control and Status Register
[cols="^2,^3,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit(s) | Name           | R/W | Description
| 31:18  | -              | r/- | _reserved_, hardwired to zero
| 17     | `dmihardreset` | r/w | setting this bit will reset the debug module interface; this bit auto-clears
| 16     | `dmireset`     | r/w | setting this bit will clear the sticky error state; this bit auto-clears
| 15     | -              | r/- | _reserved_, hardwired to zero
| 14:12  | `idle`         | r/- | recommended idle states (= 0, no idle states required)
| 11:10  | `dmistat`      | r/- | DMI status: `00` = no error, `01` = reserved, `10` = operation failed, `11` = failed operation during pending DMI operation
| 9:4    | `abits`        | r/- | number of address bits in `DMI` register (= 6)
| 3:0    | `version`      | r/- | `0001` = DTM is compatible to RISC-V debug spec. versions v0.13 and v1.0
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Debug Module (DM)

The debug module "DM" (VHDL module: `rtl/core/neorv32_debug_dm.vhd`) acts as a translation interface between abstract
operations issued by the debugger application (like GDB) and the platform-specific debugger hardware.
It supports the following features:

* Gives the debugger necessary information about the implementation.
* Allows the hart to be halted/resumed/reset and provides the current status.
* Provides abstract read and write access to the halted hart's general purpose registers.
* Provides access to a reset signal that allows debugging from the very first instruction after reset.
* Provides a _program buffer_ to force the hart to execute arbitrary instructions.
* Allows memory access from a hart's point of view.
* Optionally implements an authentication mechanism to secure on-chip debugger access.

The NEORV32 DM follows the "Minimal RISC-V External Debug Specification" to provide full debugging capabilities while
keeping resource/area requirements at a minimum. It implements the **execution based debugging scheme** for a
single hart and provides the following architectural core features:

* program buffer with 2 entries and an implicit `ebreak` instruction
* indirect bus access via the CPU using the program buffer
* abstract commands: "access register" plus auto-execution
* halt-on-reset capability
* optional authentication

.DM Spec. Version
[TIP]
The NEORV32 DM complies to the RISC-V DM spec version 1.0.

From the DTM's point of view, the DM implements a set of <<_dm_registers>> that are used to control and monitor the
debugging session. From the CPU's point of view, the DM implements several memory-mapped registers that are used for
communicating debugging control and status (<<_dm_cpu_access>>).


:sectnums:
==== DM Registers

The DM is controlled via a set of registers that are accessed via the DTM. The following registers are implemented:

.Unimplemented Registers
[NOTE]
Write accesses to registers that are not implemented are simply ignored and read accesses
to these registers will always return zero.

.Available DM registers
[cols="^2,^3,<7"]
[options="header",grid="rows"]
|=======================
| Address | Name                     | Description
| 0x04    | <<_data0>>               | Abstract data 0, used for data transfer between debugger and processor
| 0x10    | <<_dmcontrol>>           | Debug module control
| 0x11    | <<_dmstatus>>            | Debug module status
| 0x12    | <<_hartinfo>>            | Hart information
| 0x16    | <<_abstracts>>           | Abstract control and status
| 0x17    | <<_command>>             | Abstract command
| 0x18    | <<_abstractauto>>        | Abstract command auto-execution
| 0x1d    | `nextdm`                 | Base address of next DM; reads as zero to indicate there is only one DM
| 0x20    | <<_progbuf, `progbuf0`>> | Program buffer 0
| 0x21    | <<_progbuf, `progbuf1`>> | Program buffer 1
| 0x30    | <<_authdata>>            | Data to/from the authentication module
| 0x38    | `sbcs`                   | System bus access control and status; reads as zero to indicate there is **no** system bus access
|=======================


:sectnums!:
===== **`data0`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x04 | **Abstract data 0** | `data0`
3+| Reset value: `0x00000000`
3+| Basic read/write data exchange register to be used with abstract commands (for example to read/write data from/to CPU GPRs).
|======


:sectnums!:
===== **`dmcontrol`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x10 | **Debug module control register** | `dmcontrol`
3+| Reset value: `0x00000000`
3+| Control of the overall debug module and the hart. The following table shows all implemented bits. All remaining bits/bit-fields
are configured as "zero" and are read-only. Writing '1' to these bits/fields will be ignored.
|======

.`dmcontrol` Register Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit | Name [RISC-V]  | R/W | Description
| 31  | `haltreq`      | -/w | set/clear hart halt request
| 30  | `resumereq`    | -/w | request hart to resume
| 28  | `ackhavereset` | -/w | write `1` to clear `*havereset` flags
|  1  | `ndmreset`     | r/w | put whole system (except OCD) into reset state when `1`
|  0  | `dmactive`     | r/w | DM enable; writing `0`-`1` will reset the DM
|=======================


:sectnums!:
===== **`dmstatus`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x11 | **Debug module status register** | `dmstatus`
3+| Reset value: `0x00400083`
3+| Current status of the overall debug module and the hart. The entire register is read-only.
|======

.`dmstatus` Register Bits
[cols="^1,^2,<10"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]     | Description
| 31:23 | _reserved_        | reserved; zero
| 22    | `impebreak`       | `1`: indicates an implicit `ebreak` instruction after the last program buffer entry
| 21:20 | _reserved_        | reserved; zero
| 19    | `allhavereset`    .2+| `1` when the hart is in reset
| 18    | `anyhavereset`
| 17    | `allresumeack`    .2+| `1` when the hart has acknowledged a resume request
| 16    | `anyresumeack`
| 15    | `allnonexistent`  .2+| zero to indicate the hart is always existent
| 14    | `anynonexistent`
| 13    | `allunavail`      .2+| `1` when the DM is disabled to indicate the hart is unavailable
| 12    | `anyunavail`
| 11    | `allrunning`      .2+| `1` when the hart is running
| 10    | `anyrunning`
|  9    | `allhalted`       .2+| `1` when the hart is halted
|  8    | `anyhalted`
|  7    | `authenticated`   | set if authentication passed; see <<_debug_authentication>>
|  6    | `authbusy`        | set if authentication is busy, see <<_debug_authentication>>
|  5    | `hasresethaltreq` | `0`: halt-on-reset is not supported (directly)
|  4    | `confstrptrvalid` | `0`: no configuration string available
| 3:0   | `version`         | `0011`: DM compatible to debug spec. version v1.0
|=======================


:sectnums!:
===== **`hartinfo`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x12 | **Hart information** | `hartinfo`
3+| Reset value: _see below_
3+| This register gives information about the hart. The entire register is read-only.
|======

.`hartinfo` Register Bits
[cols="^1,^2,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | Description
| 31:24 | _reserved_    | reserved; zero
| 23:20 | `nscratch`    | `0001`: number of `dscratch*` CPU registers = 1
| 19:17 | _reserved_    | reserved; zero
| 16    | `dataccess`   | `0`: the `data` registers are shadowed in the hart's address space
| 15:12 | `datasize`    | `0001`: number of 32-bit words in the address space dedicated to shadowing the `data` registers (1 register)
| 11:0  | `dataaddr`    | = `dm_data_base_c(11:0)`, signed base address of `data` words (see address map in <<_dm_cpu_access>>)
|=======================


:sectnums!:
===== **`abstracts`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x16 | **Abstract control and status** | `abstracts`
3+| Reset value: `0x02000801`
3+| Command execution info and status.
|======

.`abstracts` Register Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:29 | _reserved_    | r/- | reserved; zero
| 28:24 | `progbufsize` | r/- | `0010`: size of the program buffer (`progbuf`) = 2 entries
| 23:11 | _reserved_    | r/- | reserved; zero
| 12    | `busy`        | r/- | set when a command is being executed
| 11    | `relaxedpriv` | r/- | `1`: PMP rules are ignored when in debug mode
| 10:8  | `cmderr`      | r/w | error during command execution (see below); has to be cleared by writing `111`
| 7:4   | _reserved_    | r/- | reserved; zero
| 3:0   | `datacount`   | r/- | `0001`: number of implemented `data` registers for abstract commands = 1
|=======================

Error codes in `cmderr` (highest priority first):

* `000` - no error
* `100` - command cannot be executed since hart is not in expected state
* `011` - exception during command execution
* `010` - unsupported command
* `001` - invalid DM register read/write while command is/was executing


:sectnums!:
===== **`command`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x17 | **Abstract command** | `command`
3+| Reset value: `0x00000000`
3+| Writing this register will trigger the execution of an abstract command. New command can only be executed if
`cmderr` is zero. The entire register in write-only (reads will return zero).
|======

[NOTE]
The NEORV32 DM only supports **Access Register** abstract commands. These commands can only access the
hart's GPRs x0 - x15/31 (abstract command register index `0x1000` - `0x101f`).

.`command` Register Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]      | R/W | Description / required value
| 31:24 | `cmdtype`          | -/w | `00000000`: indicates "access register" command
| 23    | _reserved_         | -/w | reserved, has to be `0` when writing
| 22:20 | `aarsize`          | -/w | `010`: indicates 32-bit accesses
| 21    | `aarpostincrement` | -/w | `0`: post-increment is not supported
| 18    | `postexec`         | -/w | set if the program buffer is executed _after_ the command
| 17    | `transfer`         | -/w | set if the operation in `write` is conducted
| 16    | `write`            | -/w | `1`: copy `data0` to `[regno]`, `0`: copy `[regno]` to `data0`
| 15:0  | `regno`            | -/w | GPR-access only; has to be `0x1000` - `0x101f`
|=======================


:sectnums!:
===== **`abstractauto`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x18 | **Abstract command auto-execution** | `abstractauto`
3+| Reset value: `0x00000000`
3+| Register to configure if a read/write access to a DM register re-triggers execution of the last abstract command.
|======

.`abstractauto` Register Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]        | R/W | Description
| 17    | `autoexecprogbuf[1]` | r/w | when set reading/writing from/to `progbuf1` will execute `command` again
| 16    | `autoexecprogbuf[0]` | r/w | when set reading/writing from/to `progbuf0` will execute `command` again
|  0    | `autoexecdata[0]`    | r/w | when set reading/writing from/to `data0` will execute `command` again
|=======================


:sectnums!:
===== **`progbuf`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x20 | **Program buffer 0** | `progbuf0`
| 0x21 | **Program buffer 1** | `progbuf1`
3+| Reset value: `0x00000013` ("NOP")
3+| Program buffer (two entries) for the DM.
|======


:sectnums!:
===== **`authdata`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x30 | **Authentication data** | `authdata`
3+| Reset value: _user-defined_
3+| This register serves as a 32-bit serial port to/from the authentication module. See <<_debug_authentication>>.
|======


:sectnums:
==== DM CPU Access

From the CPU's perspective the DM acts like another memory-mapped peripheral. It occupies 256 bytes of the CPU's address
space starting at address `base_io_dm_c`. This address space is divided into four sections of 64 bytes each to provide
access to the _park loop code ROM_, the _program buffer_, the _data buffer_ and the _status register_. The program buffer,
the data buffer and the status register do not fully occupy the 64-byte-wide sections and are mirrored several times to fill
the entire section.

.DM CPU Access - Address Map
[cols="^2,^2,<4"]
[options="header",grid="rows"]
|=======================
| Base address | Physical size | Description
| `0xffffff00` |      64 bytes | ROM for the "park loop" code
| `0xffffff40` |      16 bytes | Program buffer (<<_progbuf>>)
| `0xffffff80` |       4 bytes | Data buffer (<<_data0>>)
| `0xffffffc0` |       4 bytes | Control and <<_status_register>>
|=======================

.DM Register Access
[IMPORTANT]
All memory-mapped registers of the DM can only be accessed by the CPU if it is in debug mode. Hence, the DM registers are not
visible nor accessible for normal CPU operations. Any CPU access outside of debug mode will raise a bus access fault exception.

.Park Loop Code Sources ("OCD Firmware")
[NOTE]
The assembly sources of the park loop code are available in `sw/ocd-firmware/park_loop.S`.


:sectnums:
===== Code ROM Entry Points

The park loop code provides two entry points where code execution can start. These are used to enter the park loop either when
an explicit debug-entry/halt request has been issued (for example a halt request) or when an exception has occurred while executing
code in debug mode.

.Park Loop Entry Points
[cols="^6,<4"]
[options="header",grid="rows"]
|=======================
| Address                                | Description
| `dm_exc_entry_c`  (`base_io_dm_c` + 0) | Exception entry address
| `dm_park_entry_c` (`base_io_dm_c` + 8) | Normal entry address (halt request)
|=======================

When the CPU enters (via an explicit halt request from the dubber) or re-enters debug mode (for example via an `ebreak` in the
DM's program buffer), it jumps to the _normal entry point_ that is configured via the <<_cpu_top_entity_generics, `CPU_DEBUG_PARK_ADDR`>>
CPU generic. By default, this address is set to `dm_park_entry_c`, which is defined in the main
package file. If an exception is encountered during debug mode, the CPU jumps to the address of the _exception entry point_
configured via the <<_cpu_top_entity_generics, `CPU_DEBUG_EXC_ADDR`>> CPU generic. By default, this address
is set to `dm_exc_entry_c`, which is also defined in the main package file.


:sectnums:
===== Status Register

The status register provides a direct communication channel between the CPU's debug-mode executing the park loop
and the debugger-controlled DM. This register is used to communicate requests, which are issued by the
DM, and the according acknowledges, which are generated by the CPU.

There are only 4 bits in this register that are used to implement requests/acknowledges. Each bit is left-aligned
in one sub-byte of the entire 32-bit register. Thus, the CPU can access each bit individually using store-byte (`sb`) and
load-byte (`lb`) instructions. This eliminates the need to perform bit-masking in the park loop code resulting in less code
size and faster execution.

.DM Status Register - CPU Access
[cols="^1,^3,^3,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name               | CPU/DM access      <| Description
|     0 | `sreg_halt_ack`    | CPU write, DM read <| Set by the CPU when halting.
.2+|  8 | `sreg_resume_req`  | DM write, CPU read <| Set by the DM to request the CPU to resume normal operation.
        | `sreg_resume_ack`  | CPU write, DM read <| Set by the CPU before it starts resuming.
.2+| 16 | `sreg_execute_req` | DM write, CPU read <| Set by the DM to request execution of the program buffer.
        | `sreg_execute_ack` | CPU write, DM read <| Set by the CPU before it starts executing the program buffer.
|    24 | `sreg_execute_ack` | CPU write, DM read <| Set by the CPU if an exception occurs while being in debug mode.
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Debug Authentication

Optionally, the on-chip debugger's DM can be equipped with an _authenticator module_ to secure debugger access. This authentication
is enabled by the <<_processor_top_entity_generics, `OCD_AUTHENTICATION`>> top generic. When disabled, the debugger is always
authorized and has unlimited access. When enabled, the debugger is required to authenticate in order to gain access.

The authenticator module is implemented as individual RTL module (`rtl/core/neorv32_debug_auth.vhd`). By default, it implements
a very simple authentication mechanism. Note that this default mechanism is not secure in any way - it is intended as example
logic to illustrate the interface and authentication process. Users can modify the default logic or replace the entire module
to implement a more sophisticated custom authentication mechanism.

The authentication interface is compliant to the RISC-V debug spec and is based on a single CSR and two additional status bits:

* <<_authdata>> CSR: this 32-bit register is used to read/write data from/to the authentication module. It is hardwired to
all-zero if authentication is not implemented.
* <<_dmstatus>> CSR:
** The `authenticated` bit (read-only) is set if authentication was successful. The debugger can access the processor only
if this bit is set. It is automatically hardwired to `1` (always authenticated) if the authentication module is not implemented.
** The `authbusy` bit (read-only) indicates if the authentication module is busy. When set, no data should be written/read to/from
<<_authdata>>. This bit is automatically hardwired to `0` (never busy) if the authentication module is not implemented.

openOCD provides dedicated commands to exchange data with the authenticator module:

.openOCD RISC-V Authentication Commands
[source,tcl]
----
riscv authdata_read        // read 32-bit from authdata CSR
riscv authdata_write value // write 32-bit value to authdata CSR
----

Based on these two primitives arbitrary complex authentication mechanism can be implemented.


:sectnums:
==== Default Authentication Mechanism

[IMPORTANT]
The default authentication mechanism is not secure at all. Replace it by a custom design.

The default authenticator hardware implements a very simple authentication mechanism: a single read/write bit is implemented
that directly corresponds to the `authenticated` bit in <<_dmstatus>>. This bit can be read/written as bit zero (LSB) of the
<<_authdata>> CSR. Writing 1 to this register will result in a successful authentication. The default openOCD configuration
script for the NEORV32 implements this basic authentication mechanism:

.Default authentication process (`sw/openocd/openocd_neorv32.cfg`)
[source,tcl]
----
set challenge [riscv authdata_read]          # read authdata; not required, just an example
riscv authdata_write [expr {$challenge | 1}] # set LSB to authenticate
----


<<<
// ####################################################################################################################
:sectnums:
=== CPU Debug Mode

The NEORV32 CPU Debug Mode is compatible to the **Minimal RISC-V Debug Specification 1.0** `Sdext` (external debug)
ISA extension. When enabled via the CPU's <<_sdext_isa_extension>> generic and/or the processor's `OCD_EN` it adds
a new CPU operation mode ("debug mode"), three additional <<_cpu_debug_mode_csrs>> and one additional instruction
(`dret`) to the core.

Debug-mode is entered on any of the following events:

[start=1]
. The CPU executes an `ebreak` instruction (when in machine-mode and `ebreakm` in <<_dcsr>> is set OR when in user-mode and `ebreaku` in <<_dcsr>> is set).
. A debug halt request is issued by the DM (via CPU `db_halt_req_i` signal, high-active).
. The CPU completes executing of a single instruction while being in single-step debugging mode (`step` in <<_dcsr>> is set).
. A hardware trigger from the <<_trigger_module>> fires (`exe` and `action` in <<_tdata1>> / `mcontrol` are set).

[NOTE]
From a hardware point of view these debug-mode-entry conditions are special traps (synchronous exceptions or
asynchronous interrupts) that are handled transparently by the control logic.

**Whenever the CPU enters debug-mode it performs the following operations:**

* wake-up CPU if it was send to sleep mode by the `wfi` instruction
* switch to debug-mode privilege level
* move the current program counter to <<_dpc>>
* copy the hart's current privilege level to the `prv` flags in <<_dcsr>>
* set `cause` in <<_dcsr>> according to the cause why debug mode is entered
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
* load the address configured via the CPU's (<<_cpu_top_entity_generics, `CPU_DEBUG_PARK_ADDR`>>) generic to the program counter jumping to the
"debugger park loop" code stored in the debug module (DM)

**When the CPU is in debug-mode:**

* while in debug mode, the CPU executes the parking loop and - if requested by the DM - the program buffer
* effective CPU privilege level is `machine` mode; any active physical memory protection (PMP) configuration is bypassed
* the `wfi` instruction acts as a `nop` (also during single-stepping)
* if an exception occurs while being in debug mode:
** if the exception was caused by any debug-mode entry action the CPU jumps to the normal entry point (defined by the
<<_cpu_top_entity_generics, `CPU_DEBUG_PARK_ADDR`>> generic) of the park loop again (for example when executing `ebreak` while in debug-mode)
** for all other exception sources the CPU jumps to the exception entry point (defined by the <<_cpu_top_entity_generics, `CPU_DEBUG_EXC_ADDR`>> generic)
to signal an exception to the DM; the CPU restarts the park loop again afterwards
* interrupts are disabled; however, they will remain pending and will get executed after the CPU has left debug mode and is not being single-stepped
* if the DM makes a resume request, the park loop exits and the CPU leaves debug mode (executing `dret`)
* the standard counters <<_machine_counter_and_timer_csrs>> `[m]cycle[h]` and `[m]instret[h]` are stopped
* all <<_hardware_performance_monitors_hpm_csrs>> are stopped

Debug mode is left either by executing the `dret` instruction or by performing a hardware reset of the CPU.
Executing `dret` outside of debug mode will raise an illegal instruction exception.

**Whenever the CPU leaves debug mode it performs the following operations:**

* set the hart's current privilege level according to the `prv` flags of <<_dcsr>>
* restore the original program counter from <<_dpc>> resuming normal operation


:sectnums:
==== CPU Debug Mode CSRs

Two additional CSRs are required by the "Minimal RISC-V Debug Specification": the debug mode control and status register
`dcsr` and the debug program counter `dpc`. An additional general purpose scratch register for debug-mode-only
(`dscratch0`) allows faster execution by having a fast-accessible backup register. These CSRs are only accessible if the CPU
is in debug mode. If these CSRs are accessed outside of debug mode an illegal instruction exception is raised.


:sectnums!:
===== **`dcsr`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Debug control and status register
| Address     | `0x7b0`
| Reset value | `0x40000410`
| ISA         | `Zicsr` & `Sdext`
| Description | This register is used to configure the debug mode environment and provides additional status information.
|=======================

.Debug control and status register `dcsr` bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:28 | `xdebugver`   | r/- | `0100`: CPU debug mode is compatible to spec. version 1.0
| 27:16 | -             | r/- | `000000000000`: _reserved_
| 15    | `ebereakm`    | r/w | `ebreak` instructions in `machine` mode will _enter_ debug mode when set
| 14    | `ebereakh`    | r/- | `0`: hypervisor mode not supported
| 13    | `ebereaks`    | r/- | `0`: supervisor mode not supported
| 12    | `ebereaku`    | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
| 11    | `stepie`      | r/- | `0`: IRQs are disabled during single-stepping
| 10    | `stopcount`   | r/- | `1`: standard counters and HPMs are stopped when in debug mode
| 9     | `stoptime`    | r/- | `0`: timers increment as usual
| 8:6   | `cause`       | r/- | cause identifier: why debug mode was entered (see below)
| 5     | -             | r/- | `0`: _reserved_
| 4     | `mprven`      | r/- | `1`: `mprv` in <<_mstatus>> is also evaluated when in debug mode
| 3     | `nmip`        | r/- | `0`: non-maskable interrupt is pending
| 2     | `step`        | r/w | enable single-stepping when set
| 1:0   | `prv`         | r/w | CPU privilege level before/after debug mode
|=======================

Cause codes in `dcsr.cause` (highest priority first):

* `010` - triggered by hardware <<_trigger_module>>
* `001` - executed `EBREAK` instruction
* `011` - external halt request (from DM)
* `100` - return from single-stepping


:sectnums!:
===== **`dpc`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Debug program counter
| Address     | `0x7b1`
| Reset value | `0x00000000`
| ISA         | `Zicsr` & `Sdext`
| Description | The register is used to store the current program counter when debug mode is entered. The `dret` instruction will
return to the address stored in `dpc` by automatically moving `dpc` to the program counter.
|=======================

[NOTE]
`dpc[0]` is hardwired to zero. If `IALIGN` = 32 (i.e. <<_c_isa_extension>> is disabled) then `dpc[1]` is also hardwired to zero.


:sectnums!:
===== **`dscratch0`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Debug scratch register 0
| Address     | `0x7b2`
| Reset value | `0x00000000`
| ISA         | `Zicsr` & `Sdext`
| Description | The register provides a general purpose debug mode-only scratch register.
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Trigger Module

"Normal" software breakpoints (using GDB's `b`/`break` command) are implemented by temporarily replacing the according
instruction word by an `[c.]ebreak` instruction. However, this is not possible when debugging code that is executed from
read-only memory (for example when debugging programs that are executed via the <<_execute_in_place_module_xip>>).
To circumvent this limitation a hardware trigger logic allows to (re-)enter debug-mode when instruction execution
reaches a programmable address. These "hardware-assisted breakpoints" are used by GDB's `hb`/`hbreak` commands.

The RISC-V `Sdtrig` ISA extension adds a programmable _trigger module_ to the CPU core that is enabled via the
<<_sdtrig_isa_extension>> generic. The trigger module implements a subset of the features described in the
"RISC-V Debug Specification / Trigger Module" and complies to version v1.0 of the `Sdtrig` spec.

The NEORV32 trigger module features only a _single_ trigger implementing a "type 6 - instruction address match" trigger.
This limitation is granted by the RISC-V debug spec and is sufficient to **debug code executed from read-only memory (ROM)**.
The trigger module can also be used independently of the CPU debug-mode / `Sdext` ISA extension.
Machine-mode software can use the trigger module to raise a breakpoint exception when instruction execution
reaches a programmed address.

.Trigger Timing
[NOTE]
When enabled the address match trigger will fire **BEFORE** the instruction at the programmed address gets executed.

.MEPC & DPC CSRs
[WARNING]
The breakpoint exception when raised by the trigger module behaves different then the "normal" trapping (see
<<_neorv32_trap_listing>>): <<_mepc>> / <<_dpc>> is set to the address of the next instruction that needs to be
executed to preserve the program flow. A "normal" breakpoint exception would set <<_mepc>> / <<_dpc>> to the address
of the actual `ebreak` instruction itself.


:sectnums:
==== Trigger Module CSRs

The `Sdtrig` ISA extension adds 4 additional CSRs that are accessible from debug-mode and also from machine-mode.
Machine-mode write accesses can be ignored by setting ´dmode´ in <<_tdata1>>. This is automatically done by the debugger
if it uses the trigger module for implementing a "hardware breakpoint"

:sectnums!:
===== **`tselect`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Trigger select register
| Address     | `0x7a0`
| Reset value | `0x00000000`
| ISA         | `Zicsr` & `Sdtrig`
| Description | This CSR is hardwired to zero indicating there is only one trigger available. Any write access is ignored.
|=======================


:sectnums!:
===== **`tdata1`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Trigger data register 1, visible as trigger "type 6 match control" (`mcontrol6`)
| Address     | `0x7a1`
| Reset value | `0x60000048`
| ISA         | `Zicsr` & `Sdtrig`
| Description | This CSR is used to configure the address match trigger using "type 6" format.
|=======================

.Match Control CSR (`tdata1`) Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:28 | `type`        | r/- | `0100`: address match trigger type 6
| 27    | `dmode`       | r/w | set to ignore write accesses to <<_tdata1>> and <<_tdata2>> from machine-mode; writable from debug-mode only
| 26    | `uncertain`   | r/- | `0`: trigger satisfies the configured conditions
| 25    | `hit1`        | r/- | `0`: hardwired to zero, only `hit0` is used
| 24    | `vs`          | r/- | `0`: VS-mode not supported
| 23    | `vu`          | r/- | `0`: VU-mode not supported
| 22    | `hit0`        | r/c | set when trigger has fired (**BEFORE** executing the triggering address); must be explicitly cleared by writing zero; writing 1 has no effect
| 21    | `select`      | r/- | `0`: only address matching is supported
| 20:19 | reserved      | r/- | `00`: hardwired to zero
| 18:16 | `size`        | r/- | `000`: match accesses of any size
| 15:12 | `action`      | r/w | `0000` = breakpoint exception on trigger match, `0001` = enter debug-mode on trigger match
| 11    | `chain`       | r/- | `0`: chaining is not supported as there is only one trigger
| 10:6  | `match`       | r/- | `0000`: equal-match only
| 6     | `m`           | r/- | `1`: trigger enabled when in machine-mode
| 5     | `uncertainen` | r/- | `0`: feature not supported, hardwired to zero
| 4     | `s`           | r/- | `0`: supervisor-mode not supported
| 3     | `u`           | r/- | `0`/`1`: trigger enabled when in user-mode, set if `U` ISA extension is enabled
| 2     | `execute`     | r/w | set to enable trigger matching on instruction address
| 1     | `store`       | r/- | `0`: store address/data matching not supported
| 0     | `load`        | r/- | `0`: load address/data matching not supported
|=======================


:sectnums!:
===== **`tdata2`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Trigger data register 2
| Address     | `0x7a2`
| Reset value | `0x00000000`
| ISA         | `Zicsr` & `Sdtrig`
| Description | Since only the "address match trigger" type is supported, this r/w CSR is used to configure the address of the triggering instruction.
Note that the trigger module will fire **before** the instruction at the programmed address gets executed.
|=======================


:sectnums!:
===== **`tinfo`**

[cols="<1,<8"]
[frame="topbot",grid="none"]
|=======================
| Name        | Trigger information register
| Address     | `0x7a4`
| Reset value | `0x01000006`
| ISA         | `Zicsr` & `Sdtrig`
| Description | The CSR shows global trigger information (see below). Any write access is ignored.
|=======================

.Trigger Info CSR (`tinfo`) Bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:24 | `version`     | r/- | `0x01`: compatible to spec. version v1.0
| 23:15 | reserved      | r/- | `0x00`: hardwired to zero
| 15:0  | `info`        | r/- | `0x0006`: only "type 6 trigger" is supported
|=======================
