My interface detects output transation with 1 clk cycle delay

Hi,

I have a DUT with an output tready and an input tenbl (which is connected to an AND gate with the tready signal and a valid signal coming from another module)

To verify this DUT, I use a UVM environment where I wrote a reference model that receives the inputs generated by my sequences and listen to the output of the DUT.

The issue I’m facing is when I call (for example in my driver) `uvm_info(), to display the value of tready, I observe a delay of 1 clk cycle (10ns in my simulation). Which is annoying because a need to detect a rising/falling edge of tready to be able to discard correctly the tenbl in my reference model.

How can I remove this delay ?

Here is pieces of my code to understand how my tb is written.

//The interface I use to connect the DUT 

interface Interface(input bit clk);
    logic                               rst;
    logic[C_IMG_DATA_NBIT-1:0]          img_data;
    logic                               img_ready;
    logic                               img_enbl;
endinterface: Interface

/*
My module wrapper that instantiate a VHDL module,
 the interface and generate my clock 
*/
module md_correlation_wrapper;
    bit clk;

    Interface dut_itf(.clk);

    my_module  u_my_module(
        .clk(clk),
        .rst(dut_itf.rst),
        .img_data(dut_itf.img_data),
        .img_ready(dut_itf.img_ready),
        .img_enbl(dut_itf.img_enbl)
    );

    initial begin: clock_generator
        clk = 0;
        forever begin
            #(C_CLK_PERIOD/2);
            clk = ~clk;
        end
    end: clock_generator
endmodule: md_correlation_wrapper

/*
My driver with a virtual interface that simply display the value of img_ready
*/
class Driver extends uvm_driver#(Transaction);
    `uvm_component_utils(Driver);

    virtual Interface       dut_itf;

    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction: new

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);

        if( !uvm_config_db #(virtual Interface)::get(this, "", "Interface", dut_itf) ) begin
            `uvm_error("", "uvm_confid_db::get_failed")
        end
    endfunction: build_phase

    virtual task run_phase(uvm_phase phase);
      forever begin
          @(posedge dut_itf.clk);
          if(dut_itf.img_ready == 0)begin
              `uvm_info("", "img_ready == 0", UVM_MEDIUM);
          end
      end 
    endtask:run_phase

endclass: Driver

And here are a screenshot of what I see in the waves

and in the tcl console
image

You can see `uvm_info() is called 10ns too late

If your driver samples img_ready on the positive clock edge, and these signals are driven by VHDL processes sensitive to the same clock (same for signals driven by SystemVerilog nonblocking assignments), you always get the “old” value of the signal. That is the way synchronous designs work.

If you were to delay the clock from the driver, that would change the sampling all signals not just the ready signal.

2 Likes

In that case, how can I simulate a combinatorial logic connection between my ready and enbl ?
I want to have my input react immediately to my output without any delay