OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [on_chip_debugger.adoc] - Blame information for rev 68

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
<<<
2
:sectnums:
3
== On-Chip Debugger (OCD)
4
 
5
The NEORV32 Processor features an _on-chip debugger_ (OCD) implementing **execution-based debugging** that is compatible
6
to the **Minimal RISC-V Debug Specification Version 0.13.2**.
7
Please refer to this spec for in-deep information.
8
A copy of the specification is available in `docs/references/riscv-debug-release.pdf`.
9
The NEORV32 OCD provides the following key features:
10
 
11
* JTAG test access port
12
* run-control of the CPU: halting, single-stepping and resuming
13
* executing arbitrary programs during debugging
14
* accessing core registers (direct access to GPRs, indirect access to CSRs via program buffer)
15
* indirect access to the whole processor address space (via program buffer))
16
* compatible to the https://github.com/riscv/riscv-openocd[RISC-V port of OpenOCD];
17
  pre-built binaries can be obtained for example from https://www.sifive.com/software[SiFive]
18
 
19 61 zero_gravi
.OCD Security Note
20
[IMPORTANT]
21
Access via the OCD is _always authenticated_ (`dmstatus.authenticated` == `1`). Hence, the
22 65 zero_gravi
_whole system_ can always be accessed via the on-chip debugger. Currently, there is no option
23
to disable the OCD via software. The OCD can only be disabled by disabling implementation
24
(setting _ON_CHIP_DEBUGGER_EN_ generic to _false_).
25 61 zero_gravi
 
26 60 zero_gravi
[NOTE]
27
The OCD requires additional resources for implementation and _might_ also increase the critical path resulting in less
28
performance. If the OCD is not really required for the _final_ implementation, it can be disabled and thus,
29
discarded from implementation. In this case all circuitry of the debugger is completely removed (no impact
30
on area, energy or timing at all).
31
 
32
[TIP]
33
A simple example on how to use NEORV32 on-chip debugger in combination with `OpenOCD` and `gdb`
34 62 zero_gravi
is shown in section https://stnolting.github.io/neorv32/ug/#_debugging_using_the_on_chip_debugger[Debugging using the On-Chip Debugger]
35
of the User Guide.
36 60 zero_gravi
 
37
The NEORV32 on-chip debugger complex is based on three hardware modules:
38
 
39
.NEORV32 on-chip debugger complex
40
image::neorv32_ocd_complex.png[align=center]
41
 
42
[start=1]
43
. <<_debug_transport_module_dtm>> (`rtl/core/neorv32_debug_dtm.vhd`): External JTAG access tap to allow an external
44
  adapter to interface with the _debug module(DM)_ using the _debug module interface (dmi)_.
45
. <<_debug_module_dm>> (`rtl/core/neorv32_debug_tm.vhd`): Debugger control unit that is configured by the DTM via the
46
  the _dmi_. Form the CPU's "point of view" this module behaves as a memory-mapped "peripheral" that can be accessed
47
  via the processor-internal bus. The memory-mapped registers provide an internal _data buffer_ for data transfer
48
  from/to the DM, a _code ROM_ containing the "park loop" code,   a _program buffer_ to allow the debugger to
49
  execute small programs defined by the DM and a _status register_ that is used to communicate
50
  _halt_, _resume_ and _execute_ requests/acknowledges from/to the DM.
51
. CPU <<_cpu_debug_mode>> extension (part of`rtl/core/neorv32_cpu_control.vhd`):
52
  This extension provides the "debug execution mode" which executes the "park loop" code from the DM.
53
  The mode also provides additional CSRs.
54
 
55
**Theory of Operation**
56
 
57
When debugging the system using the OCD, the debugger issues a halt request to the CPU (via the CPU's
58
`db_halt_req_i` signal) to make the CPU enter _debug mode_. In this state, the application-defined architectural
59
state of the system/CPU is "frozen" so the debugger can monitor and even modify it.
60
While in debug mode, the CPU executes the "park loop" code from the _code ROM_ of the DM.
61
This park loop implements an endless loop, in which the CPU polls the memory-mapped _status register_ that is
62
controlled by the _debug module (DM)_. The flags of these register are used to communicate _requests_ from
63
the DM and to _acknowledge_ them by the CPU: trigger execution of the program buffer or resume the halted
64
application.
65
 
66
 
67
 
68
<<<
69
// ####################################################################################################################
70
:sectnums:
71
=== Debug Transport Module (DTM)
72
 
73
The debug transport module (VHDL module: `rtl/core/neorv32_debug_dtm.vhd`) provides a JTAG test access port (TAP).
74
The DTM is the first entity in the debug system, which connects and external debugger via JTAG to the next debugging
75
entity: the debug module (DM).
76 61 zero_gravi
External JTAG access is provided by the following top-level ports.
77 60 zero_gravi
 
78
.JTAG top level signals
79
[cols="^2,^2,^2,<8"]
80
[options="header",grid="rows"]
81
|=======================
82
| Name          | Width | Direction | Description
83
| `jtag_trst_i` | 1     | in        | TAP reset (low-active); this signal is optional, make sure to pull it _high_ if it is not used
84
| `jtag_tck_i`  | 1     | in        | serial clock
85
| `jtag_tdi_i`  | 1     | in        | serial data input
86
| `jtag_tdo_o`  | 1     | out       | serial data output
87
| `jtag_tms_i`  | 1     | in        | mode select
88
|=======================
89
 
90 68 zero_gravi
.Maximum JTAG Clock
91 60 zero_gravi
[IMPORTANT]
92 68 zero_gravi
All JTAG signals are synchronized to the processor clock domain by oversampling them in DTM. Hence, no additional
93
clock domain is required for the DTM. However, this constraints the maximal JTAG clock frequency (`jtag_tck_i`) to be less
94
than or equal to **1/5** of the processor clock frequency (`clk_i`).
95 60 zero_gravi
 
96
[NOTE]
97
If the on-chip debugger is disabled (_ON_CHIP_DEBUGGER_EN_ = false) the JTAG serial input `jtag_tdi_i` is directly
98
connected to the JTAG serial output `jtag_tdo_o` to maintain the JTAG chain.
99
 
100
[WARNING]
101
The NEORV32 JTAG TAP does not provide a _boundary check_ function (yet?). Hence, physical device pins cannot be accessed.
102
 
103
The DTM uses the "debug module interface (dmi)" to access the actual debug module (DM).
104
These accesses are controlled by TAP-internal registers.
105
Each registers is selected by the JTAG instruction register (`IR`) and accessed through the JTAG data register (`DR`).
106
 
107
[NOTE]
108
The DTM's instruction and data registers can be accessed using OpenOCDs `irscan` and `drscan` commands.
109
The RISC-V port of OpenOCD also provides low-level command (`riscv dmi_read` & `riscv dmi_write`) to access the _dmi_
110
debug module interface.
111
 
112
JTAG access is conducted via the *instruction register* `IR`, which is 5 bit wide, and several *data registers* `DR`
113
with different sizes.
114
The data registers are accessed by writing the according address to the instruction register.
115
The following table shows the available data registers:
116
 
117
.JTAG TAP registers
118
[cols="^2,^2,^2,<8"]
119
[options="header",grid="rows"]
120
|=======================
121
| Address (via `IR`) | Name     | Size [bits] | Description
122
| `00001`            | `IDCODE` | 32          | identifier, default: `0x0CAFE001` (configurable via package's `jtag_tap_idcode_*` constants)
123
| `10000`            | `DTMCS`  | 32          | debug transport module control and status register
124
| `10001`            | `DMI`    | 41          | debug module interface (_dmi_); 7-bit address, 32-bit read/write data, 2-bit operation (`00` = NOP; `10` = write; `01` = read)
125
| others             | `BYPASS` | 1           | default JTAG bypass register
126
|=======================
127
 
128 68 zero_gravi
.`DTMCS` - DTM Control and Status Register
129
[cols="^2,^3,^1,<8"]
130
[options="header",grid="rows"]
131
|=======================
132
| Bit(s) | Name           | r/w | Description
133
| 31:18  | -              | r/- | _reserved_, hardwired to zero
134
| 17     | `dmihardreset` | r/w | setting this bit will reset the DM interface; this bit auto-clears
135
| 16     | `dmireset`     | r/w | setting this bit will clear ste sticky error state; this bit auto-clears
136
| 15     | -              | r/- | _reserved_, hardwired to zero
137
| 14:12  | `idle`         | r/- | recommended idle states (= 0, no idle states required)
138
| 11:10  | `dmistat`      | r/- | DMI statu: `00` = no error, `01` = reserved, `10` = operation failed, `11` = failed operation during pending DMI operation
139
| 9:4    | `abits`        | r/- | number of DMI address bits (= 7)
140
| 3:0    | `version`      | r/- | `0001` = spec version 0.13
141
|=======================
142
 
143 60 zero_gravi
[INFO]
144
See the https://github.com/riscv/riscv-debug-spec[RISC-V debug specification] for more information regarding the data
145 68 zero_gravi
registers and operations. A local copy can be found in `docs/references`.
146 60 zero_gravi
 
147
 
148
 
149
<<<
150
// ####################################################################################################################
151
:sectnums:
152
=== Debug Module (DM)
153
 
154
According to the RISC-V debug specification, the DM (VHDL module: `rtl/core/neorv32_debug_dm.vhd`)
155
acts as a translation interface between abstract operations issued by the debugger and the platform-specific
156
debugger implementation. It supports the following features (excerpt from the debug spec):
157
 
158
* Gives the debugger necessary information about the implementation.
159
* Allows the hart to be halted and resumed and provides status of the current state.
160
* Provides abstract read and write access to the halted hart's GPRs.
161
* Provides access to a reset signal that allows debugging from the very first instruction after reset.
162
* Provides a mechanism to allow debugging the hart immediately out of reset. (_still experimental_)
163
* Provides a Program Buffer to force the hart to execute arbitrary instructions.
164
* Allows memory access from a hart's point of view.
165
 
166
The NEORV32 DM follows the "Minimal RISC-V External Debug Specification" to provide full debugging
167
capabilities while keeping resource (area) requirements at a minimum level.
168
It implements the **execution based debugging scheme** for a single hart and provides the following
169
hardware features:
170
 
171
* program buffer with 2 entries and implicit `ebreak` instruction afterwards
172
* no _direct_ bus access (indirect bus access via the CPU)
173
* abstract commands: "access register" plus auto-execution
174
* no _dedicated_ halt-on-reset capabilities yet (but can be emulated)
175
 
176
The DM provides two "sides of access": access from the DTM via the _debug module interface (dmi)_ and access from the
177
CPU via the processor-internal bus. From the DTM's point of view, the DM implements a set of <<_dm_registers>> that
178
are used to control and monitor the actual debugging. From the CPU's point of view, the DM implements several
179
memory-mapped registers (within the _normal_ address space) that are used for communicating debugging control
180
and status (<<_dm_cpu_access>>).
181
 
182
 
183
:sectnums:
184
==== DM Registers
185
 
186
The DM is controlled via a set of registers that are accessed via the DTM's _dmi_.
187
The "Minimal RISC-V Debug Specification" requires only a subset of the registers specified in the spec.
188
The following registers are implemented.
189
Write accesses to any other registers are ignored and read accesses will always return zero.
190
Register names that are encapsulated in "( )" are not actually implemented; however, they are listed to explicitly show
191
their functionality.
192
 
193
.Available DM registers
194
[cols="^2,^3,<7"]
195
[options="header",grid="rows"]
196
|=======================
197
| Address | Name           | Description
198
|  `0x04` | `data0`        | Abstract data 0, used for data transfer between debugger and processor
199
|  `0x10` | `dmcontrol`    | Debug module control
200
|  `0x11` | `dmstatus`     | Debug module status
201
|  `0x12` | `hartinfo`     | Hart information
202
|  `0x16` | `abstracts`    | Abstract control and status
203
|  `0x17` | `command`      | Abstract command
204
|  `0x18` | `abstractauto` | Abstract command auto-execution
205
|  `0x1d` | (`nextdm`)     | Base address of _next_ DM; read as zero to indicate there is only _one_ DM
206
|  `0x20` | `progbuf0`     | Program buffer 0
207
|  `0x21` | `progbuf1`     | Program buffer 1
208
|  `0x38` | (`sbcs`)       | System bus access control and status; read as zero to indicate there is no _direct_ system bus access
209
|  `0x40` | `haltsum0`     | Halt summary 0
210
|=======================
211
 
212
 
213
:sectnums!:
214
===== **`data`**
215
 
216
[cols="4,27,>7"]
217
[frame="topbot",grid="none"]
218
|======
219
| 0x04 | **Abstract data 0** | `data0`
220
3+| Reset value: _UNDEFINED_
221
3+| Basic read/write registers to be used with abstract command (for example to read/write data from/to CPU GPRs).
222
|======
223
 
224
 
225
:sectnums!:
226
===== **`dmcontrol`**
227
 
228
[cols="4,27,>7"]
229
[frame="topbot",grid="none"]
230
|======
231
| 0x10 | **Debug module control register** | `dmcontrol`
232
3+| Reset value: 0x00000000
233
3+| Control of the overall debug module and the hart. The following table shows all implemented bits. All remaining bits/bit-fields are configures as "zero" and are
234
read-only. Writing '1' to these bits/fields will be ignored.
235
|======
236
 
237
.`dmcontrol` - debug module control register bits
238
[cols="^1,^2,^1,<8"]
239
[options="header",grid="rows"]
240
|=======================
241
| Bit | Name [RISC-V]  | R/W | Description
242
| 31  | `haltreq`      | -/w | set/clear hart halt request
243
| 30  | `resumereq`    | -/w | request hart to resume
244
| 28  | `ackhavereset` | -/w | write `1` to clear `*havereset` flags
245
|  1  | `ndmreset`     | r/w | put whole processor into reset when `1`
246
|  0  | `dmactive`     | r/w | DM enable; writing `0`-`1` will reset the DM
247
|=======================
248
 
249
 
250
:sectnums!:
251
===== **`dmstatus`**
252
 
253
[cols="4,27,>7"]
254
[frame="topbot",grid="none"]
255
|======
256
| 0x11 | **Debug module status register** | `dmstatus`
257
3+| Reset value: 0x00000000
258
3+| Current status of the overall debug module and the hart. The entire register is read-only.
259
|======
260
 
261
.`dmstatus` - debug module status register bits
262
[cols="^1,^2,<10"]
263
[options="header",grid="rows"]
264
|=======================
265
| Bit   | Name [RISC-V]     | Description
266
| 31:23 | _reserved_        | reserved; always zero
267
| 22    | `impebreak`       | always `1`; indicates an implicit `ebreak` instruction after the last program buffer entry
268
| 21:20 | _reserved_        | reserved; always zero
269
| 19    | `allhavereset`    .2+| `1` when the hart is in reset
270
| 18    | `anyhavereset`
271
| 17    | `allresumeack`    .2+| `1` when the hart has acknowledged a resume request
272
| 16    | `anyresumeack`
273
| 15    | `allnonexistent`  .2+| always zero to indicate the hart is always existent
274
| 14    | `anynonexistent`
275
| 13    | `allunavail`      .2+| `1` when the DM is disabled to indicate the hart is unavailable
276
| 12    | `anyunavail`
277
| 11    | `allrunning`      .2+| `1` when the hart is running
278
| 10    | `anyrunning`
279
|  9    | `allhalted`       .2+| `1` when the hart is halted
280
|  8    | `anyhalted`
281
|  7    | `authenticated`   | always `1`; there is no authentication
282
|  6    | `authbusy`        | always `0`; there is no authentication
283
|  5    | `hasresethaltreq` | always `0`; halt-on-reset is not supported (directly)
284
|  4    | `confstrptrvalid` | always `0`; no configuration string available
285
| 3:0   | `version`         | `0010` - DM is compatible to version 0.13
286
|=======================
287
 
288
 
289
:sectnums!:
290
===== **`hartinfo`**
291
 
292
[cols="4,27,>7"]
293
[frame="topbot",grid="none"]
294
|======
295
| 0x12 | **Hart information** | `hartinfo`
296
3+| Reset value: see below
297
3+| This register gives information about the hart. The entire register is read-only.
298
|======
299
 
300
.`hartinfo` - hart information register bits
301
[cols="^1,^2,<8"]
302
[options="header",grid="rows"]
303
|=======================
304
| Bit   | Name [RISC-V] | Description
305
| 31:24 | _reserved_    | reserved; always zero
306
| 23:20 | `nscratch`    | `0001`, number of `dscratch*` CPU registers = 1
307
| 19:17 | _reserved_    | reserved; always zero
308
| 16    | `dataccess`   | `0`, the `data` registers are shadowed in the hart's address space
309
| 15:12 | `datasize`    | `0001`, number of 32-bit words in the address space dedicated to shadowing the `data` registers = 1
310
| 11:0  | `dataaddr`    | = `dm_data_base_c(11:0)`, signed base address of `data` words (see address map in <<_dm_cpu_access>>)
311
|=======================
312
 
313
 
314
:sectnums!:
315
===== **`abstracts`**
316
 
317
[cols="4,27,>7"]
318
[frame="topbot",grid="none"]
319
|======
320
| 0x16 | **Abstract control and status** | `abstracts`
321
3+| Reset value: see below
322
3+| Command execution info and status.
323
|======
324
 
325
.`abstracts` - abstract control and status register bits
326
[cols="^1,^2,^1,<8"]
327
[options="header",grid="rows"]
328
|=======================
329
| Bit   | Name [RISC-V] | R/W | Description
330
| 31:29 | _reserved_    | r/- | reserved; always zero
331
| 28:24 | `progbufsize` | r/- | `0010`; size of the program buffer (`progbuf`) = 2 entries
332
| 23:11 | _reserved_    | r/- | reserved; always zero
333
| 12    | `busy`        | r/- | `1` when a command is being executed
334
| 11    | _reserved_    | r/- | reserved; always zero
335
| 10:8  | `cmerr`       | r/w | error during command execution (see below); has to be cleared by writing `111`
336
| 7:4   | _reserved_    | r/- | reserved; always zero
337
| 3:0   | `datacount`   | r/- | `0001`; number of implemented `data` registers for abstract commands = 1
338
|=======================
339
 
340
Error codes in `cmderr` (highest priority first):
341
 
342
* `000` - no error
343
* `100` - command cannot be executed since hart is not in expected state
344
* `011` - exception during command execution
345
* `010` - unsupported command
346
* `001` - invalid DM register read/write while command is/was executing
347
 
348
 
349
:sectnums!:
350
===== **`command`**
351
 
352
[cols="4,27,>7"]
353
[frame="topbot",grid="none"]
354
|======
355
| 0x17 | **Abstract command** | `command`
356
3+| Reset value: 0x00000000
357
3+| Writing this register will trigger the execution of an abstract command. New command can only be executed if
358
`cmderr` is zero. The entire register in write-only (reads will return zero).
359
|======
360
 
361
[NOTE]
362
The NEORV32 DM only supports **Access Register** abstract commands. These commands can only access the
363
hart's GPRs (abstract command register index `0x1000` - `0x101f`).
364
 
365
.`command` - abstract command register - "access register" commands only
366
[cols="^1,^2,<8"]
367
[options="header",grid="rows"]
368
|=======================
369 65 zero_gravi
| Bit   | Name [RISC-V]      | R/W | Description / required value
370
| 31:24 | `cmdtype`          | -/w | `00000000` to indicate "access register" command
371
| 23    | _reserved_         | -/w | reserved, has to be `0` when writing
372
| 22:20 | `aarsize`          | -/w | `010` to indicate 32-bit accesses
373 66 zero_gravi
| 21    | `aarpostincrement` | -/w | `0`, post-increment is not supported
374 65 zero_gravi
| 18    | `postexec`         | -/w | if set the program buffer is executed _after_ the command
375
| 17    | `transfer`         | -/w | if set the operation in `write` is conducted
376
| 16    | `write`            | -/w | `1`: copy `data0` to `[regno]`; `0` copy `[regno]` to `data0`
377
| 15:0  | `regno`            | -/w | GPR-access only; has to be `0x1000` - `0x101f`
378 60 zero_gravi
|=======================
379
 
380
 
381
:sectnums!:
382
===== **`abstractauto`**
383
 
384
[cols="4,27,>7"]
385
[frame="topbot",grid="none"]
386
|======
387
| 0x18 | **Abstract command auto-execution** | `abstractauto`
388
3+| Reset value: 0x00000000s
389
3+| Register to configure when a read/write access to a DM repeats execution of the last abstract command.
390
|======
391
 
392
.`abstractauto` - Abstract command auto-execution register bits
393
[cols="^1,^2,^1,<8"]
394
[options="header",grid="rows"]
395
|=======================
396
| Bit   | Name [RISC-V]        | R/W | Description
397
| 17    | `autoexecprogbuf[1]` | r/w | when set reading/writing from/to `progbuf1` will execute `command again`
398
| 16    | `autoexecprogbuf[0]` | r/w | when set reading/writing from/to `progbuf0` will execute `command again`
399
|  0    | `autoexecdata[0]`    | r/w | when set reading/writing from/to `data0` will execute `command again`
400
|=======================
401
 
402
 
403
:sectnums!:
404
===== **`progbuf`**
405
 
406
[cols="4,27,>7"]
407
[frame="topbot",grid="none"]
408
|======
409
| 0x20 | **Program buffer 0** | `progbuf0`
410
| 0x21 | **Program buffer 1** | `progbuf1`
411
3+| Reset value: `NOP`-instruction
412
3+| General purpose program buffer for the DM.
413
|======
414
 
415
 
416
:sectnums!:
417
===== **`haltsum0`**
418
 
419
[cols="4,27,>7"]
420
[frame="topbot",grid="none"]
421
|======
422
| 0x40 | **Halt summary 0** | `haltsum0`
423
3+| Reset value: _UNDEFINED_
424
3+| Bit 0 of this register is set if the hart is halted (all remaining bits are always zero). The entire register is read-only.
425
|======
426
 
427
:sectnums:
428
==== DM CPU Access
429
 
430
From the CPU's point of view, the DM behaves as a memory-mapped peripheral that includes
431
 
432
* a small ROM that contains the code for the "park loop", which is executed when the CPU is _in_ debug mode.
433
* a program buffer populated by the debugger host to execute small programs
434
* a data buffer to transfer data between the processor and the debugger host
435
* a status register to communicate debugging requests
436
 
437
.Park Loop Code Sources
438
[NOTE]
439
The assembly sources of the **park loop code** are available in `sw/ocd-firmware/park_loop.S`. Please note, that these
440
sources are not intended to be changed by the used. Hence, the makefile does not provide an automatic option
441
to compile and "install" the debugger ROM code into the HDL sources and require a manual copy
442
(see `sw/ocd-firmware/README.md`).
443
 
444
The DM uses a total address space of 128 words of the CPU's address space (= 512 bytes) divided into four sections
445
of 32 words (= 128 bytes) each.
446
Please note, that the program buffer, the data buffer and the status register only uses a few effective words in this
447
address space. However, these effective addresses are mirrored to fill up the whole 128 bytes of the section.
448
Hence, any CPU access within this address space will succeed.
449
 
450
.DM CPU access - address map (divided into four sections)
451
[cols="^2,^4,^2,<7"]
452
[options="header",grid="rows"]
453
|=======================
454
| Base address | Name [VHDL package]              | Actual size | Description
455
| `0xfffff800` | `dm_code_base_c` (= `dm_base_c`) |   128 bytes | Code ROM for the "park loop" code
456
| `0xfffff880` | `dm_pbuf_base_c`                 |    16 bytes | Program buffer, provided by DM
457
| `0xfffff900` | `dm_data_base_c`                 |     4 bytes | Data buffer (`dm.data0`)
458
| `0xfffff980` | `dm_sreg_base_c`                 |     4 bytes | Control and status register
459
|=======================
460
 
461
[NOTE]
462
From the CPU's point of view, the DM is mapped to an _"unused"_ address range within the processor's
463
<<_address_space>> right between the bootloader ROM (BOOTROM) and the actual processor-internal IO
464
space at addresses `0xfffff800` - `0xfffff9ff`
465
 
466
When the CPU enters or re-enters (for example via `ebreak` in the DM's program buffer) debug mode, it jumps to
467
the beginning of the DM's "park loop" code ROM at `dm_code_base_c`. This is the _normal entry point_ for the
468
park loop code. If an exception is encountered during debug mode, the CPU jumps to `dm_code_base_c + 4`,
469
which is the _exception entry point_.
470
 
471
**Status Register**
472
 
473
The status register provides a direct communication channel between the CPU executing the park loop and the
474
host-controlled controller of the DM. Note that all bits that can be written by the CPU (acknowledge flags)
475
cause a single-shot (1-cycle) signal to the DM controller and auto-clear (always read as zero).
476
The bits that are driven by the DM controller and are read-only to the CPU and keep their state until the CPU
477
acknowledges the according request.
478
 
479
.DM CPU access - status register
480
[cols="^2,^2,^2,<8"]
481
[options="header",grid="rows"]
482
|=======================
483
| Bit | Name            | CPU access | Description
484
| 0   | `halt_ack`      | -/w        | Set by the CPU to indicate that the CPU is halted and keeps iterating in the park loop
485
| 1   | `resume_req`    | r/-        | Set by the DM to tell the CPU to resume normal operation (leave parking loop and leave debug mode via `dret` instruction)
486
| 2   | `resume_ack`    | -/w        | Set by the CPU to acknowledge that the CPU is now going to leave parking loop & debug mode
487
| 3   | `execute_req`   | r/-        | Set by the DM to tell the CPU to leave debug mode and execute the instructions from the program buffer; CPU will re-enter parking loop afterwards
488
| 4   | `execute_ack`   | -/w        | Set by the CPU to acknowledge that the CPU is now going to execute the program buffer
489
| 5   | `exception_ack` | -/w        | Set by the CPU to inform the DM that an exception occurred during execution of the park loop or during execution of the program buffer
490
|=======================
491
 
492
 
493
 
494
<<<
495
// ####################################################################################################################
496
:sectnums:
497
=== CPU Debug Mode
498
 
499
The NEORV32 CPU Debug Mode `DB` (part of `rtl/core/neorv32_cpu_control.vhd`) is compatible to the "Minimal RISC-V Debug Specification 0.13.2".
500
It is enabled/implemented by setting the CPU generic _CPU_EXTENSION_RISCV_DEBUG_ to "true" (done by setting processor
501
generic _ON_CHIP_DEBUGGER_EN_).
502
It provides a new operation mode called "debug mode".
503
When enabled, three additional CSRs are available (section <<_cpu_debug_mode_csrs>>) and also the "return from debug mode"
504
instruction `dret` is available when the CPU is "in" debug mode.
505
 
506
[IMPORTANT]
507 64 zero_gravi
The CPU _debug mode_ requires the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_
508
and _CPU_EXTENSION_RISCV_Zifencei_ = true).
509 60 zero_gravi
 
510 65 zero_gravi
.Hardware Watchpoints and Breakpoints
511
[NOTE]
512
The NEORV32 CPU _debug mode_ does not provide a hardware "trigger module" (which is optional in the RISC-V debug spec). However, gdb
513
provides a native _emulation_ for code (breakpoints using `break` instruction) and data (polling data watchpoints in automated
514
single-stepping) triggers.
515 60 zero_gravi
 
516 65 zero_gravi
The CPU debug-mode is entered when one of the following events appear:
517
 
518 60 zero_gravi
[start=1]
519
. executing `ebreak` instruction (when `dcsr.ebreakm` is set and in machine mode OR when `dcsr.ebreaku` is set and in user mode)
520
. debug halt request from external DM (via CPU signal `db_halt_req_i`, high-active, triggering on rising-edge)
521
. finished executing of a single instruction while in single-step debugging mode (enabled via `dcsr.step`)
522
 
523
From a hardware point of view, these "entry conditions" are special synchronous (`ebreak` instruction) or asynchronous
524
(single-stepping "interrupt"; halt request "interrupt") traps, that are handled invisibly by the control logic.
525
 
526 65 zero_gravi
.WFI instruction
527
[WARNING]
528
The wait-for-interrupt instruction `wfi` puts the CPU into sleep mode. The CPU will resume normale operation
529
when at least one interrupt source becomes pending (= at least one bit in `mip` CSR is set).
530
However, the CPU will _also resume_ from sleep mode if there is a halt request from the debug module (DM).
531 60 zero_gravi
 
532 65 zero_gravi
Whenever the CPU **enters debug-mode** it performs the following operations:
533
 
534 60 zero_gravi
* move `pc` to `dpcs`
535
* copy the hart's current privilege level to `dcsr.prv`
536
* set `dcrs.cause` according to the cause why debug mode is entered
537
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
538
* load the address configured via the CPU _CPU_DEBUG_ADDR_ generic to the `pc` to jump to "debugger park loop" code in the debug module (DM)
539
 
540 65 zero_gravi
When the CPU **is in debug-mode** the following things are important:
541 60 zero_gravi
 
542
* while in debug mode, the CPU executes the parking loop and the program buffer provided by the DM if requested
543 65 zero_gravi
* effective CPU privilege level is `machine` mode, any PMP configuration is bypassed
544
* the `wfi` instruction acts as a `nop` (also during single-stepping)
545
* if an exception occurs:
546
** if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
547
   (= _CPU_DEBUG_ADDR_) of the park loop again (for example when executing `ebreak` _in_ debug-mode)
548
** for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
549
   to signal an exception to the DM and restarts the park loop again afterwards
550
* interrupts are disabled; however, they will remain pending and will get executed after the CPU has left debug mode
551 60 zero_gravi
* if the DM makes a resume request, the park loop exits and the CPU leaves debug mode (executing `dret`)
552
 
553
Debug mode is left either by executing the `dret` instruction footnote:[`dret` should only be executed _inside_ the debugger
554
"park loop" code (-> code ROM in the debug module (DM).)] (_in_ debug mode) or by performing
555
a hardware reset of the CPU. Executing `dret` outside of debug mode will raise an illegal instruction exception.
556
Whenever the CPU **leaves debug mode** the following things happen:
557
 
558
* set the hart's current privilege level according to `dcsr.prv`
559
* restore `pc` from `dpcs`
560
* resume normal operation at `pc`
561
 
562
 
563
:sectnums:
564
==== CPU Debug Mode CSRs
565
 
566
Two additional CSRs are required by the _Minimal RISC-V Debug Specification_: The debug mode control and status register
567
`dcsr` and the program counter `dpc`. Providing a general purpose scratch register for debug mode (`dscratch0`) allows
568
faster execution of program provided by the debugger, since _one_ general purpose register can be backup-ed and
569
directly used.
570
 
571
[NOTE]
572
The debug-mode control and status registers (CSRs) are only accessible when the CPU is _in_ debug mode.
573
If these CSRs are accessed outside of debug mode (for example when in `machine` mode) an illegal instruction exception
574
is raised.
575
 
576
 
577
:sectnums!:
578
===== **`dcsr`**
579
 
580
[cols="4,27,>7"]
581
[frame="topbot",grid="none"]
582
|======
583
| 0x7b0 | **Debug control and status register** | `dcsr`
584
3+| Reset value: 0x00000000
585
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to configure debug mode and provides additional status information.
586
The following bits are implemented. The reaming bits are read-only and always read as zero.
587
|======
588
 
589
.Debug control and status register bits
590
[cols="^1,^2,^1,<8"]
591
[options="header",grid="rows"]
592
|=======================
593
| Bit   | Name [RISC-V] | R/W | Event
594
| 31:28 | `xdebugver` | r/- | always `0100` - indicates external debug support exists
595
| 27:16 | -           | r/- | _reserved_, read as zero
596
| 15    | `ebereakm`  | r/w | `ebreak` instructions in `machine` mode will _enter_ debug mode when set
597
| 14    | [line-through]#`ebereakh`# | r/- | `0` - hypervisor mode not supported
598
| 13    | [line-through]#`ebereaks`# | r/- | `0` - supervisor mode not supported
599
| 12    | `ebereaku`  | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
600 64 zero_gravi
| 11    | [line-through]#`stepie`#    | r/- | `0` - IRQs are disabled during single-stepping
601 60 zero_gravi
| 10    | [line-through]#`stopcount`# | r/- | `0` - counters increment as usual
602
| 9     | [line-through]#`stoptime`#  | r/- | `0` - timers increment as usual
603 64 zero_gravi
| 8:6   | `cause`     | r/- | cause identifier - why debug mode was entered
604 60 zero_gravi
| 5     | -           | r/- | _reserved_, read as zero
605 64 zero_gravi
| 4     | [line-through]#`mprven`# | r/- | `0` - `mstatus.mprv` is ignored when in debug mode
606
| 3     | [line-through]#`nmip`#   | r/- | `0` - non-maskable interrupt is pending
607 60 zero_gravi
| 2     | `step`      | r/w | enable single-stepping when set
608
| 1:0   | `prv`       | r/w | CPU privilege level before/after debug mode
609
|=======================
610
 
611
 
612
:sectnums!:
613
===== **`dpc`**
614
 
615
[cols="4,27,>7"]
616
[frame="topbot",grid="none"]
617
|======
618
| 0x7b1 | **Debug program counter** | `dpc`
619
3+| Reset value: _UNDEFINED_
620
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to store the current program counter when
621
debug mode is entered. The `dret` instruction will return to `dpc` by moving `dpc` to `pc`.
622
|======
623
 
624
 
625
:sectnums!:
626
===== **`dscratch0`**
627
 
628
[cols="4,27,>7"]
629
[frame="topbot",grid="none"]
630
|======
631
| 0x7b2 | **Debug scratch register 0** | `dscratch0`
632
3+| Reset value: _UNDEFINED_
633
3+| The `dscratch0` CSR is compatible to the RISC-V debug spec. It provides a general purpose debug mode-only scratch register.
634
|======
635
 
636
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.