Skip to content

Commit

Permalink
Revert "[jtag_dmi_reg_frontdoor] Send an extra JTAG read after a DMI …
Browse files Browse the repository at this point in the history
…request"

This reverts commit c592837.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
  • Loading branch information
rswarbrick committed May 30, 2024
1 parent 1b35e60 commit d00eb50
Showing 1 changed file with 21 additions and 55 deletions.
76 changes: 21 additions & 55 deletions hw/dv/sv/jtag_dmi_agent/jtag_dmi_reg_frontdoor.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class jtag_dmi_reg_frontdoor extends uvm_reg_frontdoor;

virtual task body();
csr_field_t csr_or_fld;
uvm_reg_data_t wdata = 0;
uvm_reg_data_t wdata = 0, rdata;
jtag_dtm_reg_block jtag_dtm_ral = jtag_agent_cfg_h.jtag_dtm_ral;
jtag_dmi_op_rsp_e op_rsp;

// If the JTAG agent is sitting in reset, print a debug message and exit early
if (jtag_agent_cfg_h.in_reset) begin
Expand Down Expand Up @@ -74,9 +75,26 @@ class jtag_dmi_reg_frontdoor extends uvm_reg_frontdoor;
// soon, it may end up setting the in progress sticky bit, causing more time wasted.
jtag_agent_cfg_h.vif.wait_tck(10);

// Poll for completion.
// Poll for completion. Reset DMI if the sticky bit 'InProgress' is set.
`DV_SPINWAIT_EXIT(
read_dmi_over_jtag(jtag_dtm_ral, csr_or_fld);,
do begin
csr_rd(.ptr(jtag_dtm_ral.dmi), .value(rdata), .blocking(1));
op_rsp = jtag_dmi_op_rsp_e'(get_field_val(jtag_dtm_ral.dmi.op, rdata));
`uvm_info(`gfn, $sformatf("DMI CSR req status: %0s", op_rsp.name()), UVM_HIGH)
if (op_rsp == DmiOpInProgress) begin
csr_wr(.ptr(jtag_dtm_ral.dtmcs.dmireset), .value(1), .blocking(1), .predict(1));
end else begin
rw_info.status = op_rsp == DmiOpOk ? UVM_IS_OK : UVM_NOT_OK;
if (rw_info.kind == UVM_READ) begin
rdata = get_field_val(jtag_dtm_ral.dmi.data, rdata);
if (csr_or_fld.field != null) begin
rdata = get_field_val(csr_or_fld.field, rdata);
end
rw_info.value = new[1];
rw_info.value[0] = rdata;
end
end
end while (op_rsp == DmiOpInProgress);,
begin
fork
wait(jtag_agent_cfg_h.in_reset);
Expand All @@ -90,56 +108,4 @@ class jtag_dmi_reg_frontdoor extends uvm_reg_frontdoor;
jtag_dtm_ral_sem_h.put();
endtask

// Use JTAG to read the contents of the DMI register
//
// If the underlying operation in rw_info is UVM_READ, this also updates rw_info.value to contain
// the requested register contents.
//
// For either direction (read or write), it waits until the DMI is running an operation.
task read_dmi_over_jtag(jtag_dtm_reg_block jtag_dtm_ral, csr_field_t csr_or_fld);
uvm_reg_data_t dmi_data_rdata;
jtag_dmi_op_rsp_e op_rsp;
int num_dones_seen = 0;

// This loop works around a confusing situation where TCK is running much faster than the main
// clock and the first JTAG read responds with DmiOpOk just as it discovers (too late) that
// there was actually an operation in progress. The next JTAG read correctly responds with
// DmiOpInProgress and the operation is done next time we see DmiOpOk (or DmiOpFailed).
//
// If we see two results other than DmiOpInProgress, we know that the operation is genuinely
// finished.
while (num_dones_seen < 2) begin
uvm_reg_data_t rdata;

csr_rd(.ptr(jtag_dtm_ral.dmi), .value(rdata), .blocking(1));
op_rsp = jtag_dmi_op_rsp_e'(get_field_val(jtag_dtm_ral.dmi.op, rdata));

// If DMI responds with DmiOpInProgress, it is telling us that an operation was running. That
// flag is sticky, so we need to follow up by writing 1 to "dmireset" over JTAG to clear the
// flag.
if (op_rsp == DmiOpInProgress) begin
csr_wr(.ptr(jtag_dtm_ral.dtmcs.dmireset), .value(1), .blocking(1), .predict(1));
end else begin
if (num_dones_seen == 0) begin
dmi_data_rdata = get_field_val(jtag_dtm_ral.dmi.data, rdata);
end

num_dones_seen++;
end
end

// At this point, we've seen two reads where op_rsp is not DmiOpInProgress. Use the results of
// the second read to populate rw_info. If we are doing a UVM_READ, this includes extracting the
// CSR or field from rdata.
rw_info.status = op_rsp == DmiOpOk ? UVM_IS_OK : UVM_NOT_OK;
if (rw_info.kind == UVM_READ) begin
if (csr_or_fld.field != null) begin
dmi_data_rdata = get_field_val(csr_or_fld.field, dmi_data_rdata);
end

rw_info.value = new[1];
rw_info.value[0] = dmi_data_rdata;
end
endtask

endclass

0 comments on commit d00eb50

Please sign in to comment.