Assertion to find if there is any clock is active in a particular state in FSM

I have three states in FSM, and in each state different clocks are active. How do I write assertion to detect whether clocks are active are not? Note:- it should not be a temporal check (i.e it should not depend on posedge or negedge of the clock it should purely depend on the state)

In reply to sumanth291092:

  1. what is your definition of “clocks are active are not?”
    Toggling for ever until state changes?
  2. periods of the clock for each of the states?

I would approach this with separate concurrent tasks or fork-join task.

Have to think about it after I know more requirements.

In reply to ben@SystemVerilog.us:

I will give an example, I have two states s0 and s1, and three clocks clk1, clk2, clk3. In s0 state clk1 and clk2 are active, and in s1 state clk3 is active.
I need to fire an assertion when in state s0 if no clk is detected (in this case clk1 and clk2) and when in state s1 if clk33 is not detected.
But there is a catch there is no high lvl clk here controlling the FSM, so I can’t write assert (@posedge clk) or (@negedge clk)

In reply to sumanth291092:
Using the example where we address clk1 by itself.
The concept is to keep track of the clk1 being active or not active, then using an immediate assertion to check that if in ST0, the active1 variable is true.
http://systemverilog.us/vf/alive.sv // code with tb
http://systemverilog.us/vf/alive.png // image of code and simulation
3 parts to this code:

  • An initial that fires a task and waits till it’s done
  • A task with a fork join to see which forks finish first. If it’s the clock, then active==1, if it’s a #P1 then active1=0. done gets set, the e event is for debug
  • The assertion. I used a #10 after the done before checking because of the asynchronous nature of when the state changes state and when I can relably detect if the clk1 is active.
    Adjust this as needed. Other immediate assertions can be written based on state=ST1.


/* I have two states s0 and s1, and three clocks clk1, clk2, clk3. 
In s0 state clk1 and clk2 are active, and in s1 state clk3 is active.
I need to fire an assertion when in state s0 if no clk is detected 
(in this case clk1 and clk2) and when in state s1 if clk33 is not detected. */

module top;
    timeunit 1ns;  timeprecision 100ps;    
    // `include "uvm_macros.svh"     import uvm_pkg::*;
    typedef enum {ST0, ST1} st_t;
    bit   clk0=0,clk1, clk2, clk3;
    bit active1, active2, active3;
    st_t state; 
    bit  done, err;
    event e;  
    let P1=7; let P2=8; let P3=10; // periods of the clocks 
    initial forever #3 clk0 = !clk0;  // for test
    always_comb if (err) clk1=1'b0; 
                else if (state==ST0) clk1= clk0; 
                else  clk1=1'b0; 

   initial forever  begin : ALIVE1 
    t_clk1(); 
    wait (done); //@ (done); 
    done=0; 
   end 

   task automatic t_clk1();    
        fork
            PERIOD1: begin 
                #P1;  
                active1=1'b0; 
                disable CLOCK1; // ADDED                 
            end

            CLOCK1: begin
                @(clk1);
                active1=1'b1;                
                disable PERIOD1; 
            end            
        join_any
        done=1;  ->e;     
    endtask 

   always begin 
        @(posedge done); 
        #10 if(state==ST0) am_st0_clk1: assert(active1); 
    end 

     always begin // FSM 
        repeat(3) begin 
        #100 state= ST0; 
        #100 state=ST1; 
        end 
    end 

    initial begin
        err=0;
        #22 err=1;  ; // error injection 
        #44 err=0;  
    end
  endmodule
 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
** 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) https://rb.gy/cwy7nb
  3. Papers:

Udemy courses by Srinivasan Venkataramanan (http://cvcblr.com/home.html)
https://www.udemy.com/course/sva-basic/
https://www.udemy.com/course/sv-pre-uvm/

In reply to ben@SystemVerilog.us:

To kill any lingering threads on the fork activity tesryou should disable
disable CLOCK1 as shown below.

 

   task automatic t_clk1();    
        fork
            PERIOD1: begin 
                #P1;  
                active1=1'b0;     
                disable CLOCK1;           
            end
 
            CLOCK1: begin
                @(clk1);
                active1=1'b1;                
                disable PERIOD1; 
            end            
        join_any
        done=1;  ->e;     
    endtask 


In reply to ben@SystemVerilog.us:
A quick test on the fork-join_any and disable.
Note without the disable any forked tasks will linger on until completed

 
module top;
    timeunit 1ns;  timeprecision 100ps;       
    bit active1, done;
    event e, e2;  
   
   initial begin : ALIVE1 
    $timeformat(-9, 0, " ns", 10);
    #10;
    $display ("%t t_clk1", $realtime);          
    t_clk1(); 
    wait (done); //@ (done); 
    done=0; 
    #60 ->e2; 
    t_clk1(); 
    wait (done); //@ (done); 
    done=0; 
    #1000 ->e2;
    #4000 $finish; 
   end 

   task automatic t_clk1();    
        fork
            PERIOD1: begin 
                #10;  
                active1=1'b0; 
                $display ("%t Period1", $realtime);               
            end

            CLOCK1: begin
                #100;
                active1=1'b1;                
                $display ("%t CLOCK1 ", $realtime);     
            end            
        join_any
        done=1;  ->e; 
        disable t_clk1; // <******************* The disable of the fork *******
        // Without the disable 
        /*      10 ns t_clk1
         #      20 ns Period1
         #      90 ns Period1
         #     110 ns CLOCK1 
         #     180 ns CLOCK1  */ 
         /* with the disable 
               10 ns t_clk1
        #      20 ns Period1
        #      90 ns Period1*/
    endtask 
  endmodule