[dv_base_reg] Extend search by name functions
This is in preparation for the alias register implementation and allows
to search a register or field by alias or generic name.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
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 123c720..24864df 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg.sv
@@ -19,6 +19,11 @@
local string update_err_alert_name;
local string storage_err_alert_name;
+ // This is used for get_alias_name
+ string alias_name = "";
+ // Lookup table for alias fields (used for get_field_by_name)
+ string field_alias_lookup[string];
+
// atomic_en_shadow_wr: semaphore to guarantee setting or resetting en_shadow_wr is unchanged
// through the 1st/2nd (or both) writes
semaphore atomic_en_shadow_wr;
@@ -30,6 +35,21 @@
atomic_en_shadow_wr = new(1);
endfunction : new
+ // this is similar to get_name, but it gets the
+ // simple name of the aliased register instead.
+ function string get_alias_name ();
+ return this.alias_name;
+ endfunction: get_alias_name
+
+ // this is similar to set_name, but it sets the
+ // simple name of the aliased register instead.
+ function void set_alias_name (string alias_name);
+ dv_base_reg_block reg_block;
+ `downcast(reg_block, get_parent())
+ reg_block.register_alias_lookup[alias_name] = this.get_name();
+ this.alias_name = alias_name;
+ endfunction: set_alias_name
+
function void get_dv_base_reg_fields(ref dv_base_reg_field dv_fields[$]);
foreach (m_fields[i]) `downcast(dv_fields[i], m_fields[i])
endfunction
@@ -381,4 +401,15 @@
return ($sformatf("%0s_%0s", get_dv_base_reg_block().get_ip_name(), storage_err_alert_name));
endfunction
+ // this overrides the get_field_by_name function
+ function dv_base_reg_field get_field_by_name(string name);
+ dv_base_reg_field retval;
+ if (field_alias_lookup.exists(name)) begin
+ `downcast(retval, super.get_field_by_name(field_alias_lookup[name]))
+ end else begin
+ `downcast(retval, super.get_field_by_name(name))
+ end
+ return retval;
+ endfunction
+
endclass
diff --git a/hw/dv/sv/dv_base_reg/dv_base_reg_block.sv b/hw/dv/sv/dv_base_reg/dv_base_reg_block.sv
index dcd50c5..7adc55b 100644
--- a/hw/dv/sv/dv_base_reg/dv_base_reg_block.sv
+++ b/hw/dv/sv/dv_base_reg/dv_base_reg_block.sv
@@ -59,6 +59,10 @@
bit has_unmapped_addrs;
addr_range_t unmapped_addr_ranges[$];
+ // Lookup table for alias registers and fields.
+ string register_alias_lookup[string];
+ string field_alias_lookup[string];
+
function new (string name = "", int has_coverage = UVM_NO_COVERAGE);
super.new(name, has_coverage);
endfunction
@@ -378,4 +382,27 @@
foreach (subblks[i]) subblks[i].set_default_map_w_subblks_by_name(map_name);
endfunction
+ // this overrides the get_reg_by_name function
+ function dv_base_reg get_reg_by_name(string name);
+ dv_base_reg retval;
+ if (register_alias_lookup.exists(name)) begin
+ `downcast(retval, super.get_reg_by_name(register_alias_lookup[name]))
+ end else begin
+ `downcast(retval, super.get_reg_by_name(name))
+ end
+ return retval;
+ endfunction
+
+ // this overrides the get_field_by_name function
+ // note however that this function is only meaningful if the fields are unique within a regblock!
+ function dv_base_reg_field get_field_by_name(string name);
+ dv_base_reg_field retval;
+ if (field_alias_lookup.exists(name)) begin
+ `downcast(retval, super.get_field_by_name(field_alias_lookup[name]))
+ end else begin
+ `downcast(retval, super.get_field_by_name(name))
+ end
+ return retval;
+ endfunction
+
endclass
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 c6998d8..8b401a6 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
@@ -14,12 +14,38 @@
local dv_base_reg_field regwen_fld;
local dv_base_lockable_field_cov lockable_field_cov;
+ // This is used for get_field_by_name
+ string alias_name = "";
+
// variable for mubi coverage, which is only created when this is a mubi reg
dv_base_mubi_cov mubi_cov;
`uvm_object_utils(dv_base_reg_field)
`uvm_object_new
+ // this is similar to get_name, but it gets the
+ // simple name of the aliased field instead.
+ function string get_alias_name ();
+ return this.alias_name;
+ endfunction: get_alias_name
+
+ // this is similar to set_name, but it sets the
+ // simple name of the aliased field instead.
+ function void set_alias_name (string alias_name);
+ dv_base_reg register;
+ dv_base_reg_block reg_block;
+ `downcast(register, this.get_parent())
+ register.field_alias_lookup[alias_name] = this.get_name();
+ // We also add the name to the lookup table inside the reg_block to enable get_field_by_name at
+ // that level. Note: in order for the get_field_by_name function of dv_base_reg_block to
+ // produce meaningful results, all field names within the reg block have to be unique - which
+ // cannot always guaranteed. If the fields are not unique at that level, the get_field_by_name
+ // of dv_base_reg should be used instead.
+ `downcast(reg_block, register.get_parent())
+ reg_block.field_alias_lookup[alias_name] = this.get_name();
+ this.alias_name = alias_name;
+ endfunction: set_alias_name
+
// Issue #5105: UVM forces the value member to be non-randomizable for certain access policies.
// We restore it in this extended class.
virtual function void configure(uvm_reg parent,