SystemVerilog Checker

In reply to mlsxdx:
There are many times when SVA is a lot lot simpler.
There are other times when SVA can be complex. Below is a non-sva solution (it needs verification). I explain an alternative way to SVA in
https://verificationacademy.com/forums/systemverilog/paper-understanding-sva-engine-simple-alternate-solutions
Abstract: Understanding the engine behind SVA provides not only a better appreciation and limitations of SVA, but in some situations provide features that cannot be simply implemented with the current definition of SVA. This paper first explains, by example, how a relatively simple assertion example can be written without SVA with the use of SystemVerilog tasks; this provides the basis for understanding the concepts of multithreading and exit of threads upon a condition, such as an error in the assertion. The paper then provides examples that uses computational variables within threads; those variables can cause, in some cases, errors in SVA. The strictly emulation model with tasks solves this issue.


/* The timing definition of two signals-(REQ, ACK) are as follows:
1.After REQ assert, ACK has to be asserted in 1~10 clk cycle
2.REQ should stay high for 5~7 clk cycles before goes low
3.After ACK assert, REQ has to be de-asserted in 1~10 clk cycle */ 

import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
    timeunit 1ns;     timeprecision 100ps;  
	bit clk, req, ack;  
    event e1, e2, e3; // for debug
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
 
    always  @(posedge clk) treqack();  

    task automatic treqack();
        automatic bit gotack, fallreq, reqhi; 
        if($rose(req)) begin : rose
         fork 
          begin: req2end
           -> e1; 
           repeat(10) begin : rpt10 
           // 1.After REQ assert, ACK has to be asserted in 1~10 clk cycle
             if(ack) begin : got
                gotack=1'b1; 
                disable rpt10;
             end : got
             @(posedge clk); 
           end : rpt10 
           a_gotack: assert(gotack) else `uvm_error("MYERR", "No ack after req in 10")
           if(!gotack) disable req2end; 
           -> e2;
           // 3.After ACK assert, REQ has to be de-asserted in 1~10 clk cycle
           repeat(10) begin  : rpt10b
             if(!req)  begin : negreq
               fallreq=1'b1;
               disable rpt10b; 
             end: negreq
             @(posedge clk) ;
           end : rpt10b
           a_gotfallreq: assert(fallreq) else `uvm_error("MYERR", "No fall of req in 10")
           if(!fallreq) disable req2end; // may not be needed
         end : req2end
         begin : Reqfor7 
          // 2.REQ should stay high for 5~7 clk cycles before goes low
            -> e3;
            repeat(7) begin : rpt7
              if(!req) begin : afell_req
               reqhi=1'b1;
               disable afell_req;
              end : afell_req
              @(posedge clk);
            end : rpt7
            areqhi7 : assert(reqhi) else `uvm_error("MYERR", "No reqhi for 7")
            if(!reqhi) disable Reqfor7; // may not be needed
         end : Reqfor7
         join
        end : rose
    endtask :treqack


 initial begin 
     repeat(200) begin 
       @(posedge clk);   
       if (!randomize(req, ack)  with 
           { req dist {1'b1:=1, 1'b0:=9};
             ack dist {1'b1:=1, 1'b0:=9};
           }) `uvm_error("MYERR", "This is a randomize error")
       end 
       $stop; 
    end 
endmodule   

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr