Uvm reg read from uvm-monitor

In reply to dhserfer:

You can have a reg_model handle in any object including uvm_compnents. A typical example for this approach is a scoreboard which compares values depending on a register content. In this scenario you do not need to perform a backdoor por frontdoor access. Simply perform a get on the register to get the actual content of that register.

In reply to chr_sue:

I am also facing the same issue when using the ral model for read the register in my uvm_monitor am getting an error:
Error-[IOUCM] Illegal use of class method
/$PROJ_DIR/hxtop_interrupt_monitor.sv

Though as of nowam using ral model in my TB and all the registers sequences are working fine.
Can you please suggest me wat go wrong here?

In reply to yuvraj khare:

Could you please show some more code from your monitor?
And I’d like to ask you what are you doing with the read register value in the monitor?

In reply to chr_sue:

In reply to yuvraj khare:
Could you please show some more code from your monitor?
And I’d like to ask you what are you doing with the read register value in the monitor?

Basically it is Interrupt monitor, so am reading the status of interrupt (if interrupt is mask) i.e. using RAL model
if(top_cfg.interrupt_mask != 32’h0) begin
while(interrupt_status == 0) begin
regmodel.reg_bank.REG_ISR.read(status,interrupt_status);
end
Getting an error where am using the reg model.
Please let me know!

In reply to yuvraj khare:

If possible show the entire code, it is very difficult to figure out what is going wrong with just 2 lines of code.

In reply to sa5691:

In reply to yuvraj khare:
If possible show the entire code, it is very difficult to figure out what is going wrong with just 2 lines of code.

class Interrupt_monitor extends uvm_monitor;

`uvm_component_utils(Interrupt_monitor)

bit [31:0] interrupt_mask;
ral_sys_model regmodel;
virtual prot_if prot_vif;

extern function new(string name, uvm_component parent);
extern function void build_phase (uvm_phase phase);
extern task run_phase (uvm_phase phase);
extern task interrupt_service ();
extern task interrupt ();
endclass : Interrupt_monitor

function void Interrupt_monitor::build_phase (uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual prot_if)::get(this,“”,“prot_vif”,prot_vif))
uvm_fatal(get_type_name(), $sformatf("Unable to get prot_vif from cfg database")) if (!uvm_config_db #(ral_sys_model)::get(null,get_full_name(),"regmodel",regmodel)) uvm_fatal(get_type_name(), “Unable to get the regmodel from cfg database”))
endfunction : build_phase

task Interrupt_monitor::run_phase (uvm_phase phase);
super.run_phase(phase);
forever begin
fork
begin
interrupt_service();
end
join
end
endtask :run_phase

task Interrupt_monitor::interrupt_service();
fork
begin
sys_interrupt();
end
begin
count = count+1;
end
join_any
endtask :interrupt_service

task Interrupt_monitor::sys_interrupt();
fork
begin //{
if(top_cfg.interrupt_mask != 32’h0) begin
while(interrupt_status == 0) begin
regmodel.reg_bank.REG_ISR.read(status,interrupt_status);
end
if(interrupt_status | hxtop_cfg.intr_enable == hxtop_cfg.intr_enable)
uvm_info(get_type_name(), $psprintf("Interrupt status is set for correct interrupt "), UVM_NONE) else uvm_info(get_type_name(), $psprintf("Interrupt status is not for correct interrupt "), UVM_NONE)
end
end //}
begin //{
if(interrupt_mask == 32’h0) begin //{
case(top_cfg.intr_enable)
32’h0000_0000: begin
wait(prot_vif.interrupt != 0);
end
32’h0000_0040: begin
wait(prot_vif.interrupt[4] != 0);
end
endcase
join_any
endtask : sys_interrupt

In reply to yuvraj khare:
i guess you might not be actually getting the error at ral model but somewhere else. Is there any typo while declaring interrupt method. It should be sys_interrupt(). Also, there is no declaration of interrupt_status.

class Interrupt_monitor extends uvm_monitor;

`uvm_component_utils(Interrupt_monitor)


bit [31:0] interrupt_mask;
ral_sys_model regmodel;
virtual prot_if prot_vif;

extern function new(string name, uvm_component parent);
extern function void build_phase (uvm_phase phase);
extern task run_phase (uvm_phase phase);
extern task interrupt_service ();
extern task interrupt ();  // It should be sys_interrupt
endclass : Interrupt_monitor

function void Interrupt_monitor::build_phase (uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual prot_if)::get(this,"","prot_vif",prot_vif))
`uvm_fatal(get_type_name(), $sformatf("Unable to get prot_vif from cfg database"))
if (!uvm_config_db #(ral_sys_model)::get(null,get_full_name(),"regmodel",regmodel))
`uvm_fatal(get_type_name(), "Unable to get the regmodel from cfg database"))
endfunction : build_phase

task Interrupt_monitor::run_phase (uvm_phase phase);
super.run_phase(phase);
forever begin
fork
begin
interrupt_service();
end
join
end
endtask :run_phase

task Interrupt_monitor::interrupt_service();
fork
begin
sys_interrupt();
end
begin
count = count+1;
end
join_any
endtask :interrupt_service

task Interrupt_monitor::sys_interrupt();
fork
begin //{
if(top_cfg.interrupt_mask != 32'h0) begin
while(interrupt_status == 0) begin
regmodel.reg_bank.REG_ISR.read(status,interrupt_status);
end
if(interrupt_status | hxtop_cfg.intr_enable == hxtop_cfg.intr_enable)
` uvm_info(get_type_name(), $psprintf("Interrupt status is set for correct interrupt "), UVM_NONE)
else
`uvm_info(get_type_name(), $psprintf("Interrupt status is not for correct interrupt "), UVM_NONE)
end
end //}
begin //{
if(interrupt_mask == 32'h0) begin //{
case(top_cfg.intr_enable)
32'h0000_0000: begin
wait(prot_vif.interrupt != 0);
end
32'h0000_0040: begin
wait(prot_vif.interrupt[4] != 0);
end
endcase
join_any
endtask : sys_interrupt

In reply to sa5691:
I paste the code just for reference. if some variable is not declared…it easy to resolve:)

In reply to yuvraj khare:

That is the reason we ask to show the full code here so that we can help you out. In the example you have shown there is no way i can know what is there inside your reg_model class and lot of other things missing. How would you expect someone to help and figure out your error unless you show full scenario or codes.

In reply to yuvraj khare:

A monitor is assigned to be a passive component. You are violating this rule by using a read to the RAL. In the testbench you need only a get. The get takes the register value from the mirror in the testbench. The read is doing a read through the bus interface and a get.
I’m wondering why you are observing your interrupt in the monitor. Finally you have to start in case of an interrupt an interrupt sequence. This happens in the sequencer. How do you send the interrupt information to the sequence/sequencer? There is no standard interface. You have to implment this on your own.
Why do you not use the existing interface betwenn the driver and the sequencer?
How to implement is you can see in a code example of the Verification Academy.
Code Example Downloads | Verification Academy, interrupts - simple.

In reply to chr_sue:

Thanks chr_sue.
It’s working now in my TB.