I am running uvm_reg_hw_reset_seq on my regmodel. But before running I am writing onto a register (which is a must for my Env.)
So, I am trying to update the mirror value (through callback) for that register while the uvm_reg_reset_seq is being executed.
Below is the code :
class regmodel_write_cb extends uvm_reg_cbs;
ral_sys_REGBLOCK_wrapper regmodel;
// ... other things
virtual task post_read(uvm_reg_item rw);
begin
bit [31:0] rstcfg;
this.regmodel.REGBLOCK.RSTCFG.predict(32'h0003);
rstcfg = this.regmodel.REGBLOCK.RSTCFG.get_mirrored_value();
$display("after prediction values are rst %h ",rstcfg);
end
endtask
// ... other things
endclass
I have only shown the logic which I am implementing for overwriting the mirror value. Rest other things like callback registration, writing of this registers in the Top Env etc. are being done properly.
My intention here is to test the uvm_reg_hw_reset_seq on this register with it’s updated value ('h3). Not with the reset value ('h0).
Did I understand you right: you Need a Special valaue in one of your registers before running the hw_reset_seq?
Does this make sense, writing a certain value which is immediately overwritten bya the reset_seq?
My intention is to change the mirrored value (which is 'h0 after reset) to the value which I write (as 'h3 in my Top Env) before running the hw_reset_seq.
So that I can avoid this Error :
reporter [RegModel] Register “regmodel.REGBLOCK.RSTCFG” value read from DUT (0x0000000000000003) does not match mirrored value (0x0000000000000000)
So, basically my Idea is to override the mirrored value just after the read and just before the comparison takes place inside the hw_reset_seq for this register.
Hence, I am calling the predict() method inside the post_read() method.
Hope you got what I am trying to achieve here… :)
There might be one question in your mind that why am I writing to that register from the Top Env. The answer is that my Env needs to have that register written with that value ('h3) due to some setup requirement.
I think there is something wrong with your Environment. DUT contains 'h3 this is the value after reset. But the mirror was not reset correctly or your Register model is wrong regarding this reset value. Please double-check.
Yes, DUT contains 'h3 after reset. This is because, I do call .predict() method inside pre_write() method in order to make sure that the register will hold 'h3 value through out the simulation.
I want to update the mirror value to 'h3 before the comparison. But I am unable to do it.
class customized_uvm_reg_hw_reset_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
// Subset of maps to be considered for running this sequence
string test_on_maps[$];
bit [31:0] register_addr;
reg_test_splitter m_reg_split_h;
bit model_should_not_be_reset;
bit predict_retention;
int retention_value;
`uvm_object_utils(customized_uvm_reg_hw_reset_seq)
function new(string name="customized_uvm_reg_hw_reset_seq");
super.new(name);
m_reg_split_h = reg_test_splitter::type_id::create("m_reg_split_h");
endfunction
virtual task body();
uvm_reg regs[$];
uvm_reg_map maps[$];
string map_name;
if (model == null)
begin
`uvm_error("customized_uvm_reg_hw_reset_seq", "Not block or system specified to run sequence on");
return;
end
m_reg_split_h.get_configs();
uvm_report_info("STARTING_SEQ",{"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
if (uvm_resource_db#(bit)::get_by_name({"REG::",model.get_full_name()},
"NO_REG_TESTS", 0) != null ||
uvm_resource_db#(bit)::get_by_name({"REG::",model.get_full_name()},
"NO_REG_HW_RESET_TEST", 0) != null )
return;
// Hack for specific model to be reset/not
if(!model_should_not_be_reset)
begin
`uvm_info("RESETTING_REG_MODEL",get_name(),UVM_LOW)
this.reset_blk(model);
model.reset();
end
else
`uvm_info("NOT_RESETTING_REG_MODEL",get_name(),UVM_LOW)
model.get_maps(maps);
// Iterate over all maps defined for the RegModel block
foreach (maps[d])
begin
map_name = maps[d].get_name();
foreach(test_on_maps[i])
begin
if (map_name == test_on_maps[i])
begin
uvm_status_e status;
regs.delete();
maps[d].get_registers(regs);
if (regs.size() == 0)
begin
`uvm_fatal("customized_uvm_reg_hw_reset_seq", "Did not find any registers to test")
return;
end
m_reg_split_h.filter(regs);
foreach (regs[i])
begin :foreach_loop
uvm_reg my_reg = regs[i];
uvm_status_e status;
register_addr = regs[i].get_address();
// Registers with certain attributes are not to be tested
if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
"NO_REG_TESTS", 0) != null ||
uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
"NO_REG_HW_RESET_TEST", 0) != null )
begin
continue;
end
// Simpl hack to load the mirror value apart from reset value
if(predict_retention && regs[i].get_name() == "RETENTION_REGISTER")
regs[i].predict(retention_value);
// Regular mirror method
regs[i].mirror(status, UVM_CHECK, UVM_FRONTDOOR, maps[d], this);
if (status != UVM_IS_OK)
begin : uvm_okay
`uvm_error(get_type_name(),
$sformatf("Status was %s when reading reset value of register \"%s\" through map \"%s\".",
status.name(), regs[i].get_full_name(), maps[d].get_full_name()));
end : uvm_okay
end :foreach_loop
end
end
end
endtask: body
endclass: customized_uvm_reg_hw_reset_seq
In reply to chr_sue:
My intention is to change the mirrored value (which is 'h0 after reset) to the value which I write (as 'h3 in my Top Env) before running the hw_reset_seq.
So that I can avoid this Error :
So, basically my Idea is to override the mirrored value just after the read and just before the comparison takes place inside the hw_reset_seq for this register.
Hence, I am calling the predict() method inside the post_read() method.
Hope you got what I am trying to achieve here… :)
There might be one question in your mind that why am I writing to that register from the Top Env. The answer is that my Env needs to have that register written with that value ('h3) due to some setup requirement.
One thing you should note here is,
hw-rst-seq does model.reset() followed by reg.mirror().
From your env if you are writing 'h3 to register and followed by hw-rst-seq, then its expected that the register value to have 'h0. and there will be an UVM_ERROR in hw-rst-seq.
so if you don’t want that register to get affected by model.reset(), then you can skip that register else you can modify the register’s predict value before mirror() method as specified in hack-code and get your job done.
It is completely confusing what you are saying. Because running a hw_reset seq overwrites any value in the DUT and the mirror. It does not make sense first to write something to a certain Register and immediately afterwards running a hw_reset seq.
If the mirror Returns you 'h0 and #h0 is not the reset value of this Register soemthing is wrong with your Environment. Because the mirror Returns the Default initial value of your Register.
The hw_res seq works perfectly. I’m using it in all my projects.
I think, the issue here is, the DUT is right in having the resetvalue of 3, but the reg_model is expecting a value of 0 (which is an issue). So as a workaround he is trying to update the mirror value.
But, I think eventually he will need to fix the reg_model, rather than the working around it.
**Solution:**Now coming to WA, I think rather than predict(), you can use set_reset(val) I think.
I believe the DUT register has the value 3. If the mirror is not setup correctly it always returns 0. This is what I have seen in my projects. But another reason could also be the reset value of this register is wrong. This can be checked and corrected manually without big effort.
In this case if you are using the reset method of the register model it will also fail.
In my code when I write the register from top env, I call the pre_write() method. In which I update the value to 'h3 by calling the same predict() method.
I have mentioned that I have to write this register for some Env requirement whcih cannot be avoided.
So, I am trying to update the mirror value again while executing the hw_reset_seq.
As I am not able to do it as of now, I would rather skip this register from hw_reset_seq (as suggested by tesjastv).