Not able to access virtual interace variables inside driver code. It does not throw the fatal error. Im not able to see the After clock statement

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):

  1. 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:

  1. Too much use of uvm_hdl_read instead of vif.cb.HWRITE for example
  2. $display?? Should use `uvm_info
  3. Instead of ahb_vif.hwrite → use ahb_vif.mon_cb.hwrite → use clocking block unless there is a good reason not to
  4. @(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.

1 Like

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?