Skip to content

Commit

Permalink
[chip,dv] Wait for JTAG connection in chip_sw_base_vseq
Browse files Browse the repository at this point in the history
The wait_lc_status() task does a DMI read over JTAG to figure out the
current state of lc_ctrl. This requires pinmux to route the JTAG
signals to LC_CTRL and things get rather confused if we run this task
before the routing has happened.

In normal use, the JTAG driver will send an IR command to switch
address to the DMI address. Then it will send a DR command to do the
DMI read/write. On the next DMI command, it can avoid the silly extra
IR command because it knows we're already pointing at the DMI address.

Of course, this doesn't work if the JTAG signals got squashed. In that
case, it will not know that IR hasn't changed, so it will send
repeated DR commands expecting to see a particular lc_ctrl status come
out. But that won't happen because we're not actually looking at the
DMI register at all. Oops!

This commit adds a wait to make sure that JTAG has actually been
connected up.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
  • Loading branch information
rswarbrick committed May 13, 2024
1 parent 19697e8 commit bb056f7
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -751,10 +751,48 @@ class chip_sw_base_vseq extends chip_base_vseq;
(is_test_unlocked_lc_state(state) == 1));
endfunction


// LC_CTRL JTAG tasks


// Wait until pinmux has become configured for JTAG signals to be routed to lc_ctrl. Fail if this
// doesn't happen within max_cycles cycles.
task wait_lc_ctrl_jtag_connection(int max_cycles = 1000);
bit connected = 1'b0;

fork : isolation_fork
fork
cfg.clk_rst_vif.wait_clks(max_cycles);
forever begin
uvm_hdl_data_t tap_strap_value;
string tap_strap_path = {"tb.dut.top_earlgrey.u_pinmux_aon.",
"u_pinmux_strap_sampling.tap_strap"};
`DV_CHECK(uvm_hdl_read(tap_strap_path, tap_strap_value))
if (tap_strap_value == pinmux_pkg::LcTapSel) begin
connected = 1'b1;
break;
end
cfg.clk_rst_vif.wait_clks(10);
end
join_any
disable fork;
join

if (!connected) begin
`uvm_fatal(`gfn, $sformatf("Cycle timeout (%0d) for pinmux to connect JTAG to lc_ctrl",
max_cycles))
end
endtask

// Read the lc_ctrl status over JTAG and wait until it becomes expect_status.
//
// This task will only work when the dut power-on sequence has got far enough for the JTAG signals
// to be routed correctly to lc_ctrl.
virtual task wait_lc_status(lc_ctrl_status_e expect_status, int max_attempt = 5000);
int i;

// Make sure the DUT power-on sequence has got far enough for this to work at all.
wait_lc_ctrl_jtag_connection(100000);

for (i = 0; i < max_attempt; i++) begin
bit [TL_DW-1:0] status_val;
lc_ctrl_status_e dummy;
Expand Down

0 comments on commit bb056f7

Please sign in to comment.