Jump to content
mastrick

how to drive a clocking block output asynchronously

Recommended Posts

Our uvm_driver derivatives push values into the RTL via clocking blocks in interfaces.  This updates the signals synchronously as we typically want, but is there a recommended way to add an asynchronous update of the signal to model a change that could occur when asynchronous reset is applied?  We see that if we just assign to the signal at the interface level (not the clocking block level), we get a conflict between both assignments.  

Share this post


Link to post
Share on other sites

First, ask yourself: Do we really want to be testing timing related issues using functional simulation or would we be better served using static timing analysis (STA)?

 

If you just want to simulate what might happen for a signal arriving late/early, just drive it a clock later/earlier.

 

If you insist on driving a signal asynchronously, I would suggest creating a task to do this...

interface my_if(input clock);
  logic DATA;
  clocking cb @(posedge clock);
    default input #1step output #0ns;
    output DATA;
  endclocking
  time period=0, first=0;
  initial begin // observe/measure clock period for later use
    @(posedge clock);
    first = $time;
    @(posedge clock);
    period = $time - first;
  end
  task async_DATA(logic value, time offset);
    if (period>0 && offset>period) $warn("Offset greater than clock period.");
    if (offset == 0) $warn("Possible race situation with zero time offset.");
    fork
      @(posedge clock); // starting point for offset
      #(offset);
      $info("Driving DATA asynchronously");
      DATA <= value;
    join_none
  endtask
  modport test_mp(clocking cb, import task async_DATA(logic value, time offset));
endinterface

This approach has several benefits. First, it clearly marks the fact you are doing an asynchronous modification. Second, it requires effort to go beyond the normal synchronous drive. Third, you can see when it happens in the simulation so there are no surprises. In your transaction (uvm_sequence_item), you might want a async_time member that has a normal value of 0 and is set non-zero when invoking this "feature".

 

Debugging asynchronous issues can be a bear. I do understand the occasional need to do this.

 

I would recommend against anything that makes it too easy to generate asynchronous stimulus for something fundamentally synchronous.

Share this post


Link to post
Share on other sites

Thanks for the suggestion, David.  The situation that caused us to consider this question was that we had a verification component modeling an external interface to our ASIC, so it had its own clock, not shared with the rest of the design.  There is a possibility that clock is not running, which we wanted to model, but when the clock did not run, our drive through the clocking block never happened.  In real circuitry, even though the clock is not running, the asynchronous reset (applied to the external component also) would ensure that the external data was driven to a known value.  This made us consider that often our verification components act as if they are synchronously reset but they may not be in real life, and one can imagine scenarios where a bug could escape.

 

So your example implies that a non-blockjng assignment to DATA would change the value on DATA and not be treated as another driver to be resolved on DATA.  If so, can you say why the internal assignment behaves differently from a non-blocking assignment from outside the interface of the form m_if_instance.DATA <= value?

Share this post


Link to post
Share on other sites

While I don't use clocking blocks myself, we were considering moving to them for our VIPs. I would find it worrisome to not be able to model an asynchronous reset so I tried out what you wanted to do (updating the interface signal asynchronously based on reset). It worked on EDA Playground. Example here: http://www.edaplayground.com/x/2nj

 

In case you use a different tool vendor, I would find it surprising that they complain about any conflict as the standard clearly states that a signal can appear in multiple clocking blocks (regardless of direction) - 14.6 Signals in multiple clocking blocks. Having a signal as an output in multiple clocking blocks would cause the same situation (an update form multiple sources).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×