SystemVerilog Checker

In reply to mlsxdx:

In reply to ben@SystemVerilog.us:
Hi Ben, thanks for your reply. It is very helpful.
I have two doubts about the code.
//[ML]should it be $rose(ack) instead of ack?

[Ben] It does have to be, but it could be. Upon a rose of ack, or of ack=1 you disable the loop However, the $rose(ack) would catch the error if ack is always a 1’b1.


begin : Reqfor7 
// 2.REQ should stay high for 5~7 clk cycles before goes low
-> e3;
//[ML]------------------------------------------------------
//[ML] how to check lower bound >=5 clk cycles??
//[ML]------------------------------------------------------

Below is updated code. FOr that case, I used a counter and a check on that value.


/* 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();  // <---- Edited to: 
    always  @(posedge clk) fork treqack(); join_none  
    task automatic treqack();
        automatic bit gotack, fallreq, reqhi;
        automatic int count;  
        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($rose(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
              else count=count+1'b1; 
              @(posedge clk);
            end : rpt7
            areqhi7 : assert(reqhi && count>=5) else `uvm_error("MYERR", "No reqhi for 5 to  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