import uvm_pkg::*;
`include "uvm_macros.svh"
class ahb_monitor extends uvm_monitor;
`uvm_component_utils(ahb_monitor)
bit data;
//uvm_analysis_port#(ahb_transaction) ap;
ahb_transaction item;
virtual ahb_interface ahb_vif;
function new(string name="ahb_monitor",uvm_component parent = null);
super.new(name,parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual ahb_interface)::get(this," ","ahb_if",ahb_vif))
`uvm_fatal(get_full_name(),"Failed to get inteface inside ahb_monitor")
endfunction
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
item = ahb_transaction::type_id::create("item");
//$display("Inside ahb monitor");
uvm_hdl_read("tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HREADY",data);
//$display("Value of data = %b",data);
uvm_hdl_read("tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HREADY",data);
//@(posedge tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HCLK)
//@(posedge tb_top.dut.u_cmsdk_mcu_system.HCLK)
@(posedge ahb_vif.clock)
$display("After clock\n");
//wait(tb_top.dut.u_cmsdk_mcu_system.HREADY == 1'b1 && (tb_top.dut.u_cmsdk_mcu_system.HWRITE == 1'b0 || tb_top.dut.u_cmsdk_mcu_system.HWRITE == 1'b1))
wait(ahb_vif.h_ready == 1'b1 && (ahb_vif.h_write== 1'b0 || ahb_vif.h_write == 1'b1))
$display("After wait\n");
//if(tb_top.dut.u_cmsdk_mcu_system.HWRITE == 1'b0) begin
if(ahb_vif.h_write == 1'b0) begin
//item.raddr = ahb_vif.addr;
//item.raddr = tb_top.dut.u_cmsdk_mcu_system.HADDR;
item.raddr = ahb_vif.addr;
//$display("Value of read address = %h\n",item.raddr);
//$display("Inside read condition\n");
end
else begin
//item.waddr = tb_top.dut.u_cmsdk_mcu_system.HADDR;
item.waddr = ahb_vif.addr;
//$display("Value of write data = %h\n",item.waddr);
//$display("Inside write condition\n");
end
//if(ahb_vif.addr == 32'hF0000000 && ahb_vif.data == 32'hAAAAAAAA) begin
//if(tb_top.dut.u_cmsdk_mcu_system.HADDR == 32'hF0000000 && tb_top.dut.u_cmsdk_mcu_system.HWDATA == 32'h0000000A) begin
//if(tb_top.dut.u_cmsdk_mcu_system.HADDR == 32'hF0000000 ) begin
//wait(tb_top.dut.u_cmsdk_mcu_system.HWDATA == 32'h0000000A)
// `uvm_info(get_full_name(),"Test Passed",UVM_LOW)
// $display("Entered inside run phase of ahb_monitor\n");
// $finish();
//end
//else begin
// `uvm_info(get_full_name(),"Test Failed",UVM_LOW)
// $finish();
//end
//ap.write(item);
end
endtask
endclass
@(posedge ahb_vif.clock)
In your title you say “driver” but in the code you showed a monitor. Assuming the code is where you have issue, a guess (With limited information provided):
- Your clock is not toggling, perhaps it is X/Z/stable.
Besides, this is extremely unconventional use of UVM - under the disguise of UVM, your code is non-reuse friendly, not adhering to standard style - if you care to, below are some observations:
- Too much use of uvm_hdl_read instead of vif.cb.HWRITE for example
- $display?? Should use `uvm_info
- Instead of ahb_vif.hwrite → use ahb_vif.mon_cb.hwrite → use clocking block unless there is a good reason not to
- @(posedge ahb_vif.clock) → use @(ahb_vif.mon_cb) → leave the clocking edge spec to the interface definition
Good luck
@(posedge ahb_vif.clock)
Do you even know if the code reaches this statement?
Interesting Q Dave - assuming standard UVM style (meaning the component is hooked up etc.), run_phase should kick start and I don’t see any blocking code prior to that line, what else can go wrong till there? I am just curious on various debug horror stories around, so asking.
Thanks
@Srini Assume nothing. Get as close to the point of failure as you can.
Nope it’s not reaching there , I have given a $display statement to see if it reaches there
posedge tb_top.dut.u_cmsdk_mcu_system.HCLK
when i used this hierarchy to sample the clock, the code is going through
I have given my interface like this,
interface ahb_interface;
logic h_write = tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HWRITE;
logic [15:0] addr = tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HADDR;
logic [31:0] data = tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HWDATA;
logic h_ready = tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HREADY;
logic clock = tb_top.dut.u_cmsdk_mcu_system.u_apb_subsystem.HCLK;
endinterface
Where and how do you pass the interface to the dynamic part of your testbench. Is there a set to the uvm_:config_db?