Skip to content

Commit f485ae2

Browse files
committed
[rv_dm,dv] Give rv_dm_if a passive mode
Doing this properly involves tidying up the clocking block a little bit and defining a "mon_cb" version. Detailed changes: - The signals in the interface and the testbench are now listed in the same order as the ports of rv_dm. No functional change, but it should make the code slightly easier to read quickly. - The interface now has an is_active flag and the various signals that the testbench *might* drive (inputs to rv_dm) are now wires and driven with 'z in passive mode. - All the clocked signals are now in the clocking block. The commit removes scanmode and scan_rst_n from the block (because they are not synchronous to clk_i). - There is now a modport that groups together all the signals from the "point of view" of an active testbench. - The code in the rv_dm environment now consistently accesses signals through the modport. - For passive mode, the clocking block and modport are duplicated (as mon_cb and mon_mp) with all the signals as inputs. Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
1 parent 3c91f17 commit f485ae2

5 files changed

Lines changed: 49 additions & 20 deletions

File tree

hw/ip/rv_dm/dv/env/rv_dm_if.sv

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,53 @@ interface rv_dm_if(input logic clk, input logic rst_n);
66

77
import rv_dm_env_pkg::*;
88

9-
// DUT inputs.
10-
logic scan_rst_n;
11-
logic [NUM_HARTS-1:0] unavailable;
9+
// Most of the signals in the interface are designed to be connected to ports of rv_dm. If
10+
// is_active is true, the signals that will be connected to its input ports are driven by cb. If
11+
// is_active is false, they are driven with 'z here, which allows the interface to monitor a
12+
// larger design that drives rv_dm itself.
13+
//
14+
// The flag is defined as a wire with a weak pull-up. This ensures that a testbench that doesn't
15+
// customise is_active will see the interface be driven actively, but allows a testbench that
16+
// *does* want to customise the signal to pull it low.
17+
wire is_active;
18+
assign (weak0, weak1) is_active = 1'b1;
1219

13-
// DUT outputs.
14-
wire ndmreset_req;
15-
wire dmactive;
16-
wire [NUM_HARTS-1:0] debug_req;
20+
// The signals connected to ports of rv_dm, other than the TL, alert, RACL and JTAG interfaces.
21+
// These have the same name as the port, but without an _i or _o suffix.
22+
wire logic scan_rst_n;
23+
wire logic ndmreset_req;
24+
wire logic dmactive;
25+
wire [NUM_HARTS-1:0] debug_req;
26+
wire logic [NUM_HARTS-1:0] unavailable;
1727

18-
// Disable TLUL host SBA assertions when injecting intg errors on the response channel.
19-
bit disable_tlul_assert_host_sba_resp_svas;
28+
// "Internal" versions of the per-port signals above for rv_dm's input ports
29+
logic scan_rst_n_internal;
30+
logic [NUM_HARTS-1:0] unavailable_internal;
2031

32+
// Drive the wire signals for rv_dm's input ports if is_active is true
33+
assign scan_rst_n = is_active ? scan_rst_n_internal : 'z;
34+
assign unavailable = is_active ? unavailable_internal : 'z;
35+
36+
// A clocking block for driving the various _internal signals that are all synchronous to clk. If
37+
// is_active is true, these can be used to drive input ports of rv_dm. The signals from output
38+
// ports of rv_dm can also be sampled through this clocking block.
2139
clocking cb @(posedge clk);
22-
output scan_rst_n;
23-
output unavailable;
40+
input ndmreset_req;
41+
input dmactive;
42+
input debug_req;
43+
output scan_rst_n = scan_rst_n_internal;
44+
output unavailable = unavailable_internal;
45+
endclocking
46+
47+
// A clocking block for a monitor
48+
clocking mon_cb @(posedge clk);
2449
input ndmreset_req;
2550
input dmactive;
2651
input debug_req;
52+
input unavailable;
2753
endclocking
2854

55+
// Disable TLUL host SBA assertions when injecting intg errors on the response channel.
56+
bit disable_tlul_assert_host_sba_resp_svas;
57+
2958
endinterface

hw/ip/rv_dm/dv/env/seq_lib/rv_dm_base_vseq.sv

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,21 +246,21 @@ class rv_dm_base_vseq extends cip_base_vseq #(
246246
uint delay;
247247
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(delay, delay inside {[0:1000]};) // ns
248248
#(delay * 1ns);
249-
cfg.rv_dm_vif.cb.scan_rst_n <= 1'b0;
249+
cfg.rv_dm_vif.scan_rst_n_internal <= 1'b0;
250250
// Wait for core clock cycles.
251251
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(delay, delay inside {[2:50]};) // cycles
252252
cfg.clk_rst_vif.wait_clks(delay);
253253
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(delay, delay inside {[0:1000]};) // ns
254-
cfg.rv_dm_vif.cb.scan_rst_n <= 1'b1;
254+
cfg.rv_dm_vif.scan_rst_n_internal <= 1'b1;
255255
endtask
256256

257257
virtual task apply_resets_concurrently(int reset_duration_ps = 0);
258258
int trst_n_duration_ps = cfg.m_jtag_agent_cfg.vif.get_tck_period_ps() * $urandom_range(5, 20);
259-
cfg.rv_dm_vif.cb.scan_rst_n <= 1'b0;
259+
cfg.rv_dm_vif.scan_rst_n_internal <= 1'b0;
260260
cfg.m_jtag_agent_cfg.vif.assert_test_reset();
261261
super.apply_resets_concurrently(dv_utils_pkg::max2(reset_duration_ps, trst_n_duration_ps));
262262
cfg.m_jtag_agent_cfg.vif.clear_test_reset();
263-
cfg.rv_dm_vif.cb.scan_rst_n <= 1'b1;
263+
cfg.rv_dm_vif.scan_rst_n_internal <= 1'b1;
264264
endtask
265265

266266
virtual task dut_shutdown();
@@ -333,7 +333,7 @@ class rv_dm_base_vseq extends cip_base_vseq #(
333333

334334
csr_wr(.ptr(jtag_dmi_ral.dmcontrol.haltreq), .value(1));
335335
if (!cfg.clk_rst_vif.rst_n) return;
336-
`DV_CHECK_EQ(cfg.rv_dm_vif.cb.debug_req, 1)
336+
`DV_CHECK_EQ(cfg.rv_dm_vif.mon_cb.debug_req, 1)
337337

338338
// Wait a short time (up to 10 cycles, but stopping early if there's a reset)
339339
fork begin : isolation_fork

hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_halted_vseq.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class rv_dm_mem_tl_access_halted_vseq extends rv_dm_base_vseq;
1111
uvm_reg_data_t r_data;
1212
// Disable unavailable signal to make sure that hart should be in known state. if hart
1313
// is unavailable then it could not halted.
14-
cfg.rv_dm_vif.unavailable <= 0;
14+
cfg.rv_dm_vif.cb.unavailable <= 0;
1515

1616
// Make sure that the ndmreset signal is not currently asserted. If it is asserted then DMI
1717
// operations work but the TLUL connection is blocked by u_tlul_lc_gate_rom, which is held in

hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_resuming_vseq.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class rv_dm_mem_tl_access_resuming_vseq extends rv_dm_base_vseq;
4444

4545
// Disable unavailable signal to make sure that hart should be in known
4646
// state. If hart is unavailable then it could not halted.
47-
cfg.rv_dm_vif.unavailable <= 0;
47+
cfg.rv_dm_vif.cb.unavailable <= 0;
4848

4949
// Request a halt as the debugger and then acknowledge it as the hart.
5050
request_halt();

hw/ip/rv_dm/dv/env/seq_lib/rv_dm_smoke_vseq.sv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class rv_dm_smoke_vseq extends rv_dm_base_vseq;
5959
cfg.rv_dm_vif.cb.unavailable <= data;
6060
csr_rd(.ptr(jtag_dmi_ral.dmstatus), .value(data));
6161
if (cfg.clk_rst_vif.rst_n) begin
62-
`DV_CHECK_EQ(cfg.rv_dm_vif.unavailable,
62+
`DV_CHECK_EQ(cfg.rv_dm_vif.mon_cb.unavailable,
6363
get_field_val(jtag_dmi_ral.dmstatus.anyunavail, data))
64-
`DV_CHECK_EQ(cfg.rv_dm_vif.unavailable,
64+
`DV_CHECK_EQ(cfg.rv_dm_vif.mon_cb.unavailable,
6565
get_field_val(jtag_dmi_ral.dmstatus.allunavail, data))
6666
end
6767
endtask

0 commit comments

Comments
 (0)