In reply to rohithgm:
Looks to me that you are trying to check a gated clock (c) that is synchronous to a master clock (clk). Below is a code with a testbench. Two key approachesL
// Uses the concept of multiclocking where @ (posedge clk) (a, t=$realtime) you save the current time. Then, with the |> if @ (posedge c) exactly occurs with the @ (posedge clk) then the consequent starts right away, thus in synchronism. Else, it waits till the next @ (posedge c).
property p_c;
realtime t;
@ (posedge clk) (a, t=$realtime) |-> @ (posedge c) ($realtime==t);
endproperty
ap_c: assert property(p_c);
The Other approach uses a task that fires two threads (forks) and each measure the current time, and when joined, check the time diff. The while(a) keep on firing those threads.
ap_ac: assert property(@ (posedge clk) $rose(a) |-> (1, t_check()) ); // ** LINE 22
task automatic t_check();
automatic realtime ta1, tc;
$display("%t start of task ", $realtime);
while (a) begin : while1
fork
begin : chk1
@ (clk);
ta1=$realtime;
-> e1;
end : chk1
begin : chk2
@(c);
tc=$realtime;
-> e2;
end : chk2
join
a_intask: assert(ta1==tc) else $display ("%t clk and c not in sync", $realtime);
$display("%t ta1= %t tc=%t", $realtime, ta1, tc);
if(ta1!=tc) -> ec;
end : while1
endtask
// ****** simulation results
310 start of task
# 410 ta1= 410 tc= 410
# ** Error: Assertion error.
# Time: 54 ns Started: 51 ns Scope: top.ap_c File: C:/ben_play/./a_syncs.sv Line: 22 Expr: $realtime()==t
# Local vars : t = 51
# 540 clk and c not in sync
# 540 ta1= 510 tc= 540
# 640 clk and c not in sync
# 640 ta1= 610 tc= 640
# 710 ta1= 710 tc= 710
# 810 ta1= 810 tc= 810
# 1110 start of task
# ** Error: Assertion error.
# Time: 114 ns Started: 111 ns Scope: top.ap_c File: C:/ben_play/./a_syncs.sv Line: 22 Expr: $realtime()==t
# Local vars : t = 111
# 1210 clk and c not in sync
# 1210 ta1= 1210 tc= 1140
# 1310 clk and c not in sync
# 1310 ta1= 1310 tc= 1240
testbench
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
timeunit 1ns; timeprecision 100ps;
bit clk0, clk, a, c;
bit va, vb, vc;
realtime period =20ns;
event ec, e1, e2;
default clocking @(posedge clk);
endclocking
initial forever #(period/2) clk0=!clk0;
always @(clk0) begin
#1 clk <= clk0;
if(vb) #3 c <= clk0;
else c <= clk0;
end
property p_c;
realtime t;
@ (posedge clk) (a, t=$realtime) |-> @ (posedge c) ($realtime==t);
endproperty
ap_c: assert property(p_c);
// How can I check toggling of signal "c" when
// frequency of signal "c" is same as "clk"?
ap_ac: assert property(@ (posedge clk) $rose(a) |-> (1, t_check()) );
task automatic t_check();
automatic realtime ta1, tc;
$display("%t start of task ", $realtime);
while (a) begin : while1
fork
begin : chk1
@ (clk);
ta1=$realtime;
-> e1;
end : chk1
begin : chk2
@(c);
tc=$realtime;
-> e2;
end : chk2
join
a_intask: assert(ta1==tc) else $display ("%t clk and c not in sync", $realtime);
$display("%t ta1= %t tc=%t", $realtime, ta1, tc);
if(ta1!=tc) -> ec;
end : while1
endtask
// here you can use # delays, wait statements, @ (posedge clk),
// fork other tasks, or whatever you need to verify your requirements
initial begin
repeat(200) begin
@(posedge clk0);
if (!randomize(va, vb, vc) with
{ va dist {1'b1:=10, 1'b0:=1};
vb dist {1'b1:=1, 1'b0:=2};
vc dist {1'b1:=1, 1'b0:=1};
}) `uvm_error("MYERR", "This is a randomize error")
#3;
a <= va;
end
$stop;
end
endmodule
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr
- Verification Horizons - March 2018 Issue | Verification Academy
- SVA: Package for dynamic and range delays and repeats | Verification Academy
- SVA in a UVM Class-based Environment
SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy
FREE BOOK: Component Design by Example
… A Step-by-Step Process Using VHDL with UART as Vehicle
http://systemverilog.us/cmpts_free.pdf