We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for
Did you mean:
449 Views
Registered: ‎01-18-2019

Are these two codes supposed to be the same?

Hello,

I wonder if there is difference between

always @ (posedge clk) begin
x <= 0;
if (condition) x <= 1;
end

and

always @ (posedge clk) x <= condition;

Their waveforms look the same, but they act differently when it comes to waiting for these signals in a testbench.

I made a very simple and clear test.

My DUT code:

module proba_mt( input clk,
output logic X=0,
output logic Y=0
);
timeunit 1ns;
timeprecision 1ps;
logic [3:0] cnt = 4'b0000; always @ (posedge clk) cnt <= cnt + 1; // cnt[3] will be the 'condition' always @ (posedge clk) X <= cnt[3]; // CASE 1 always @ (posedge clk) begin // CASE 2 Y <= 0; if (cnt[3]) Y <= 1; end endmodule

and my testbench:

module tb_proba();

timeunit 1ns;
timeprecision 1ps;

logic clk = 1;
always #5 clk++;

logic X;
logic Y;
logic sx=0;
logic sy=0;

proba_mt DUT ( .clk,  .X,  .Y );

always begin
@(posedge X)  sx = 1;
@(negedge X)  sx = 0;
end

always begin                     // EXACTLY THE SAME AS WITH X
@(posedge Y)  sy = 1;
@(negedge Y)  sy = 0;
end

endmodule

And this is what I get:

Thank you.

Miklos

1 Solution

Accepted Solutions
212 Views
Registered: ‎01-18-2019

Re: Are these two codes supposed to be the same?

Here is The Solution ! :)

If X has zero-width glitches, just add an assigment and the glitches will not be transfered.

assign W = X;

@(posedge W)   solves the problem. :)

8 Replies
448 Views
Registered: ‎01-18-2019

Re: Are these two codes supposed to be the same?

However, if I use

@(Y) sy=1;
@(!Y) sy=0;

then it works fine.

304 Views
Registered: ‎01-18-2019

Re: Are these two codes supposed to be the same?

I have done a little more research and found that this pheonomena has been noticed by many,  is well known for long, and is due to how simulators handle time. However, if a simulator triggers a posedge/negedge event when there is no change in the signal, then I consider it a serious nasty bug. Sure there are ways to get around it, still..

I have a DUT that works fine on real HW. I am trying to run an official verification on each module in it, and do not want change my DUT just because the simulator is wrong. I do not think there is anything wrong with using default values at the beginning of an always block.

Dear Xilinx, what is your view on this?

Thank you

Miklos

Contributor
262 Views
Registered: ‎10-25-2019

Re: Are these two codes supposed to be the same?

Clearly, both codes are supposed to be same . I tried same code with vhdl and the problem persits. We have to be careful in such cases and work the alternative way. Interesting issue.

Regards,
jagannath@logictronix.com
Participant
245 Views
Registered: ‎09-13-2018

Re: Are these two codes supposed to be the same?

I have done a little more research and found that this pheonomena has been noticed by many, is well known for long, and is due to how simulators handle time. However, if a simulator triggers a posedge/negedge event when there is no change in the signal, then I consider it a serious nasty bug. Sure there are ways to get around it, still..

It's not a bug, and yes both codes will produce same rtl. This 'phenomen' is because of delta cycles in simulation:

always @ (posedge clk) begin           // CASE 2
Y <= 0;
if (cnt[3]) Y <= 1;
end

At each rising edge of clk your Y will be assigned 0 value at 1 delta cycle, and then '1' if cnt[3] in 2nd delta cycle. So in verilog Y timespace there is actually a glitch 1->0->1 (it's delta cycle so it's not seen on waveform thus i bealive there is switch to see delta cycles in simulators lie aldec), that's why your process @negedge is triggered.

Look at different waveform you will get if switched

always begin                     // EXACTLY THE SAME AS WITH X
@(posedge Y)  sy = 1;
@(negedge Y)  sy = 0;
end

to:

always begin                     // EXACTLY THE SAME AS WITH X
@(negedge Y)  sy = 0;
@(posedge Y)  sy = 1;
end

Anyway for VHDL and signals it should be fine i quess, different mechanism for passing values in simulation, though variables will act the same

239 Views
Registered: ‎01-18-2019

Re: Are these two codes supposed to be the same?

Hi blindobs,

> in verilog Y timespace there is actually a glitch 1->0->1
> that's why your process @negedge is triggered.

I understand what causes this, but the end result is just not OK.
The simulator should simply not consider a pulse of zero width as two edges, methinks.
Participant
233 Views
Registered: ‎09-13-2018

Re: Are these two codes supposed to be the same?

To be honest simulator only catches one edge that's why there is pulse on output.
this code will give 'funny' waveform

always begin // EXACTLY THE SAME AS WITH X
@(posedge Y) sy = 1;
@(posedge Y) sy = 1;
@(negedge Y) sy = 0;
@(posedge Y) sy = 1;
end

as each line in block will get different schedule delta time.
TBH simulator caching 'zero' width pulses is usefull concept for logging different events in simulation time.
Anyway it's a really nice example, and maybe someone will post modelsim delta cycles of this testbench code. I currently got only Active-HDL restricted edition.
213 Views
Registered: ‎01-18-2019

Re: Are these two codes supposed to be the same?

Here is The Solution ! :)

If X has zero-width glitches, just add an assigment and the glitches will not be transfered.

assign W = X;

@(posedge W)   solves the problem. :)

Scholar
80 Views
Registered: ‎05-21-2015