UPGRADE YOUR BROWSER

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 
Search instead for 
Did you mean: 
Adventurer
Adventurer
449 Views
Registered: ‎01-18-2019

Are these two codes supposed to be the same?

Jump to solution

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:

posedge.PNG

Any comments welcome.

Thank you.

Miklos

 

 

1 Solution

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

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

Jump to solution

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. :)

View solution in original post

0 Kudos
8 Replies
Adventurer
Adventurer
448 Views
Registered: ‎01-18-2019

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

Jump to solution

However, if I use

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

then it works fine.

0 Kudos
Adventurer
Adventurer
304 Views
Registered: ‎01-18-2019

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

Jump to solution

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
Contributor
262 Views
Registered: ‎10-25-2019

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

Jump to solution

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
0 Kudos
Participant blindobs
Participant
245 Views
Registered: ‎09-13-2018

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

Jump to solution

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

 

Adventurer
Adventurer
239 Views
Registered: ‎01-18-2019

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

Jump to solution
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.
0 Kudos
Participant blindobs
Participant
233 Views
Registered: ‎09-13-2018

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

Jump to solution
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.
0 Kudos
Adventurer
Adventurer
213 Views
Registered: ‎01-18-2019

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

Jump to solution

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. :)

View solution in original post

0 Kudos
Scholar dgisselq
Scholar
80 Views
Registered: ‎05-21-2015

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

Jump to solution

@mbence76,

My own solution is to use non-blocking assignments in test bench code, rather than blocking assignments.  I've found more than one piece of nearly-inexplicable behavior that gets fixed by using non-blocking assignments.

The two aren't quite equivalent, so you might find yourself needing to make further adjustments to your code to use them, but the non-blocking assignments (followed by a clock edge of course) tend to be more robust.

Just my two cents,

Dan

0 Kudos