In reply to MahD:
You have 3 different frequencies to compute and compare.
Thus, I can see why you used tasks to compute those frequencies.
Your code below has several errors, though it compiles OK:
[list=1]
[*] The task all_clk_freq_meter() triggers 3 sequential calls to freq_meter(), rather
than concurrently; I would use afork join_none
task automatic all_clk_freq_meter();
fork
@(posedge clka) freq_meter(clka, clka_freq);
@(posedge clkb) freq_meter(clkb, clkb_freq);
@(posedge clkc) freq_meter(clkc, clkc_freq);
join_none
endtask: all_clk_freq_meter
[*] Since clocks have different frequencies, and the clk’X’_freq change at different times,
with many attempted, I would consider a ##6 in
signal_a && !signal_b |-> ##[0:6] (1, all_clk_freq_meter()) ##1 (clka_freq != clkc_freq));
I took a variation to your code. Check if this works better for you.
Basically, I run the test in 6 cycles once the antecedent is true, but also with less overlaps.
/* In the following code I am trying use the assertion in the way that when the
signal_a == 1 and signal_b == 0, within 6 clock cycle
the frequency of clka, clkb and clkc are calculates and compare with each other! */
//Any idea what did I miss? PS. The code compile and run but never calculate
//frequency/period and shows always as 0. The clka, clkb and clkc are changing over simulation!
module assertions_module (
input logic signal_a,
input logic signal_b,
input logic clkc,
input logic clka,
input logic clkb
);
real clka_freq;
real clkb_freq;
real clkc_freq;
bit ac_match, bc_match, active=1;
task automatic freq_meter(input logic clk_in, ref real clk_out_freq);
realtime start_time, end_time;
realtime period;
real clk_freq;
//@(posedge clk_in);
start_time = $realtime;
@(posedge clk_in);
end_time = $realtime;
period = end_time - start_time;
clk_freq = real'(1e12/period);
clk_out_freq = clk_freq/1e6;
endtask : freq_meter
task automatic all_clk_freq_meter();
active <= 1;
repeat(6) begin
fork : start
@(posedge clka) freq_meter(clka, clka_freq);
@(posedge clkb) freq_meter(clkb, clkb_freq);
@(posedge clkc) freq_meter(clkc, clkc_freq);
join
@(posedge clka) am_ac: if(clka_freq != clkc_freq) ac_match=1;
if(clkb_freq == clkc_freq) bc_match=1;
end
am_ac_bc_match: assert(ac_match==1 && bc_match==1);
ac_match=0; bc_match=0; active=0;
endtask : all_clk_freq_meter
always @(posedge clka) // Fire the tasks to compute the frequencies
clk_test_assert: assert property(
!active && signal_a && !signal_b |-> (1, all_clk_freq_meter()));
endmodule
Ben Cohen
Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.
or Cohen_Links_to_papers_books - Google Docs
Getting started with verification with SystemVerilog