Skip to content

Commit

Permalink
[rv_dm,dv] Use the "right enable" in *_jtag_dmi_debug_disabled_vseq
Browse files Browse the repository at this point in the history
The code here was a bit broken and I clearly hadn't previously
understood the difference between "pinmux enabled" and "debug
enabled".

The *whole point* of this test is supposed to be that DMI transactions
get blocked when pinmux is not enabled. After the changes here, we
actually test that property!

Signed-off-by: Rupert Swarbrick <[email protected]>
  • Loading branch information
rswarbrick committed Jul 11, 2024
1 parent 2f4f347 commit 2988669
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 37 deletions.
7 changes: 6 additions & 1 deletion hw/ip/rv_dm/dv/env/seq_lib/rv_dm_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class rv_dm_base_vseq extends cip_base_vseq #(

// Drive the pinmux_hw_debug_en_i pin to match the pinmux_hw_debug_en bit, avoiding assertions
// that get triggered in prim_lc_sync if the input is 'x.
cfg.rv_dm_vif.pinmux_hw_debug_en <= bool_to_lc_tx_t(pinmux_hw_debug_en);
upd_pinmux_hw_debug_en();

// Drive the lc_hw_debug_en_i pin to match the lc_hw_debug_en bit, avoiding assertions that get
// triggered in prim_lc_sync if the input is 'x.
Expand Down Expand Up @@ -383,6 +383,11 @@ class rv_dm_base_vseq extends cip_base_vseq #(
csr_wr(.ptr(ral.late_debug_enable), .value(bool_to_mubi32_t(bool_val)));
endtask

// Update the pinmux_hw_debug_en_i pin to match the bit in pinmux_hw_debug_en
function void upd_pinmux_hw_debug_en();
cfg.rv_dm_vif.pinmux_hw_debug_en <= bool_to_lc_tx_t(pinmux_hw_debug_en);
endfunction

// Update the lc_hw_debug_en_i pin to match the bit in lc_hw_debug_en
function void upd_lc_hw_debug_en();
cfg.rv_dm_vif.lc_hw_debug_en <= bool_to_lc_tx_t(lc_hw_debug_en);
Expand Down
70 changes: 34 additions & 36 deletions hw/ip/rv_dm/dv/env/seq_lib/rv_dm_jtag_dmi_debug_disabled_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ class rv_dm_jtag_dmi_debug_disabled_vseq extends rv_dm_base_vseq;
`uvm_object_utils(rv_dm_jtag_dmi_debug_disabled_vseq)
`uvm_object_new

// Override the constraint in rv_dm_base_vseq that enables debug (to disable it instead)
constraint debug_enabled_c {
lc_hw_debug_en == 1'b0;
}

task automatic write_abstractdata(uvm_reg_data_t value);
csr_wr(.ptr(jtag_dmi_ral.abstractdata[0]), .value(value));
endtask
Expand All @@ -31,46 +26,49 @@ class rv_dm_jtag_dmi_debug_disabled_vseq extends rv_dm_base_vseq;
end
endtask

task body();
repeat ($urandom_range(1, 10)) begin
bit [31:0] value0, value1;
`DV_CHECK_STD_RANDOMIZE_FATAL(value0)
`DV_CHECK_STD_RANDOMIZE_FATAL(value1)
// Control the pinmux_hw_debug_en_i signal, waiting long enough to ensure the signal has
// synchronised properly.
task control_pinmux_enable(bit enable);
pinmux_hw_debug_en = enable;
upd_pinmux_hw_debug_en();

// Write value0 to abstractdata[0], then read it back, checking the value has arrived as
// expected.
write_abstractdata(value0);
read_abstractdata(value0);
// Wait a few cycles to make sure that the changed pinmux signal has made it through a
// prim_lc_sync. If we start the next operation too early, things will get rather confused
// because only half of a JTAG operation will get through.
cfg.clk_rst_vif.wait_clks(3);
endtask

// Possibly wait a bit
maybe_delay();
task body();
bit [31:0] value0, value1;
`DV_CHECK_STD_RANDOMIZE_FATAL(value0)
`DV_CHECK_STD_RANDOMIZE_FATAL(value1)

// Pick an arbitrary value for lc_hw_debug_en_i other than On
upd_lc_hw_debug_en();
// At the start of the vseq, we expect that pinmux_hw_debug_en_i is On, so we should have a
// working DMI connection. Write some arbitrary value to abstractdata 0.
write_abstractdata(value0);
read_abstractdata(value0);

// Wait a few cycles to make sure that the changed enable signal has made it through a
// prim_lc_sync. If we start the next operation too early, things will get rather confused
// because only the latter half of a JTAG operation will get through.
cfg.clk_rst_vif.wait_clks(3);
// Possibly wait a bit
maybe_delay();

// Write a different value to abstractdata[0] than read it back. The write should be ignored
// and the register should read as its reset value (because the debug block is disabled).
write_abstractdata(value1);
read_abstractdata(jtag_dmi_ral.abstractdata[0].get_reset());
// Now we want to disable the DMI connection by setting pinmux_hw_debug_en_i to a value other
// than On.
control_pinmux_enable(1'b0);

// Possibly wait a bit
maybe_delay();
// Write a different value to abstractdata[0] than read it back. The write should be ignored
// and the register should read as zero (because the JTAG connection isn't actually up).
write_abstractdata(value1);
read_abstractdata(0);

// Issue a JTAG reset through trst_n and switch lc_hw_debug_en to On.
cfg.m_jtag_agent_cfg.vif.do_trst_n(2);
cfg.rv_dm_vif.cb.pinmux_hw_debug_en <= lc_ctrl_pkg::On;
// Possibly wait a bit
maybe_delay();

// Wait again to make sure the LC signal makes it through the prim_lc_sync
cfg.clk_rst_vif.wait_clks(3);
// Issue a JTAG reset through trst_n and reconnect the DMI
cfg.m_jtag_agent_cfg.vif.do_trst_n(2);
control_pinmux_enable(1'b1);

// Read the contents of abstractdata[0] and check they are what we set at the start.
read_abstractdata(value0);
end
// Read the contents of abstractdata[0] and check they are what we set at the start.
read_abstractdata(value0);
endtask : body

endclass : rv_dm_jtag_dmi_debug_disabled_vseq

0 comments on commit 2988669

Please sign in to comment.