In reply to puranik.sunil@tcs.com:
I have a requirement in which we need to check if a clock is toggling throughout the simulation. Now if the clock is derived from another clock by dividing by an integer (which is programmed in a register), we can check this using statement similar to following :
- (assuming clock period is 2n, n is passed as argument)
drclk_prop1: assert property (
disable iff (reset) @ (posedge clk)$rose(clk_derived) |-> ##n !clk_derived
);
Assuming this code for the derivation:
always #1 clk = !clk ;
always @(posedge clk) begin
clk1 <= !clk1;
if(clk1) clk2 <= !clk2;
end
you’ll have posedges of clk, clk1, clk2 in the same time step and the sampling of clk1 at those time steps will be zero. This may work for clk1 by using the negedge of clk
EPWave Waveform Viewer waves
drclk2: assert property (
disable iff (reset) @ (negedge clk) clk1==0 |-> ##1 clk1==1);
drclk1: assert property (
disable iff (reset) @ (negedge clk) clk2==0 |-> ##1 clk2==0 ##1 clk2==1[*2]);
- Another way would be to write a sequence of (clk_derived ##n !clk_derived) repeated very large number of time and write it in assert property statement.
NO
- For the clock which is not derived but basic clock, we can however check if the period of the basic clock is 100 or 200 ns by using $time to get the interval between the times at which it is toggling. Is this correct approach?
Yes, Do a search, this was addressed many times, including me.
I just did this search: ben cohen verificationacademy period $realtime
It yielded:
Another approach modeled after my reply to
uses the fork join_any. It is modeled after my paper
Understanding the SVA Engine Using the Fork-Join Model
https://verificationacademy.com/verification-horizons/july-2020-volume-16-issue-2
Using a model, the paper addresses important concepts about attempts and threads. Emphasizes the total independence of attempts.
For reuse of the task, I wanted to use arguments with a ref to the clock.
Example: task automatic check_clk(int rpt, ref bit ck); and pass clk1. BUT:
// Actual argument ‘clk1’ passed as reference cannot be used
// within fork-join_any or fork_join_none blocks
If you can write separate tasks for each clock, this will also work, but it definitely looks complex. I am throwing it in to get you thinking about other possibilities.
(3) - EDA Playground // code
EPWave Waveform Viewer // wave
module test();
int pass, fail, deb;
bit clk, clk1=1, clk2=1; // period clk=2, clk1==4, clk2==8
always #1 clk = !clk ;
always @(posedge clk) begin
clk1 <= !clk1;
if(clk1) clk2 <= !clk2;
end
always @(posedge clk) begin
fork check_clk(2); // trigger the task
join_none
fork check_clk4(4); // trigger the task
join_none
end
task automatic check_clk(int rpt);
// Actual argument 'clk1' passed as reference cannot be used
// within fork-join_any or fork_join_none blocks
bit timeout_flag;
fork
begin
@(posedge clk1);
end
begin
repeat(rpt) @(posedge clk);
#1 timeout_flag = 1;
end
join_any;
am_stat_ok: assert(timeout_flag == 0) pass=pass +rpt +1 + rpt; //debug
else begin fail=fail+1 +rpt; $display("Fail"); end
endtask
task automatic check_clk4(int rpt);
// Actual argument 'clk1' passed as reference cannot be used
// within fork-join_any or fork_join_none blocks
bit timeout_flag;
fork
begin
@(posedge clk2);
end
begin
repeat(rpt) @(posedge clk);
#1 timeout_flag = 1;
end
join_any;
am_stat_ok4: assert(timeout_flag == 0) pass=pass +rpt +1 + rpt; //debug
else begin fail=fail+1 +rpt; $display("Fail"); end
endtask
initial begin
$dumpfile("dump.vcd"); $dumpvars;
#50 force clk1=0;
#20 $finish;
end
endmodule
Ben Cohen
Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.
or Links_to_papers_books - Google Docs
Getting started with verification with SystemVerilog