Values of signals AT the rising/falling edge - Page 1
Forum section: electronics / general

author: TheGreatNed
author_rank: Contributor
timestamp: May 15, 2020, 12:00:41 am
content: Hi,My verilog, $display and EPWave are all disagreeing about the value of a signal at it's rising edge.I'm a noob I guessWhat is the rule of thumb for signals sampled exactly at their rising/falling edge? Do the sampled signals take the 'last' value or 'new'?Code is very simple:Code:initial begin$dumpfile("dump.vcd");$dumpvars;#5;rst = 0;a<=1;#3rst = 1;a<=0;#1a<=1;$display("time:%tns, a:%d, clk:%d, f:%d", $time, a, vif.clk, f);#20;$finish;endVCS gives:time:90ns, a:0, clk:0, f:zAs you can see, VCS and $display are disagreeing. Why?Thank you!!!!!

author: ataradov
author_rank: Super Contributor
timestamp: May 15, 2020, 12:22:34 am
content: What happens if you change the last assignment to a blocking one ("a=1;")?I'm not sure if evaluation rules apply to things like $display(), but if they are, then $display() is correct.Although for any sort of practical situations it does not matter. This will lead to meta-stability issues.

author: TheGreatNed
author_rank: Contributor
timestamp: May 15, 2020, 04:51:04 am
content: Last assignment changed to 'a=1':time:90ns, a:1, clk:0, f:zSo a=1 correctly blocks $display, but the other values surprisingly were unaffected

author: ataradov
author_rank: Super Contributor
timestamp: May 15, 2020, 04:56:29 am
content: What other values?Blocking assignment becomes a "synchronization point". All non-blocking assignments are executed in parallel.In your first case assignment and $display() executed at the same time, making both use the original value of 'a'. The assignment obviously did not care what the value of 'a' is, but $display() did.

author: TheGreatNed
author_rank: Contributor
timestamp: May 16, 2020, 12:07:51 pm
content: Quote from: ataradov on May 15, 2020, 04:56:29 amI figured 'a=1' would give clk and f enough time to realize their 'new' values. But I guess it is best to never assume a rising or falling edge is a 1 or a 0.I wonder if it makes sense to write code that always sets up data on the neg-edges of a clock and leaves the posedge for sampling?

author: ataradov
author_rank: Super Contributor
timestamp: May 16, 2020, 04:21:22 pm
content: Quote from: TheGreatNed on May 16, 2020, 12:07:51 pmIt makes sense to have all synchronous logic use non-blocking assignments and always operate on the same edge. Most often posedge is used.This closely reflects how actual hardware works. And that also gives the most time for data to setup before the next clock edge.

author: Bassman59
author_rank: Super Contributor
timestamp: May 16, 2020, 04:35:23 pm
content: Quote from: TheGreatNed on May 16, 2020, 12:07:51 pmNone of the code presented is synchronous to a clock edge. It’s all written in the form of delays, and those delays are subject to the assignment type of blocking vs non-blocking (and you really need to understand the difference) as well as the order in which the assignments are written (vital for blocking assignments).If you re-write your code so that all signals change on a clock edge and that they are all non-blocking assignments, this sort of delta-cycle ambiguity goes away. Use @(posedge clk) to wait for that event. Your code doesn’t do that.As for setting up data on the falling edge and sampling on the rising edge, there’s no need for that if everything is properly written to be synchronous to the clock. When you do this, the signals drive on a delta after one clock edge and are sampled with the next clock edge, exactly as you’d expect in a real system. The only difference between your simulation and a real design is that your model has an infinitesimal (delta) clock-to-out, zero prop delay, and zero setup to the next clock.

author: TheGreatNed
author_rank: Contributor
timestamp: May 16, 2020, 07:55:20 pm
content: If I did wait for the clock, what is the 'rule of thumb' for signals changing at the clock edge? For example:Code:@(posedge clk)a <= 1;f <= 1;$display("a:%d, f:%d", a, f);OrCode:always @(posedge clk or negedge clk)a <= clk;always @(posedge clk)data <= a;Can I really rely on this that a or data will be the 'new' values 100% of the time?

author: ataradov
author_rank: Super Contributor
timestamp: May 16, 2020, 08:01:54 pm
content: The first case would print the old values. In this test-bench (non-synthesizeable) style use blocking assignments to get what you want.In the second case I'm not exactly sure what you mean. If you mean what will be in the 'data', then it will be the value of 'a' just before the positive clock edge. So in this case it would always be 1, which was assigned at negedge of 'clk', and the value of 'clk' before the negedge was 1.

author: ejeffrey
author_rank: Super Contributor
timestamp: May 17, 2020, 02:46:20 am
content: I thought that was undefined which order separate always blocks execute when triggering on the same edge and that non blocking assignment is only deferred until the end of the current block. In that case the second example would be undefined.

author: ataradov
author_rank: Super Contributor
timestamp: May 17, 2020, 03:42:12 am
content: It would not be undefined because first block contains "negedge clk" in the sensitivity list. That's where a will be assigned a stable value. And there is no way "posedge clk" would be undefined, since it will absolutely break every single design out there.

author: Bassman59
author_rank: Super Contributor
timestamp: May 17, 2020, 03:56:13 am
content: Quote from: ataradov on May 16, 2020, 08:01:54 pmJust to clarify for "the Great Ned," what Alex means here is that on the rising edge of the clock,ais scheduled to be assigned the value 1 andfis also scheduled to be assigned the value 1. This is what the non-blocking assignment does: at the time of the trigger event (in this case, the rising edge ofclk), it evaluates all of the right-hand-sides of the signals which are triggered, in this case,aandf. The evaluation here is trivial, it's just the constant 1. But for more complex statements, all of the signals on that right-hand side are "captured," and using those values the combinatorial logic on the RHS is worked out. And by "scheduled," we mean that all right-hand-sides of all signals triggered by the event in question. (A large FPGA design may have hundreds of signals all sensitive to the rising edge of the clock!)However, the $display function is blocking. That means it will use whatever value is currently driven on its inputs (aandfin this case). These are the values of those signalsbeforethe scheduled update takes place. This is why is prints, as Alex says, "the old values."Homework: what should the output of the following always block be? And why?Code:always @(posedge clk) begincounter <= counter + 1;foobar <= counter;end

author: Bassman59
author_rank: Super Contributor
timestamp: May 17, 2020, 04:11:06 am
content: Quote from: TheGreatNed on May 16, 2020, 07:55:20 pmIn this case (and it's bizarre and you'd never do it, but ...), what will happen is clear.On the rising edge ofclk, we look at the current values ofclkanda. Assuming an initializer ona(clearing to 0), and that a rising edge meansclkis 1, this means we schedule an assignment to a of 1, and we schedule an assignment todataof 0 (the initial value ofa).The next thing that happens (of interest) is a falling edge onclk. This schedules a new assignment toa, of 0. Since the other always block is not sensitive to the falling edge ofclk, it doesn't get triggered.dataremains the same.Then there's another rising edge ofclk. This again schedules a new assignment of 1 toa. It also schedules a new assignment todata. It uses the current value ofa-- which is 0 (from the negedge event).And so forth. It helps to draw it out on paper.

author: ataradov
author_rank: Super Contributor
timestamp: May 17, 2020, 04:34:35 am
content: That case is somewhat interesting. In theory "data" would always be 0. But in practice with naive synthesis with real elements with delays, "a" would be assigned 1 on the negedge. Basically if you directly connect "clk" to the clock and data inputs.So I wonder if tools will recognize this and will actually attempt to simulate ideal simulation result with non-ideal building blocks. This never happens is real life, so I have no idea and I'm too lazy to try.

author: ataradov
author_rank: Super Contributor
timestamp: May 17, 2020, 04:50:49 am
content: Well, ok, curiosity got the best of me. Here is what Lattice Diamond generated.It basically only kept the posedge part and literally connected clk to the input. The log also contains this warning "WARNING - demo.v(11): assignment under multiple single edges is not supported for synthesis. VERI-1466".So real tools don't want to do anything with that craziness.And yes, what the value of "a" would be in a real hardware depends on the internal propagation delays within the logic block.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 17, 2020, 04:02:15 pm
content: Quote from: TheGreatNed on May 16, 2020, 07:55:20 pmNote that most FPGAs don't have dual-edge flip-flops, so the above code will either be reject by the synthesis tool, or it will at least yield warnings and will be implemented in a way that is likely to give you timing issues, and/or not even act on both edges at all.Usually, the only structures that support dual-edge stuff on FPGAs are IOBs supporting DDR, but of course what you can do with this is restricted and won't usually be inferred from "general-purpose" code.

author: Bassman59
author_rank: Super Contributor
timestamp: May 18, 2020, 12:25:37 am
content: Quote from: ataradov on May 17, 2020, 04:34:35 amI thought this discussion was all about simulation. A synthesizer will barf on everything presented here.QuoteIt will simulate — no problem. Whether the results are what are expected is the question.

author: Bassman59
author_rank: Super Contributor
timestamp: May 18, 2020, 12:29:17 am
content: Quote from: ataradov on May 17, 2020, 04:50:49 amDiamond is a synthesis tool, and as such, synthesis barfed, as expected. Try it in ModelSim or in Active-HDL.

author: ataradov
author_rank: Super Contributor
timestamp: May 18, 2020, 12:30:31 am
content: I'm aware, but have assumed that there is more than purely theoretical interest.