susun
susun

Reputation: 21

SVA - Is there any way to check an variable variable pattern in a variable length serial output using system verilog assertion?

For example, I have a pattern pt=1101 that needs to be checked in a serial output s_out= 1011101110111011 (LSB first). I am trying to check the "pt" in "s_out" only using SVA without using always block. Note: pt and s_out both are variable in length.

I am trying to use two counters for pt and s_out lengths but I don't know how to use them in SVA.

Any suggestions will be much helpful. Thank you, susun

Upvotes: 1

Views: 1311

Answers (1)

Tudor Timi
Tudor Timi

Reputation: 7573

You can declare internal variables in sequences and in properties. These can also have input arguments. Here's how I'd approach your problem:

First, I would create a sequence to handle matching one occurrence of the pattern. This sequence would take the pattern as an argument, together with the length:

sequence pattern_in_output(pattern, int unsigned len);
  int unsigned count = 0;
  (
    s_out == pattern[count],
    $display("time = ", $time, " count = ", count),
    count += 1
  ) [*len];
endsequence

Notice that the pattern argument is untyped. I also left some debug prints in there for you to see how it works. Once this sequence starts, it checks for len cycles that s_out matches the appropriate bit of the pattern.

I don't know what your exact condition for checking is (when exactly you want to start and stop) so I just assumed you have a signal called tx that tells you if you are currently transmitting or not (1 means you are transmitting so we need to check, 0 means you aren't, hence no check).

The property would look something like this:

assert property (
  @(posedge clk)

  // check first group
  $rose(tx) |-> pattern_in_output(pt, 4)

  // if 'tx' is still high, need to check for another occurence
  // - repeat this forever
  ##1 tx |-> pattern_in_output(pt, 4)

  // this line causes and internal error
  //##1 tx |-> pattern_in_output(pt, 4) [+] or !tx

  // this prints when the property exits
  ##0 (1, $display("exited at ", $time))
);

We start checking on the rising edge of tx. We look for a match of our previously defined sequence. Afterwards, it could be the case that we are still transmitting and we need to check a second occurrence of the pattern. If after this second occurrence, tx is still 1, we need to check for a third and so on.

Here, I'll have to apologize for leaving you with half of an answer. I was doing this example on EDAPlayground and couldn't get this to work (I kept getting simulator internal errors). The line ##1 tx |-> pattern_in_output(pt, 4) only checks for a second occurrence. The one under that (which is commented out), ##1 tx |-> pattern_in_output(pt, 4) [+] or !tx, should check for any subsequent occurrence of the pattern while tx is still 1 and stop matching once it becomes 0.

You'll have to fiddle with the details here yourself, but I guess your question was pretty much answered. You can see how you can use internal variables inside assertion constructs.

P.S. If you want it, the full code (including testing harness) is here: http://www.edaplayground.com/x/4my

Upvotes: 2

Related Questions