SystemVerilog Checker

In reply to ben@SystemVerilog.us:
Update code for task method.


/* 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; 
  int delay=1;  
// Requirements: 
// 1.After REQ assert, ACK has to be asserted in 1~10 clk cycle
ap_req2ack: assert property(  
    @(posedge clk) $rose(req) |-> ##[1:10] $rose(ack) );  
// 2.REQ should stay high for 5~7 clk cycles before goes low
ap_reqHi: assert property(  
    @(posedge clk) $rose(req) |-> req[*5:7]);
//3.After ACK assert, REQ has to be de-asserted in 1~10 clk cycle 
ap_ack2req: assert property(
     @(posedge clk) $rose(req) |-> $rose(ack) [->1]  
                                   ##[1:10] $fell(req) );   

  event e1, e2, e3, e4, e5, e6; // for debug
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
 
    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; 
           rpt10: repeat(10) begin   
           // 1.After REQ assert, ACK has to be asserted in 1~10 clk cycle
             -> e6; 
             @(posedge clk); // <-- Update 
             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
           rpt10b: repeat(10) begin   
             @(posedge clk); // Updated 
             if(!$fell(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; count=1; // Update, because of the rose(req)
            rpt7: repeat(7) begin  
            $display("%t count=%d", $time, count); -> e5; 
             @(posedge clk); // Updated
              if($fell(req) || count==5) begin : afell_req // update
               reqhi=1'b1; -> e4;  $display("%t IN count=%d", $time, count); 
               disable rpt7; // Update
              end : afell_req
              else count=count+1'b1; 
              //@(posedge clk);
            end  : rpt7
            $display("%t OUT count=%d", $time, count); 
            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 
       repeat(delay)  @(posedge clk);  
       #1; if (!randomize(req, ack, delay)  with 
           { req dist {1'b1:=1, 1'b0:=9};
             ack dist {1'b1:=1, 1'b0:=1};
             delay dist {3:=1, 4:= 1, 5:=2, 7:= 1, 12:= 1};
           }) `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