In reply to verif_25:
Hello,
I need to read/write and apply different methods on my register model, however I am unable to get access simultaneously to different registers with the same name.
e.g: In my sequence I need to get the mirrored value of REGx with x = 1 … 30
and in my regmodel ,each of these registers is instantiated separately, so every time I need to write in or read these registers ,I need to call them one by one .
is there any better way to do this,because it is really inconvenient for large number of registers.
Thanks,
You could try to play around with the uvm_re (regular expressions) to get all the registers in your model that match a specific pattern (keep in mind you need to have DPI enabled when compiling the UVM library and UVM regex uses POSIX AFAIK)
For example given the following register and reg model:
import uvm_pkg::*;
`include "uvm_macros.svh"
class my_reg extends uvm_reg;
`uvm_object_utils(my_reg)
rand uvm_reg_field f1;
function new (string name = "");
super.new(name, 8, UVM_NO_COVERAGE);
endfunction
function void build;
f1 = uvm_reg_field::type_id::create("f1");
f1.configure(this, 8, 0, "RW", 0, 0, 1, 1, 0);
endfunction
endclass
class my_reg_model extends uvm_reg_block;
`uvm_object_utils(my_reg_model)
// A register model containing two registers
rand my_reg r0;
rand my_reg r1;
rand my_reg r30;
rand my_reg rX;
function new (string name = "");
super.new(name, build_coverage(UVM_NO_COVERAGE));
endfunction
function void build;
r0 = my_reg::type_id::create("r0");
r0.build();
r0.configure(this);
r0.add_hdl_path_slice("r0", 0, 8); // name, offset, bitwidth
r1 = my_reg::type_id::create("r1");
r1.build();
r1.configure(this);
r1.add_hdl_path_slice("r1", 0, 8); // name, offset, bitwidth
r30 = my_reg::type_id::create("r30");
r30.build();
r30.configure(this);
r30.add_hdl_path_slice("r30", 0, 8); // name, offset, bitwidth
rX = my_reg::type_id::create("rX");
rX.build();
rX.configure(this);
rX.add_hdl_path_slice("rX", 0, 8); // name, offset, bitwidth
default_map = create_map("my_map", 0, 3, UVM_LITTLE_ENDIAN); // name, base, nBytes
default_map.add_reg(r0, 0, "RW"); // reg, offset, access
default_map.add_reg(r1, 1, "RW"); // reg, offset, access
default_map.add_reg(r30, 2, "RW"); // reg, offset, access
default_map.add_reg(rX, 3, "RW"); // reg, offset, access
lock_model();
endfunction
endclass
You could implement the logic somewhere in your sequence etc
module test();
bit match;
string regex = "r[0-9]+";
my_reg_model regmodel;
uvm_reg reg_list[$];
uvm_reg reg_list_to_be_written[$];
initial begin
regmodel = my_reg_model::type_id::create("regmodel");
regmodel.build();
regmodel.print();
regmodel.get_registers(reg_list);
foreach(reg_list[i]) begin
match = uvm_re_match(regex, reg_list[i].get_name());
if(!match) begin // zero means match
`uvm_info("TEST", $sformatf("reg = %s found with regex = %s", reg_list[i].get_name(), regex), UVM_LOW)
reg_list_to_be_written.push_back(reg_list[i]);
end
end
do_stuff(reg_list_to_be_written);
$finish;
end
task automatic do_stuff (ref uvm_reg regs[$]);
uvm_reg_data_t mirror_value;
foreach(regs[i]) begin
mirror_value = regs[i].get_mirrored_value();
`uvm_info("TEST", $sformatf("reg = %s mirrored value = %0h", regs[i].get_name(), mirror_value), UVM_LOW)
end
endtask
endmodule
Which outputs:
# KERNEL: ---------------------------------------------------
# KERNEL: Name Type Size Value
# KERNEL: ---------------------------------------------------
# KERNEL: regmodel my_reg_model - @445
# KERNEL: r0 my_reg - @447
# KERNEL: f1 uvm_reg_field ... RW r0[7:0]=8'h00
# KERNEL: r1 my_reg - @451
# KERNEL: f1 uvm_reg_field ... RW r1[7:0]=8'h00
# KERNEL: r30 my_reg - @455
# KERNEL: f1 uvm_reg_field ... RW r30[7:0]=8'h00
# KERNEL: rX my_reg - @459
# KERNEL: f1 uvm_reg_field ... RW rX[7:0]=8'h00
# KERNEL: my_map uvm_reg_map - @463
# KERNEL: endian ... UVM_LITTLE_ENDIAN
# KERNEL: r0 my_reg ... @447 +'h0
# KERNEL: r1 my_reg ... @451 +'h1
# KERNEL: r30 my_reg ... @455 +'h2
# KERNEL: rX my_reg ... @459 +'h3
# KERNEL: ---------------------------------------------------
# KERNEL: UVM_INFO /home/runner/testbench.sv(85) @ 0: reporter [TEST] reg = r0 found with regex = r[0-9]+
# KERNEL: UVM_INFO /home/runner/testbench.sv(85) @ 0: reporter [TEST] reg = r1 found with regex = r[0-9]+
# KERNEL: UVM_INFO /home/runner/testbench.sv(85) @ 0: reporter [TEST] reg = r30 found with regex = r[0-9]+
# KERNEL: UVM_INFO /home/runner/testbench.sv(97) @ 0: reporter [TEST] reg = r0 mirrored value = 0
# KERNEL: UVM_INFO /home/runner/testbench.sv(97) @ 0: reporter [TEST] reg = r1 mirrored value = 0
# KERNEL: UVM_INFO /home/runner/testbench.sv(97) @ 0: reporter [TEST] reg = r30 mirrored value = 0
You can find more information about UVM re here
HTH,
-R