Assertion to multi clock and condition checker

Hi
I’m very appreciated for helps if you can give some tips on this case.
there are two clocks ,clka(~100M),clkb (~10M), and two ‘x’ and ‘z’ signals.
defualt is:
clka toggle.
clkb not toggle
‘x’ is low
‘z’ is low

I need to implment a checker to check follow condition.
in clka toggle phase, set ‘x’ to high, then clkb should be toggled in 100T (unit is clka period) when ‘x’ is high
and ‘z’ should have raise a ack pulse (0-1-0) in clkb toggle phase.

then set set ‘x’ to low
then clkb should stop toggling in 100T (unit is clka period) when ‘x’ is low
and ‘z’ should have raise a similar pulse (0-1-0) in clkb toggle phase.

In reply to guorke:
Your requirements are ambiguous and hard to follow.
I suggest that you clarifyyour requirements wth waveforms and a start of a SystemVerilog template. for example,


// this is not an assrsionb just my noted
// in struggling to understand the requirements 
module top; 
    timeunit 1ns/100ps;
    `include "uvm_macros.svh"
     import uvm_pkg::*;
     bit clka, clkb, x, z;  
     default clocking @(posedge clka); 
     endclocking
     initial forever #10 clk=!clk;  
     initial begin
       $timeformat(-9, 1, "ns", 8);
       $display("%t", $realtime);
    end 
/* I need to implment a checker to check follow condition.
in clka toggle phase, set 'x' to high, then clkb should be toggled in 100T (unit is clka period) when 'x' is high
and 'z' should have raise a ack pulse (0-1-0) in clkb toggle phase. */ 
always @(@(clka) begin
    realtime v; 
    bit ten_ps; 
    x<=1'b1; 
    v=$realtime; 
    @(clkb) $realtime -v==10ps; 
    assert(z==0); 
    ap: assert property(@(clkb) ack ##1 !ack);  
    #100000; 
    
/* then set set 'x' to low
then clkb should stop toggling in 100T (unit is clka period) when 'x' is low
and 'z' should have raise a similar pulse (0-1-0) in clkb toggle phase. */ 
    x<=1'b0; 
    v=$realtime;
    //  clkb should stop toggling in 100T (unit is clka period) when 'x' is low
    fork
        begin #10ps; ten_ps=1; end// need to define the units 
        @(clkb); 
    join_any
    assert(ten_ps);

end

In reply to ben@SystemVerilog.us:
clear version

In reply to guorke:
The key to defining a verification assertion (not necessarily with SVA) is to first define the 4 zones or envelopes of examinations http://systemverilog.us/vf/eobeoff.png

  1. *From $rose(x) to ##0 x[100]
    The endpoint of this sequence is identified with event e_on
  2. *From $fell(x) to x[100]
    The endpoint of this sequence is identified with event e_off
  3. The clkb_region between e_on and e_off to check for clk_b
  4. the envelope between e_on and fell(x) to check for a z
  5. the envelope between fell(x) and e_off to check for a z

 // The variables
bit clka, clkb,  x, z;  // clka(~100M),clkb (~10M)
     event e_on, e_off;    
     logic clkb_region;

// The definition of e_on and e_off
// For this I used an assertion with sequence_match_items calling a function 
unction set_event(bit on_off);
      if(on_off) -> e_on;
      else       -> e_off;
    endfunction
    
    // Region definition 
    ap_x_100Tregion: assert property(
        @(posedge clka)
         $rose(x) |-> !clkb && $past(!clkb) ##0 x[*100] ##0(1, set_event(1'b1))
                      ##[1:$] $fell(x) ##0 x[*100] ##0(1, set_event(1'b0))); 

// The clkb_region 
     always @(e_on) clkb_region <= 1'b1; 
     always @(e_off) clkb_region <= 1'b0; 

// The check clkb region for activity of the clkb 
    let half_p=55ns; // maybe 1 or 2 ns more for sync? FIX the number needed 
    always_ff @(e_on) begin
        clkb_activity_check();                
    end
    task automatic clkb_activity_check(); 
        bit no_clkb; 
        fork
            begin #half_p; no_clkb=1'b1; end 
            begin @clkb;  no_clkb=1'b0;  end  // this should come first           
        join_any
        assert(no_clkb==1'b0);
        if(clkb_region) clkb_activity_check();
    endtask

// The checks for z within their zones 
// Check for Z at start of 100T
    always @(e_on)  begin
        bit no_z; 
        fork
            begin @(posedge z) no_z=1'b0; end 
            begin @(negedge x) no_z=1'b1;  end            
        join_any
        assert(no_z==1'b0); 
    end 
    
    // Check for Z at end of 100T
    // Need to check if more than one, give it some thoughts
    always @(neg_edge(x))  begin
        bit no_z; 
        fork
            begin @(z) no_z=1'b0; end 
            begin @(e_off) no_z=1'b1;  end            
        join_any
        assert(no_z==1'b0); 
    end 

The complete untested code. I would like to see your final tested solution and your testbench.


module top; 
    timeunit 1ns/10ps;
    `include "uvm_macros.svh"
     import uvm_pkg::*;
     bit clka, clkb,  x, z;  // clka(~100M),clkb (~10M)
     event e_on, e_off; 
     default clocking @(posedge clka); 
     endclocking
     initial forever #10 clka=!clka;   
     logic clkb_region;
     // Ser clkb region envelope 
     always @(e_on) clkb_region <= 1'b1; 
     always @(e_off) clkb_region <= 1'b0; 

    function set_event(bit on_off);
      if(on_off) -> e_on;
      else       -> e_off;
    endfunction
    
    // Region definition 
    ap_x_100Tregion: assert property(
        @(posedge clka)
         $rose(x) |-> !clkb && $past(!clkb) ##0 x[*100] ##0(1, set_event(1'b1))
                      ##[1:$] $fell(x) ##0 x[*100] ##0(1, set_event(1'b0))); 

    // check clkb region for activity 
    let half_p=55ns; // maybe 1 or 2 ns more for sync? 
    always_ff @(e_on) begin
        clkb_activity_check();                
    end
    task automatic clkb_activity_check(); 
        bit no_clkb; 
        fork
            begin #half_p; no_clkb=1'b1; end 
            begin @clkb;  no_clkb=1'b0;  end            
        join_any
        assert(no_clkb==1'b0);
        if(clkb_region) clkb_activity_check();
    endtask

    // Check for Z at start of 100T
    always @(e_on)  begin
        bit no_z; 
        fork
            begin @(posedge z) no_z=1'b0; end 
            begin @(negedge x) no_z=1'b1;  end            
        join_any
        assert(no_z==1'b0); 
    end 
    
    // Check for Z at end of 100T
    always @(neg_edge(x))  begin
        bit no_z; 
        fork
            begin @(z) no_z=1'b0; end 
            begin @(e_off) no_z=1'b1;  end            
        join_any
        assert(no_z==1'b0); 
    end 
endmodule

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  2. Free books: Component Design by Example https://rb.gy/9tcbhl
    Real Chip Design and Verification Using Verilog and VHDL($3) Amazon.com
  3. Papers: