[dv/chip] solve same_csr_outstanding_timeout
This PR fixes same_csr_outstanding timeout issue. The timeout is reached
mainly because there are too many resets in this sequence.
We removed the reset when writing to wen_regs by manually calling the
function to lock lockable regs.
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/dv/sv/cip_lib/cip_base_vseq.sv b/hw/dv/sv/cip_lib/cip_base_vseq.sv
index 5a2b8f0..147f951 100644
--- a/hw/dv/sv/cip_lib/cip_base_vseq.sv
+++ b/hw/dv/sv/cip_lib/cip_base_vseq.sv
@@ -577,7 +577,7 @@
rd_mask = get_mask_excl_fields(test_csrs[i], CsrExclWriteCheck, csr_test_type, csr_excl);
wr_mask = get_mask_excl_fields(test_csrs[i], CsrExclWrite, csr_test_type, csr_excl);
- repeat ($urandom_range(2, 50)) begin
+ repeat ($urandom_range(2, 20)) begin
// do read, exclude CsrExclWriteCheck, CsrExclCheck
if ($urandom_range(0, 1) &&
!csr_excl.is_excl(test_csrs[i], CsrExclWriteCheck, csr_test_type)) begin
@@ -597,8 +597,8 @@
end
csr_utils_pkg::wait_no_outstanding_access();
- // reset after writing to wen_reg to avoid it locking associated regs
- if (test_csrs[i].is_wen_reg()) dut_init("HARD");
+ // Manually lock lockable flds because we use tl_access() instead of csr_wr().
+ if (test_csrs[i].is_wen_reg()) test_csrs[i].lock_lockable_flds(`gmv(test_csrs[i]));
end
end
endtask
diff --git a/hw/dv/sv/dv_base_reg/dv_base_reg.sv b/hw/dv/sv/dv_base_reg/dv_base_reg.sv
index 5915fc4..608635d 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg.sv
@@ -181,7 +181,6 @@
// automation.
virtual task post_write(uvm_reg_item rw);
dv_base_reg_field fields[$];
- string field_access;
// no need to update shadow value or access type if access is not OK, as access is aborted
if (rw.status != UVM_IS_OK) return;
@@ -190,6 +189,7 @@
// first write
if (!shadow_wr_staged) begin
shadow_wr_staged = 1;
+ // rw.value is a dynamic array
staged_shadow_val = rw.value[0];
return;
end begin
@@ -203,24 +203,7 @@
shadowed_val = ~committed_val;
end
end
- if (is_wen_reg()) begin
- foreach (m_fields[i]) begin
- dv_base_reg_field fld;
- `downcast(fld, m_fields[i])
- if (fld.is_wen_fld()) begin
- // rw.value is a dynamic array
- uvm_reg_data_t field_val = rw.value[0] & fld.get_field_mask();
- field_access = fld.get_access();
- case (field_access)
- // discussed in issue #1922: enable register is standarized to W0C or RO (if HW has
- // write access).
- "W0C": if (field_val == 1'b0) fld.set_lockable_flds_access(1);
- "RO": ; // if RO, it's updated by design, need to predict in scb
- default:`uvm_fatal(`gfn, $sformatf("lock register invalid access %s", field_access))
- endcase
- end
- end
- end
+ lock_lockable_flds(rw.value[0]);
endtask
// shadow register read will clear its phase tracker
@@ -261,9 +244,9 @@
// 2). It is shadow_reg's second write with an update_err.
// 2). The shadow_reg is locked due to fatal storage error and it is not a backdoor write.
- virtual function void do_predict (uvm_reg_item rw,
- uvm_predict_e kind = UVM_PREDICT_DIRECT,
- uvm_reg_byte_en_t be = -1);
+ virtual function void do_predict(uvm_reg_item rw,
+ uvm_predict_e kind = UVM_PREDICT_DIRECT,
+ uvm_reg_byte_en_t be = -1);
if (is_shadowed && kind != UVM_PREDICT_READ && (shadow_wr_staged || shadow_update_err ||
(shadow_fatal_lock && rw.path != UVM_BACKDOOR))) begin
`uvm_info(`gfn, $sformatf(
@@ -274,13 +257,36 @@
super.do_predict(rw, kind, be);
endfunction
- virtual task poke (output uvm_status_e status,
- input uvm_reg_data_t value,
- input string kind = "BkdrRegPathRtl",
- input uvm_sequence_base parent = null,
- input uvm_object extension = null,
- input string fname = "",
- input int lineno = 0);
+ // This function is used for wen_reg to lock its lockable flds by changing the lockable flds'
+ // access policy. For register write via csr_wr(), this function is included in post_write().
+ // For register write via tl_access(), user will need to call this function manually.
+ virtual function void lock_lockable_flds(uvm_reg_data_t val);
+ if (is_wen_reg()) begin
+ foreach (m_fields[i]) begin
+ dv_base_reg_field fld;
+ `downcast(fld, m_fields[i])
+ if (fld.is_wen_fld()) begin
+ uvm_reg_data_t field_val = val & fld.get_field_mask();
+ string field_access = fld.get_access();
+ case (field_access)
+ // discussed in issue #1922: enable register is standarized to W0C or RO (if HW has
+ // write access).
+ "W0C": if (field_val == 1'b0) fld.set_lockable_flds_access(1);
+ "RO": ; // if RO, it's updated by design, need to predict in scb
+ default:`uvm_fatal(`gfn, $sformatf("lock register invalid access %s", field_access))
+ endcase
+ end
+ end
+ end
+ endfunction
+
+ virtual task poke(output uvm_status_e status,
+ input uvm_reg_data_t value,
+ input string kind = "BkdrRegPathRtl",
+ input uvm_sequence_base parent = null,
+ input uvm_object extension = null,
+ input string fname = "",
+ input int lineno = 0);
if (kind == "BkdrRegPathRtlShadow") shadowed_val = value;
else if (kind == "BkdrRegPathRtlCommitted") committed_val = value;