Skip to main content

Waiting on clocking block signals

Its a good practice to use the clocking blocks for creating verification components.

There are some scenarios, where you have to wait on change on some values. As an example, when DUT drives the valid signal, in monitor you wait for valid signal and then read other signal on next clock.

Lets say the DUT drives a valid signals and in your monitor you have to wait till valid is high and wait for two clocks. Then in your montior, you do something like this:

wait (interface.cb.valid == 1'b1);
@interface.cb;
@interface.cb;

What do you expect?
when valid happens, then wait for two clock cycles. But this may not happen. the first wait and then @interface.cb may happen in same cycle.
This is because the clocking block events are synchronous. The wait and the @() statement will execute in same delta.

Instead, the best way is to use this:

@(tif1.cb iff tif1.cb.data);

In this way, you wait every clock only if the cb.data is high.

Code: https://www.edaplayground.com/x/5Cev


interface tif(input clk);

logic data;

clocking cb@(posedge clk);
input data;

endclocking

endinterface

module test;

reg clk;
tif tif1(clk);

initial begin
    tif1.data = 1'b0;
    #12;
    tif1.data <= 1'b1;
end

initial begin
    //wait(tif1.cb.data == 1'b1);  //This happens on 15ns. (12ns assignment. 15ns on posedge of clock)
    @(tif1.cb iff tif1.cb.data);
    $display("[%t]:: After waiting for cb.data",$time); //Here time is 15ns.
    @(tif1.cb); //Expect this to happen at next clock edge
    $display("[%t]:: After waiting for cb",$time); //Here time is 15ns. //expect the time here to be 25ns. one posedge later.
end

initial
begin
#1000 $finish;
end
initial
begin
    clk <= 1'b0;
    forever
    begin
        #5;
        clk <= ~clk;
    end
end
endmodule

Be careful with when using @(clocking_block). This is not same as @(posedge clk)

  1. All samples and drives to clocking block inputs and outputs respectively must be synchronized to the clocking block event (cb). Do not use any other events or waits other than @cb or @(cb iff signal==1)
  2. The clock event used to trigger the clocking block must not come from a program. (we do not recommend using program blocks anyways)
  3. Once you start using clocking blocks in an interface, do not reference those signals from anything other than the clocking block in your testbench.

Comments

Popular posts from this blog

Verdi Uses - I

COVERAGE While going through some of the blog posts, i found that the Verdi supports even coverage right out of the box, but from the 2014 Version. Well till now, we relied on the URG reports and the DVE to review the coverage and apply waivers and create exclusion files. Looks verdi supports all the features.. I did not get any hands on the features of this option, soon i will find some time to play around with this option of coverage in Verdi. How to launch the verdi with coverage. $> verdi -cov -covdir <PATH_TO_TB>.simv.vdb -covdir <PATH_TO_TEST1>.simv.vdb -covdir <PATH_TO_TEST2>.simv.vdb...  You can pass multiple covdirs, where in all the results will be merged. References: SYNOPSYS SITE Think Verification  

Virtual Sequence and Virtual Sequencer in UVM

Virtual sequences and sequencers in UVM are just virtual containers of multiple sequences and sequencers. Using virtual sequencers and sequences can be done in these three ways: Using only virtual Sequence and handles of sequencers inside the virtual sequence. Using Virtual sequencer to hold the sequencers Same as step 2, by using uvm_declare_p_sequencer. Virtual Sequencer does not create any sequencer objects, rather it points to other physical sequencers in different agents.  Virtual Sequencer extends from uvm_sequencer. Virtual sequence will create its sequences and start them. Running sequences can be controlled by user in the body() task. virtual sequence extends from uvm_sequence. METHOD-1: In this method, we will have one base virtual sequence which will hold the handles to different sequencers. Here we dont use any virtual sequencer. We just use the nested seqeunces with handles ot sequencers inside sequence itself. //This is the base virtual se...

Good uses of System Verilog DPI..

What is DPI?? Well, The easiest answer is Direct Programming Interface. The DPI is used to communicate the system verilog/ Verilog code to any other language. Well DPI has its own advantages over PLI.  You can check out the differences between the DPI and PLI   HERE . With DPI, you can directly call the c-functions from system verilog code and vice versa. With lot of SOCs and complicated chips in the silicon industry, sometimes you cannot completely live with the generic UVM/System verilog to write complete stimulus for complete chip.  Basics of DPI, Basics of DPI can be found when you google it.  There are some interesting cases where you will find the uses of DPI. I will get through some advanced take aways from IEEE 1800.2012 LRM. You cannot export the objects with in class. You can export only from static objects. exporting the tasks/functions should be in a module/program/interface scope.[or any static scope] . ..... Bear with me as th...