forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rv_dm_testplan.hjson
572 lines (523 loc) · 23.4 KB
/
rv_dm_testplan.hjson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{
name: "rv_dm"
// TODO: remove the common testplans if not applicable
import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson",
"hw/dv/tools/dvsim/testplans/mem_testplan.hjson",
"hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson",
"hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson",
"hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson",
"rv_dm_sec_cm_testplan.hjson"]
testpoints: [
// Note that the CSR tests in the imported csr_testplan.hjson will cover CSRs attached to both,
// the main RV_DM device interface as well as the debug ROM interface.
{
name: smoke
desc: '''
A basic smoke test.
. Read the DTM register `idcode` and verify that it reflects the correct value.
- Enable debug by setting lc_hw_debug_en to true.
- Write to the DMI register field dmcontrol[dmactive] via JTAG and verify that the
`dmactive` output pin reflects the same value.
- Write to the DMI register field dmcontrol[haltreq] via JTAG and verify that the
`debug_req` output pin reflects the same value.
- Write to the DMI register field dmcontrol[ndmreset] via JTAG and verify that the
`ndmreset` output pin reflects the same value.
- Wiggle the `unavailable` input and read the DTM register field dmstatus[allunavail]
to verify that it reflects the same value as the input signal.
'''
stage: V1
tests: ["rv_dm_smoke"]
}
{
name: jtag_dtm_csr_hw_reset
desc: '''
Verify the reset values of JTAG DTM CSRs as indicated in the RAL specification.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DTM regisers.
In these set of tests, the lc_hw_debug_en is set to true, scanmode & scan_rst_n inputs
to false.
'''
stage: V1
tests: ["rv_dm_jtag_dtm_csr_hw_reset"]
}
{
name: jtag_dtm_csr_rw
desc: '''
Verify accessibility of JTAG DTM CSRs as indicated in the RAL specification.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DTM regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dtm_csr_rw"]
}
{
name: jtag_dtm_csr_bit_bash
desc: '''
Verify no aliasing within individual bits of JTAG DTM CSR.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DTM regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dtm_csr_bit_bash"]
}
{
name: jtag_dtm_csr_aliasing
desc: '''
Verify no aliasing within the JTAG DTM CSR address space.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DTM regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dtm_csr_aliasing"]
}
{
name: jtag_dmi_csr_hw_reset
desc: '''
Verify the reset values of JTAG DMI CSRs as indicated in the RAL specification.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DMI regisers.
In these set of tests, the lc_hw_debug_en is set to true, scanmode & scan_rst_n inputs
to false.
Also, the dmcontrol[dmactive] field is set to 1 at the start, to ensure CSR accesses to
all other registers go through.
'''
stage: V1
tests: ["rv_dm_jtag_dmi_csr_hw_reset"]
}
{
name: jtag_dmi_csr_rw
desc: '''
Verify accessibility of JTAG DMI CSRs as indicated in the RAL specification.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DMI regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dmi_csr_rw"]
}
{
name: jtag_dmi_csr_bit_bash
desc: '''
Verify no aliasing within individual bits of JTAG DMI CSR.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DMI regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dmi_csr_bit_bash"]
}
{
name: jtag_dmi_csr_aliasing
desc: '''
Verify no aliasing within the JTAG DMI CSR address space.
See hw/dv/tools/dvsim/testplans/csr_testplan.hjson for more description, This follows
the same approach, but applies to the JTAG DMI regisers.
'''
stage: V1
tests: ["rv_dm_jtag_dmi_csr_aliasing"]
}
{
name: idcode
desc: '''
Verify that the JTAG IDCODE reads the correct value.
- Set a different JTAG ID code an rv_dm design parameter.
- Read the IDCODE register in JTAG DTM register space, via JTAG.
- Verify it reads back what was set.
'''
stage: V2
tests: ["rv_dm_smoke"]
}
{
name: jtag_dtm_hard_reset
desc: '''
Verify that the debugger can cancel an on-going DMI transaction with a hard reset.
- Perform DMI register read and check the data value.
- Write 1 to dtmcs[dmihardreset] bit.
- Perform DMI register read and check the data value to make sure the reset doesn't
create any harmful event.
'''
stage: V2
tests: ["rv_dm_jtag_dtm_hard_reset"]
}
{
name: jtag_dtm_idle_hint
desc: '''
Verify that the JTAG debugger does not need to stay any longer than the advertized idle
time indicated in dtmcs register.
- Read the dtmcs[idle] value and configure the JTAG DMI register adapter to insert that
many delay between transactions.
- Issue random legal DMI accesses back to back and ensure that all of them complete
successfully, without dmistat reflecting an error.
'''
stage: V2
tests: ["rv_dm_jtag_dtm_idle_hint"]
}
{
name: jtag_dmi_failed_op
desc: '''
Verify that a failed DMI op is reflected properly in dtmcs register.
- Issue a random legal DMI write to a chosen DMI register.
- Before that access completes, issue another random legal DMI access.
- Read the dtmcs[dmistat] register to verify busy error.
- Clear it by writing to dtmcs[dmireset] register.
- Poll the DMI access for completion and verify that the first write completed
successfully by doing a read-check.
'''
stage: V2
tests: ["rv_dm_dmi_failed_op"]
}
{
name: jtag_dmi_dm_inactive
desc: '''
Verify that DMI writes to data other than dmcontrol.dmactive are ignored when dmactive
is false. All of these registers should return their reset values on reads.
- Write 0 to DMCONTROL.DMACTIVE to put the debug module into its reset state.
- Perform random DMI writes, constrained only by requiring that they don't write 1 to
DMCONTROL.DMACTIVE.
- Write 1 to DMCONTROL.DMACTIVE to leave the reset state.
- Read DMI registers back and check they have their POR values.
'''
stage: V2
tests: ["rv_dm_jtag_dmi_dm_inactive"]
}
{
name: sba
desc: '''
Verify all types of accesses from JTAG to SBA.
- Enable debug by setting lc_hw_debug_en to true and activate the dm
- Write to SBA registers to inject randomized 8/16/32bit writes and reads.
- Randomize readonaddr and readondata settings and ensure those have the intended
effect.
- Generate sbbusy = 1 scenario by picking a very large response delay, since JTAG
accesses are much slower (SBA TL accesses tend to complete faster than JTAG can
read the SBCS register).
'''
stage: V2
tests: ["rv_dm_sba_tl_access", "rv_dm_delayed_resp_sba_tl_access"]
}
{
name: bad_sba
desc: '''
Verify attempts to make bad SBA accesses results in the error sticky bits getting set.
- Enable debug by setting lc_hw_debug_en to true and activate the dm.
- Build on the previous `sba` test and randomly inject errors in the following
ways:
- Inject a response error on the TL response channel (d_error = 1) and verify that
the sberror bit is set to 2.
- Inject a randomized SBA access that is not aligned to the size of the transfer and
verify that the sberror bit is set to 3.
- Inject a randomized SBA access that is greater that the supported transfer size and
verify that the sberror bit is set to 4.
- Inject an integrity error on the TL response channel and verify that the sberror
bit is set to 7. Verify that an alert is seen. Reset the DUT.
- Inject a new SBA traffic before the previous one completes - verify that the
sbbusyerror asserts. This is achieved by setting a large TL response delay (TODO).
- Have more than one of these types of errors trigger at the same time.
Note: The following error scenarios are not supported by the design:
- pulp-platform/riscv-dbg#128: response timeout (sberror = 1) is not implemented.
'''
stage: V2
tests: ["rv_dm_bad_sba_tl_access"]
}
{
name: sba_autoincrement
desc: '''
Verify the address autoincrement functionality of SBA.
- Enable debug by setting lc_hw_debug_en to true and activate the dm.
- Write to the SBCS register to inject randomized 8/16/32bit writes. Set the
autoincrement bit.
- Pick a random address and write to sbaddress0 register.
- Write a random value to sbdata0, repeating a randomized number of times.
- Each write should trigger a new SBA TL write access with the address incremented with
the transfer size. Verify that the SBA TL access shows up.
- Repeat the same procedure for reads. For reads, set the readondata register and read
the sbdata0 a randomized number of times - each read should trigger a new SBA TL read
access.
- Intermittently also generate busy and error conditions.
'''
stage: V2
tests: ["rv_dm_autoincr_sba_tl_access"]
}
{
name: jtag_dmi_debug_disabled
desc: '''
Verify that the JTAG DMI register space cannot be accessed if pinmux_hw_debug_en is a non
strict true value.
- Set pinmux_hw_debug_en to true and activate the dm.
- Write a known value to a randomly picked DMI CSR.
- Set pinmux_hw_debug_en to non-true value.
- Write a different value to the same DMI CSR.
- Attempt to read that DMI CSR - it should read all 0s.
- Note that the above steps are rendered moot because the JTAG DTM itself will not
receive any incoming JTAG transactions.
- Set pinmux_hw_debug_en to true and again read the DMI CSR - it should reflect the
originally written value.
'''
stage: V2
tests: ["rv_dm_jtag_dmi_debug_disabled"]
}
{
name: sba_debug_disabled
desc: '''
Verify that access to SBA interface is disabled if lc_hw_debug_en is set to a value
other than lc_ctrl_pkg::On.
- Set lc_hw_debug_en to non-true value and activate the dm.
- Attempt to send some legal randomized SBA accesses. Checks in the scoreboard will
assert that no SBA TL accesses appear on the TL interface.
'''
stage: V2
tests: ["rv_dm_sba_debug_disabled"]
}
{
name: ndmreset_req
desc: '''
Verify that the debugger can issue a non-debug reset to the rest of the system.
- Set lc_hw_debug_en / pinmux_hw_debug_en to true value and activate the dm.
- Pick a random set of write/readable CSRs in the debug RALs (JTAG DMI and debug
memory). Write known values to them.
- Write the dmcontrol register to assert ndmreset - verify that the ndmreset output
is asserted.
- Mimic the CPU going into reset by asserting the unavailable input.
- Set lc_hw_debug_en to something other than On (since it should no longer be needed).
At this point the ndmreset output signal will drop. Keep pinmux_hw_debug_en set to On
to keep the JTAG side open while the ndmreset is in progress.
- Read the dmstatus register to verify allunavail is asserted.
- De-assert the ndmreset by writing 0 to the dmcontrol register field, verify the
ndmreset output deasserted as well.
- Mimic the CPU going out of reset by de-asserting unavailable input
after some delay. Set lc_hw_debug_en to true again as well.
- Read the previously written registers back and verify that they reflect the previously
written value, proving that ndmreset assertion had no effect on them.
'''
stage: V2
tests: ["rv_dm_ndmreset_req"]
}
{
name: hart_unavail
desc: '''
Verify that the debugger can read the status of unavailable hart
- Set lc_hw_debug_en to true value and activate the dm.
- Randomly assert and de-assert the `unavailable` input (indicates the CPU is under
reset). This ideally happens when ndmreset is issued by the debugger.
- Periodically issue reads to dmstatus register to verify allunavail matches the
`unavailable` input value
'''
stage: V2
tests: ["rv_dm_hart_unavail"]
}
{
name: tap_ctrl_transitions
desc: '''
Verify all JTAG TAP controller FSM transitions
This test should verify that the standardized JTAG TAP FSM is working correctly.
'''
stage: V2
tests: ["rv_dm_tap_fsm", "rv_dm_tap_fsm_rand_reset"]
}
{
name: jtag_dmi_cmderr_busy
desc: '''
Generate the "busy" command error in abstractcs.
- Start an abstract command executing (but don't allow it to stop)
- Write to one of command, abstractcs, abstractauto or access (read or write) the data
or progbuf register.
- Read the abstractcs register and check that cmderr is now set to 1 (the encoding of
"busy")
'''
stage: V1
tests: ["rv_dm_cmderr_busy"]
}
{
name: jtag_dmi_cmderr_not_supported
desc: '''
Generate the "not supported" command error in abstractcs
This command error is generated when trying to run an abstract command that is not
supported.
- Write a command to the command register where cmdtype is definitely not supported.
- Check that the cmderr field of abstractcs register is set to 2.
'''
stage: V1
tests: ["rv_dm_cmderr_not_supported"]
}
{
name: cmderr_exception
desc: '''
Verify that if an exception occurs when executing a command then cmderr is set to 3.
- Start an abstract command.
- While it's running, write to the exception register over TL.
- Check that the cmderr field of abstractcs register is now 3.
'''
stage: V1
tests: ["rv_dm_cmderr_exception"]
}
{
name: mem_tl_access_resuming
desc: '''
Verify whether the selected hart has been resumed or not.
-Write into memory mapped register called RESUMING(0x110) through tl-device interface.
-Verify that the anyresumeack and allresumeack bits of the dmstatus register are set.
-After that, set the resumereq bit of dmcontrol register.
-Verify that the anyresumeack and allresumeack bits of the dmstatus register are cleared.
'''
stage: V1
tests: ["rv_dm_mem_tl_access_resuming"]
}
{
name: mem_tl_access_halted
desc: '''
Verify whether the selected hart has been halted or not.
- Set the haltreq bit of dmcontrol register.
- Write into memory mapped register called HALTED(0x100) through tl-device(mem_tl_if) interface.
- Verify that the anyhalted and allhalted bits of the dmstatus register are set.
'''
stage: V1
tests: ["rv_dm_mem_tl_access_halted"]
}
{
name: cmderr_halt_resume
desc: '''
Verify that attempt to generate command error result in cmderr field of abstractcs
register are set.
- Try to execute abstract command when hart is not in halt/resume state.
- Assert unavailable signal through core interface.
- The abstract command could not be execute.
- Verify that the cmderr field of abstractcs register is set to 4.
'''
stage: V1
tests: ["rv_dm_cmderr_halt_resume"]
}
{
name: dataaddr_rw_access
desc: '''
Verify the read write access of the data registers through the memory mapped DataAddr register.
- Write random data to the shadowed data registers via the corresponding DataAddr registers.
- Read back the written data and verify that it matches the expected values.
'''
stage: V1
tests: ["rv_dm_dataaddr_rw_access"]
}
{
name: halt_resume
desc: '''
Verify debug module halt/going/resume behavior.
- Request a halt over DMI, then send an abstract command.
- Check that the debug module reports itself to be busy.
- Check that the debug module's internal state machine is in the Go state.
- As the hart, respond to the message from the debug module to say that it has started handling it.
- Check the debug module still reports itself to be busy.
- Check that WHERETO points at the expected address (which contains the start of the abstract command)
- As the hart, tell the debug module that we have halted.
- Check the debug module no longer reports itself to be busy.
- Tell the debug module to resume again, by clearing the halt request and sending a resume request.
- Check the debug module now reports itself busy again (since it should be asking the hart to resume)
- Check flags to make sure the debug module is in the Resume state.
- As the hart, acknowledge the resume request.
- Check the debug module no longer reports itself to be busy.
'''
stage: V1
tests: ["rv_dm_halt_resume_whereto"]
}
{
name: progbuf_busy
desc: '''
Verify that writing on DM progbuf registers while abstract command is executing
causes jtag_dmi_ral.abstractcs.busy to be set to 1.
This is implemented by rv_dm_cmderr_busy, which chooses a random operation to generate
the busy command error. One possible operation is writing to progbuf[0].
'''
stage: V1
tests: ["rv_dm_cmderr_busy"]
}
{
name: abstractcmd_status
desc: '''
Verify the functionality of abstract command by reading tl_mem_ral.abstractcmd0-9
registers.
- Program jtag_dmi_ral.dmcontrol.haltreq to 1'b1.
- Verify that the 'debug_req_o' is set to 1.
- Acknowledge haltreq by setting tl_mem_ral.halted to 0.
- Send a valid abstract command (command type AccessRegister).
- Verify that the jtag_dmi_ral.abstractcs.busy is set to 1.
- Read tl_mem_ral.abstractcmd0-9 registers to verify that due to executing specific
abstract command we can read instructions stored in these registers.
'''
stage: V1
tests: ["rv_dm_abstractcmd_status"]
}
{
name: progbuf_read_write_execute
desc: '''
Verify the functionality of program buffer by writing random data on program buffer.
- Program jtag_dmi_ral.dmcontrol.haltreq to 1'b1.
- Verify that 'debug_req_o' is set to 1.
- Acknowledge haltreq by setting tl_mem_ral.halted to 0.
- Fill the program buffer by writing random data to jtag_dmi_ral.progbuf0-7
registers.
- Read tl_mem_ral.program_buffer0-7 registers to
verify that the data we wrote is what we read back.
'''
stage: V1
tests: ["rv_dm_progbuf_read_write_execute"]
}
{
name: progbuf_exception
desc: '''
Verify that writing on tl_mem_ral.exception register while an abstract command
is executing causes jtag_dmi_ral.abstractcs.cmderr to be set to 3.
- Program jtag_dmi_ral.dmcontrol.haltreq to 1'b1.
- Verify that 'debug_req_o' is set to 1.
- Acknowledge haltreq by setting tl_mem_ral.halted to 0.
- Send access register abstract command with postexec bit set.
- Write on tl_mem_ral.exception register.
- Verify that jtag_dmi_ral.abstractcs.cmderr is set to 3.
'''
stage: V1
tests: ["rv_dm_cmderr_exception"]
}
{
name: rom_read_access
desc: '''
Verify the read accessability of rom.
- Read from the addresses of rom and verify that it reads the expected data.
'''
stage: V1
tests: ["rv_dm_rom_read_access"]
}
{
name: hartsel_warl
desc: '''
Check the WARL behaviour of the hartsel field in dmcontrol
- Write '1 to hartsel and then read dmcontrol back again.
- Check resulting value of hartsel equals the maximum hart index.
'''
stage: V2
tests: ["rv_dm_hartsel_warl"]
}
{
name: stress_all
desc: '''
A 'bug hunt' test that stresses the DUT to its limits.
- Combine above sequences in one test and run as many of them as possible in parallel.
Run the rest sequentially.
- Randomly inject a full device reset intermittently.
'''
stage: V2
tests: ["rv_dm_stress_all"]
}
]
covergroups: [
{
name: sba_access_cg
desc: '''Cover all possible types of accesses over SBA.
- cp: reads and write accesses
- cp: supported transfer sizes
- cp: auto-increment address with back-to-back acesses
- cp: for reads, cover readonaddr and readondata settings
- cp: sberror cases with unaligned address and unsupported size
- cp: sbbusyerror case - attempt new access before the previous one completed
- cr: cross all of the above
'''
}
]
}