[dv/lock_reg] Update IPs to adopt the lock_reg changes
Following the lock_reg changes that support reg field, this PR updates
naming changes to the rest of the DV testbenches.
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 012d29c..b71ccb0 100644
--- a/hw/dv/sv/cip_lib/cip_base_vseq.sv
+++ b/hw/dv/sv/cip_lib/cip_base_vseq.sv
@@ -630,8 +630,8 @@
end
csr_utils_pkg::wait_no_outstanding_access();
- // reset after writing to enable_reg to avoid it locking associated regs
- if (test_csrs[i].is_enable_reg()) dut_init("HARD");
+ // reset after writing to wen_reg to avoid it locking associated regs
+ if (test_csrs[i].is_wen_reg()) dut_init("HARD");
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 9f18a4e..d4ece1e 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg.sv
@@ -71,6 +71,8 @@
return wen_fld.locks_reg_or_fld(obj);
endfunction
+ // Even though user can add lockable register or field via `add_lockable_reg_or_fld` method, the
+ // get_lockable_flds function will always return a queue of lockable fields.
function void get_lockable_flds(ref dv_base_reg_field lockable_flds_q[$]);
dv_base_reg_field wen_fld;
`DV_CHECK_FATAL(m_fields.size(), 1, "This register has more than one field.\
@@ -79,6 +81,7 @@
wen_fld.get_lockable_flds(lockable_flds_q);
endfunction
+ // The register is a write enable register (wen_reg) if its fields are wen_flds.
function bit is_wen_reg();
foreach (m_fields[i]) begin
dv_base_reg_field fld;
diff --git a/hw/dv/sv/dv_base_reg/dv_base_reg_field.sv b/hw/dv/sv/dv_base_reg/dv_base_reg_field.sv
index 60a27bd..58641af 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg_field.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg_field.sv
@@ -65,7 +65,9 @@
end
endfunction
- // Only used for lock regsiter and reset.
+ // Lock the write access to this field.
+ // This only pertains to a lockable field. It is invoked in the `set_lockable_flds_access()`
+ // method of its corresponding lock (wen) field.
local function void set_fld_access(bit lock);
if (lock) void'(this.set_access("RO"));
else void'(this.set_access(m_original_access));
@@ -81,12 +83,15 @@
endfunction
// Returns true if this field can lock the specified register/field, else return false.
+ // If lockable register is partially lockable (only certain field is lockable), this method will
+ // still return true.
function bit locks_reg_or_fld(uvm_object obj);
dv_base_reg_field flds[$];
get_flds_from_uvm_object(obj, `gfn, flds);
-
- foreach(flds[i]) if (!(flds[i] inside {lockable_flds})) return 0;
- return 1;
+ foreach (flds[i]) begin
+ if (flds[i] inside {lockable_flds}) return 1;
+ end
+ return 0;
endfunction
function bit is_wen_fld();
diff --git a/hw/dv/sv/dv_base_reg/dv_base_reg_pkg.sv b/hw/dv/sv/dv_base_reg/dv_base_reg_pkg.sv
index 9353b19..cb64671 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg_pkg.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg_pkg.sv
@@ -48,7 +48,13 @@
typedef class dv_base_reg;
- typedef class dv_base_reg_field;
+
+ `include "csr_excl_item.sv"
+ `include "dv_base_reg_field.sv"
+ `include "dv_base_reg.sv"
+ `include "dv_base_mem.sv"
+ `include "dv_base_reg_block.sv"
+ `include "dv_base_reg_map.sv"
function automatic void get_flds_from_uvm_object(input uvm_object obj,
input string msg = "dv_base_reg_pkg",
@@ -56,6 +62,7 @@
dv_base_reg csr;
dv_base_reg_field fld;
+ flds.delete();
if ($cast(csr, obj)) begin
csr.get_dv_base_reg_fields(flds);
end else if ($cast(fld, obj)) begin
@@ -66,11 +73,4 @@
end
endfunction
- `include "csr_excl_item.sv"
- `include "dv_base_reg_field.sv"
- `include "dv_base_reg.sv"
- `include "dv_base_mem.sv"
- `include "dv_base_reg_block.sv"
- `include "dv_base_reg_map.sv"
-
endpackage
diff --git a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
index 98a07bd..6bdc473 100644
--- a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
@@ -247,7 +247,7 @@
update_state(get_next_state(current_state));
// set sw_binding_regwen after advance OP
void'(ral.sw_binding_regwen.predict(.value(1)));
- ral.sw_binding_regwen.en.set_locked_regs_access("original_access");
+ ral.sw_binding_regwen.en.set_lockable_flds_access(.lock(0));
end
end
keymgr_pkg::OpDisable: begin
@@ -314,7 +314,7 @@
if (addr_phase_write) begin
// if OP WIP or keymgr_en=0, will clear cfg_regwen and below csr can't be written
if ((current_op_status == keymgr_pkg::OpWip || !cfg.keymgr_vif.get_keymgr_en()) &&
- ral.cfg_regwen.is_inside_locked_regs(dv_reg)) begin
+ ral.cfg_regwen.locks_reg_or_fld(dv_reg)) begin
`uvm_info(`gfn, $sformatf("Reg write to %0s is ignored due to cfg_regwen=0", csr.get_name()),
UVM_MEDIUM)
return;
@@ -336,7 +336,7 @@
// in StReset, can't change sw_binding_regwen value
// set related locked reg back to original_access as this is updated automatic in post_write
#0; // push below update to be done after post_write
- ral.sw_binding_regwen.en.set_locked_regs_access("original_access");
+ ral.sw_binding_regwen.en.set_lockable_flds_access(.lock(0));
end
// process the csr req
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfg_regwen_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfg_regwen_vseq.sv
index a1a330f..c0ed043 100644
--- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfg_regwen_vseq.sv
+++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfg_regwen_vseq.sv
@@ -54,30 +54,30 @@
wait_no_outstanding_access();
csr_rd(ral.op_status, op_status_val, .backdoor(1));
if (op_status_val == keymgr_pkg::OpWip && !cfg.keymgr_vif.kmac_data_rsp.done) begin
- write_and_check_regwen_locked_reg();
+ write_and_check_regwen_lockable_reg();
end
end
endtask
- virtual task write_and_check_regwen_locked_reg();
- bit [TL_DW-1:0] val = $urandom;
+ virtual task write_and_check_regwen_lockable_reg();
+ bit [TL_DW-1:0] val = $urandom;
// since it's timing sensitive, only write one of these reg
- dv_base_reg locked_reg;
- dv_base_reg locked_regs[$];
+ dv_base_reg lockable_reg;
+ dv_base_reg_field lockable_flds[$];
- ral.cfg_regwen.get_locked_regs(locked_regs);
- locked_regs.shuffle();
- locked_reg = locked_regs[0];
+ ral.cfg_regwen.get_lockable_flds(lockable_flds);
+ lockable_flds.shuffle();
+ lockable_reg = lockable_flds[0].get_dv_base_reg_parent();
- `uvm_info(`gfn, $sformatf("Write regwen locked reg %0s, and this write should be ignored",
- locked_reg.get_name()), UVM_MEDIUM)
- csr_wr(locked_reg, val);
+ `uvm_info(`gfn, $sformatf("Write regwen lockable reg %0s, and this write should be ignored",
+ lockable_reg.get_name()), UVM_MEDIUM)
+ csr_wr(lockable_reg, val);
// if it's control, wait until OP is done, so that control.start is clear
- if (locked_reg.get_name() == "control") begin
+ if (lockable_reg.get_name() == "control") begin
csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpWip),
.compare_op(CompareOpNe));
end
- csr_rd(locked_reg, val); // checking is done with scb
- endtask : write_and_check_regwen_locked_reg
+ csr_rd(lockable_reg, val); // checking is done with scb
+ endtask : write_and_check_regwen_lockable_reg
endclass : keymgr_cfg_regwen_vseq
diff --git a/hw/ip/kmac/dv/env/kmac_scoreboard.sv b/hw/ip/kmac/dv/env/kmac_scoreboard.sv
index ea94817..62f3026 100644
--- a/hw/ip/kmac/dv/env/kmac_scoreboard.sv
+++ b/hw/ip/kmac/dv/env/kmac_scoreboard.sv
@@ -200,7 +200,7 @@
// - entropy_seed_upper
// - key_len
// if writes to these csrs are seen, must check that they are not locked first.
- if (ral.cfg_regwen.is_inside_locked_regs(check_locked_reg) &&
+ if (ral.cfg_regwen.locks_reg_or_fld(check_locked_reg) &&
`gmv(ral.cfg_regwen) == 0) return;
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
index da6e384..19eccf1 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -388,7 +388,7 @@
if (addr_phase_write) begin
// Skip predict if the register is locked by `direct_access_regwen`.
- if (ral.direct_access_regwen.is_inside_locked_regs(dv_reg) &&
+ if (ral.direct_access_regwen.locks_reg_or_fld(dv_reg) &&
`gmv(ral.direct_access_regwen) == 0) return;
// Skip predict if the register is accessing DAI interface while macro alert is triggered.
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_regwen_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_regwen_vseq.sv
index 580acdc..72e8b1a 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_regwen_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_regwen_vseq.sv
@@ -44,26 +44,26 @@
// 2. use backdoor check otp init is not done and is not under reset
wait_no_outstanding_access();
if (cfg.otp_ctrl_vif.pwr_otp_done_o === 0 && !cfg.under_reset) begin
- write_and_check_regwen_locked_reg();
+ write_and_check_regwen_lockable_reg();
end
wait (cfg.otp_ctrl_vif.pwr_otp_done_o === 1 || cfg.under_reset || regular_vseq_done);
end
endtask
- virtual task write_and_check_regwen_locked_reg();
+ virtual task write_and_check_regwen_lockable_reg();
bit [TL_DW-1:0] val = $urandom;
// since it's timing sensitive, only write one of these reg
- dv_base_reg locked_reg;
- dv_base_reg locked_regs[$];
+ dv_base_reg lockable_reg;
+ dv_base_reg_field lockable_flds[$];
- ral.direct_access_regwen.get_locked_regs(locked_regs);
- locked_regs.shuffle();
- locked_reg = locked_regs[0];
+ ral.direct_access_regwen.get_lockable_flds(lockable_flds);
+ lockable_flds.shuffle();
+ lockable_reg = lockable_flds[0].get_dv_base_reg_parent();
- `uvm_info(`gfn, $sformatf("Write regwen locked reg %0s, and this write should be ignored",
- locked_reg.get_name()), UVM_HIGH)
- csr_wr(locked_reg, val);
- csr_rd(locked_reg, val); // checking is done with scb
- endtask : write_and_check_regwen_locked_reg
+ `uvm_info(`gfn, $sformatf("Write regwen lockable reg %0s, and this write should be ignored",
+ lockable_reg.get_name()), UVM_HIGH)
+ csr_wr(lockable_reg, val);
+ csr_rd(lockable_reg, val); // checking is done with scb
+ endtask : write_and_check_regwen_lockable_reg
endclass