How to combine events

Hi,
I am new to system verilog, so please excuse me if my questions are basic and silly.
Is there a way to wait for two events in system verilog, which will happen at the same time stamp.
For Example: If there are two differential clocks, A and B, in a system. I want to check for the rising edge of A and falling edge of B.

  fork 
     @(posedge A);
     @(negedge B);
  join

The above code worked for me, but i want to know if there is any other way to achive the same with a single line statement.

        Thanks for your support in advance.
  • regards
    JC

JC,

What you wrote is fine as long as you don’t care if the two events don’t happen at the same time or not. You should not worry about whether it is one statement or two; what is important is that it correctly captures the intent of the functionality you need.

If you do care that they happen at the same time, then is there some amount of skew possible? If so, you will have to sample the two signals with a third clock, or use one clock to sample the other. You might want to look at the expect statement to wait for a sequence to happen.

In reply to dave_59:

Hi Dave,
Thanks for your reply. The two signals are differential clock signals i.e B is inverted clock of A. The posedge of A and negedge of B happens at the same time. There is no skew between the two clocks. But even if there is some skew, the fork join will work.

As this is not a temporal expression i am not using the expect statement. I just want my code to proceed when these two events happen at the same time.
Assuming that there is no skew between clock A and its inverted clock B, which is the bestway to check that both posedge of A and negedge of B happens at the same time stamp?

In reply to jcvobu:

As soon as you say you want to check to signals happen at the same time, you are talking about temporal expressions. What do you consider not at the same time? The fork/join assumes that to two events always occur in pairs, and they are always the same number of both events. That would be true if clock A was simply the inversion of clock B (i.e. no gating). In that case you might want to use a basic Verilog timing check to verify that.

Hi,

Since we want to wait for the posedge of A, and simultaneously check if the differential functionality is working,

time time_A, time_B;

fork
begin @(posedge A); time_A == $stime; end
begin @(negedge B); time_B == $stime; end
join

if (time_A != time_B) $error(“…”);

I haven’t tried it out though.

Regards,
Melvin

In reply to SV_baby:

Thanks melvin i think it works.

In reply to jcvobu:

What about


@(posedge A or negedge B); //if you want that goes if either A or B happens. Not exactly what you want but you can use it creatively 
//The Following will not work
@(posedge A and negedge B);//Notice that this is not allowed because two different events cannot be in the same delta and will be never triggered.
//However, you can use
@(posedge A iff (B==0));//This will trigger when posedge clock event A is triggered and the value of B is zero. The problem with this is that it doesn't ensure that B was triggered at the same time.

As Dave already said, the definition of at the same time for signals means a logical relation. In your case, it would be just to check that relation and wait for one of the signals since they change at the same time.


assert (A != B) $display ("OK. A equals not B");
    else $error("It's gone wrong");
//Another way to check
fork 
  begin
    forever 
    begin
     @(A iff (B==A));
     $display ("This is an unexpected ERROR on A event");
    end
  end
  begin
    forever 
    begin
      @(B iff (B==A));
      $display ("This is an unexpected ERROR on B event");
    end
  end
  begin
    forever 
     begin
      @(A iff (B!=A));
      $display ("This is OK and what should happens anycase");
     end
  end
join_none

You can also check if two events are aliased to each other


event evt1, evt2, evt3;
initial
begin
evt1 = evt2;
if (evt1 == evt2)
$display("evt1 == evt2");
if (evt1 === evt2)
$display("evt1 === evt2");
if (evt1 != evt3)
$display("evt1 != evt3");
if (evt3 != null)
$display("evt3 != null");
end
endprogram


The $display system tasks display the following:
evt1 == evt2
evt1 === evt2
evt1 != evt3
evt3 != null

In comparing named events, the case equality operator === works the same as the equality operator ==, and the case inequality operator !== works the same as the inequality operator !=.