I am trying to count how many times some condition occurs, I used “pulse_done” variable to detect the condition and “pulse_done_cnt” to count that pulse.
Variable “pulse_done” asserts for 3 times, however “pulse_done_cnt” shows count as 5.
I think there is glitch happening in between due to which it counts extra pulses.
Could you please help me to solve this issue.
module glitch_counter;
logic a, b, pulse_done;
logic clk=0;
logic [2:0] data;
reg a_reg, b_reg;
logic [2:0] data_reg;
int pulse_done_cnt;
assign a = a_reg;
assign b = b_reg;
assign data = data_reg;
assign pulse_done = a && b && data == 'h5;
always@(posedge pulse_done) begin
pulse_done_cnt += 1;
end
initial begin
$monitor("@%0t: pulse_done_cnt=%0d, pulse_done=%0d",$realtime,pulse_done_cnt,pulse_done);
$dumpfile("glitch_counter.fsdb");
$dumpvars(0,glitch_counter);
end
initial begin
#100;
$finish;
end
initial begin
fork
forever begin
#1;
clk <= ~clk;
end
join_none
a_reg = 0;
b_reg = 1;
data_reg = 0;
#5;
fork
begin //a_reg
int delay;
forever begin
delay = $urandom_range(4,7);
a_reg <= 1;
@(posedge clk);
a_reg <= 0;
repeat(delay) @(posedge clk);
end
end
begin
int i=0;
forever@(posedge a_reg) begin
i = i+1;
if (i%2 == 0) begin
data_reg <= 5;
end else begin
data_reg <= 1;
end
end
end
join_none
end
endmodule
I’m not sure what kind of better solution you’re looking for.
Your code has a delta cycle glitch. a_reg and data_reg are being updated in two different active event regions. Your solution samples pulse_done so it ignores the glitch it has. Note that $monitor or VCD $dumpvars do not show glitches.
In reply to dave_59:
Thanks for the reply Dave.
Rather ‘better’ I should have used ‘alternate’, could we use “uvm_wait_for_nba_region” somehow such that assign statement samples values in NBA region to avoid that glitch?
Second thing is, I am not sure how glitch is generated in the first place itself? Since I am driving a_reg and data_reg in the NBA region and trying to sample in the next active region i.e driving and sampling are in different timing region then how did glitch is generated? (referring to the time when pulse_done_cnt is going 1->2 due to glitch)
You are making assignments to a_reg and data_reg in successive NBA regions because you are using different posedge events. Remember that each event region may create events in other regions and will keep looping back to earlier regions until they are empty of events.
Your first forever loop waits for @(posedge clk) in the Active region and schedules assignments to a_reg in an NBA region. After the Active region is empty, we advance to the NBA region where the update to a_reg happens. That schedules the @(posedge a_reg) to resume in the Active region, as well as scheduling the continuous assign statements to revaluate.
Once the NBA region is empty, we go back to the Active region and evaluate the assign statements, update their values and if there is a posedge of a_reg, resume that process. That schedules assignments to data_reg in the NBA region. After the Active region is empty, we advance to another NBA region where the update to data_reg happens. That schedules the continuous assign statements to revaluate for the second time in another Active region. It is between these two evaluations where the glitch happens.
To avoid glitchy behavior, I suggestion only using @(posedge/negedge clk) and no other edges of any other signals. Instead of