Assertion to check for the pulses of the clock

Hi,

Is it possible to write assertion for the following

I have a clock say 50mhz is running and I want my assertion to pulse ‘n’ consecutive clock pulses of above clock
(For Ex 2 consecutive clock pulses) based on the following conditions

The clock cycles which are to be pulsed must be of same clock period (50mhz).

a) Disable the assertion if reset is there
b) The clock cycles are to be pulsed only after the de-asserting the signal scan_en.

I implemented the code for a & b as follows

property @(posedge clk) disable iff (reset); // 50mhz

(scan_en == 1’b0) |-> ( ??? );

endproperty

Thanks
Durga

In reply to durga:
If I understand your requirements:

  1. There is a running clock clk
  2. There is a scan_en control signal that gates the clk with an output called scan clock sc_clk.
  3. That sc_clk runs for N more clock cycles following the deassertion of the scan_en control signal
    With those requirements, you can write the following:

let N=2; 
ap_scan: assert property(@(posedge clk) disable iff (reset); // 50mhz
   $fell(scan_en) |=> sc_clk[*N] ##1 !sc_clk);
// signal sc_clk ==1 @(posedge clk) N cycles following the $fell(scan_en)
// Following those N cycles, signal sc_clk ==0

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


In reply to ben@SystemVerilog.us:

You description regarding to the requirement is much clear, especially clarify sc_clk is a gated version of clk by scan_en.

The assertion is also implemented well, I read it and think maybe update is needed as below:

  • change clock event from @(posedge clk) to @(negedge clk). Assertion evaluation uses sampled values (pre-clock values), so negedge clk will get sc_clk sampled to be 1 and posedge clk will sample sc_clk to be low.
  • add scan_en to the disable condition to disable check in case scan_en asserts to bring up sc_clk running again.
  • next cycle implication |=> change to |-> same cycle implication

ap_scan: assert property(@(posedge clk) disable iff (reset); // 50mhz
   $fell(scan_en) |=> sc_clk[*N] ##1 !sc_clk);
->
ap_scan: assert property(@(negedge clk) disable iff (reset||scan_en); // 50mhz
   $fell(scan_en) |-> sc_clk[*N] ##1 !sc_clk);

In reply to ben@SystemVerilog.us:

Thank you ben for you response.

let me re frame my question

  1. I have two phases shift phase and capture phase
  2. During Shift phase there is a clock running say frequency of 100 mhz.(In shift phase
    scan_en is 1 indicating that this clock is shift clock… lets name this “shift_clk”)
  3. Now, comes the capture phase by de-asserting the “scan_en” signal.
    a) In Capture phase, i.e scan_en is “0” I get functional clock… let us name it as
    “fun_clk”

My question is I wanted to check the frequency of “fun_clk” with the expected value.
We can parameterize the expected value.

For example the expected value is 500ns.
I want the “fun_clk” time period should equal to 500ns.
If this happens assertion pass else fail.

The reason I have mentioned 2 consequtive cycles in my previous post to get the time_period.

Thanks,
durga

In reply to ben@SystemVerilog.us:

line:1 let N=2;
line:2 ap_scan: assert property(@(posedge clk) disable iff (reset); // 50mhz
line:3 $fell(scan_en) |=> sc_clk[*N] ##1 !sc_clk);
// signal sc_clk ==1 @(posedge clk) N cycles following the $fell(scan_en)
// Following those N cycles, signal sc_clk ==0

Hi ben,

In line : 3

It is mentioned as sc_clk[*2]
My question is : Is the signal “sc_clk” is high for 2 consecutive “clk” cycles ???

Thanks
durga

In reply to Lina.Lin:

In reply to ben@SystemVerilog.us:
You description regarding to the requirement is much clear, especially clarify sc_clk is a gated version of clk by scan_en.
The assertion is also implemented well, I read it and think maybe update is needed as below:

  • change clock event from @(posedge clk) to @(negedge clk). Assertion evaluation uses sampled values (pre-clock values), so negedge clk will get sc_clk sampled to be 1 and posedge clk will sample sc_clk to be low.

My mistake on this. You’re correct. My fram of mind was more on the control to the clock gating than an assertion on the clock waveform; that is the first time I see such requirements. But I would write the assertion this way if I really wanted to check the clock waveforms:

 
ap_scan: assert property(@(posedge clk) disable iff (reset); // 50mhz
   $fell(scan_en) |-> (@(negedge clk) sc_clk ##0 @(posedge clk) !sc_clk) [*N] ##0 @(negedge clk) !sc_clk[*2]); 
// Typically, one deals with the control signsls.  Thus, the forllowing would be correct
ap_scan: assert property(@(posedge clk) disable iff (reset); // 50mhz
   $fell(scan_en) |=> sc_clk_enable[*N] ##1 !sc_clk_enable);

  • add scan_en to the disable condition to disable check in case scan_en asserts to bring up sc_clk running again.

Wouldn’t that cause the miss of $fell(scan_en)
Ben SystemVerilog.us

[b]In reply to ben@SystemVerilog.us:

In reply to Lina.Lin:
Wouldn’t that cause the miss of $fell(scan_en)
Ben SystemVerilog.us

adding scan_en to disable condition wouldn’t cause the miss of $fell(scan_en) because expression in iff condition uses scan_en current value (not sampled value).

In reply to durga:

If you only want to check the func_clk period, you need to capture its period first. see if the following code works for you.


  real prev_time, cur_time, periodT;
  parameter FUNC_CLK_PERIOD = 8;
  parameter SAMPLE_CLK_PERIOD = 2; //sample clk can be TB clk or internal design clock like non-gated version fun_clk.
  
  //capture func_clk period: periodT
  always @(posedge func_clk_used_in_capture_phase ) begin
    cur_time=$time;
    periodT=cur_time - prev_time;
    $display("prev_time =%0t, current_time=%0t, periodT=%0t",prev_time, $time, periodT);
    prev_time = $time;
  end

  property P_CHECK_FUNC_CLK_PERIOD_IN_CAPTURE_PHASE;
    @(posedge sample_clk) disable iff (reset || scan_en)
    $fell(scan_en) |-> ##[FUNC_CLK_PERIOD/SAMPLE_CLK_PERIOD-1:FUNC_CLK_PERIOD/SAMPLE_CLK_PERIOD+1] periodT==FUNC_CLK_PERIOD;
  endproperty
  
  assert property (P_CHECK_FUNC_CLK_PERIOD_IN_CAPTURE_PHASE) $display("Check periodT Success: periodT=%0t",periodT); else $error("Check periodT failed: periodT=%0t", periodT);

In reply to Lina.Lin:
10.34 Measuring clock periods // From my SVA book
User’s requirement: Check that the duty cycle of a clock is within acceptable limits.
The concept is simple: based on clock edges, measure the widths in which the clock is high and low, and compare the difference against an acceptable tolerance. The use of realtime type provides more accuracy. When using a concurrent assertion, local variables are used to hold the measured values. A multiclocking approach is used to trigger on each edge of the clock.

module timem; // /ch10/10.34/timem.sv
	timeunit 100ps; timeprecision 100ps;
	initial $realtimeformat(-9, 5, " ns", 10); // for display of time
	bit clk, a, b;
	property period_chk;
		realtime current_time, deltat; // deltat used for debug, as a temp
		('1,current_time = $realtime ) ##1
			(1, deltat=current_time) ##0 deltat == 10ns;
	endproperty
	ap_time: assert property(@(posedge clk) period_chk);
	property period_chk2;
		realtime current_time, deltat;
		('1,current_time = $realtime ) ##1
			(1, deltat=current_time) ##0 (deltat >= 9.99ns && deltat<= 10.01ns); //
	endproperty
	ap_time2: assert property(@(posedge clk) period_chk2); 
	
	// On multi-clocking, you can use something like
	property @(posedge clk) disable iff (reset); // 50mhz
		realtime t; 
		(scan_en == 1'b0, t=$realtime) |-> 
			@(negedge clk2)  (1, $realtime-t== 250ns, t=$realtime) ##0
			@(posedge clk2)  (1, $realtime-t== 250ns, t=$realtime);
	endproperty	

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


In reply to ben@SystemVerilog.us:

Thanks Ben. multi-clocking assertion works much better and simpler.


   property P_CHECK_MULTI_CLOCKING;
     realtime t; 
     @(posedge sample_clk) disable iff (reset||scan_en) 
     $fell(scan_en) |-> @(posedge func_clk)  (1, t=$realtime) ##1 (($realtime-t)== FUNC_CLK_PERIOD);    
   endproperty

In reply to Lina.Lin:

Hi lina/Ben

As per my understanding,

The first line @(posedge sample_clk) disable iff (reset || scan_en) says

Disable the assertion if there is a reset or scan_en==1 and it will go to next line only when reset ==0 and scan_en==0 but when scan_en == 1’b0 there will not be any sample_clk.

The only clock I can see when scan_en==0 is func_clk.

Now my question is how it will go to second line since there will not be a sample clk when scan_en==0.

Thanks
durga

In reply to durga:
Read a page from my SVA Handbook 4th Edition on multiclocking; that should explain what you need to know.

Also, read my paper on the sva engine; you can play tricks, like adding Delay instead of a clock following you no-clock zone.
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.

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


In reply to durga:

Not sure your assertion is placed in line with the design or in test bench. If it is in the test bench, you can use a clock in the test bench as sample clock.

Or

you can use “negedge scan_en” as the event.


   property P_CHECK_CLOCKING;
     realtime t; 
     @(negedge scan_en) disable iff (reset||scan_en) 
     @(posedge func_clk_used)  (1, t=$realtime) ##1 (($realtime-t)== FUNC_CLK_PERIOD);    
   endproperty