module test;
reg a, b;
initial begin a = 0; b = 0; #1 a = 1; end
always @(a) begin $display("edge on a"); b = 0; b = 1; b = 0; end
always @(b) begin $display("edge on b"); a = 0; a = 1; a = 0; end
endmodule
Everyone agrees there's an edge on a at time 1. Now the question is, should
this edge trigger an edge on b? And should that edge re-trigger another
edge on a, leading to an infinite loop? Pedantically speaking, you may say
that there should be an edge generated. But that's not what you want.
Practically speaking, the "edge" on b was totally false, since by the end of
the time slice, the variable went back to zero. When you synthesize this into
real gates, no signals are ever going to change voltage.
This desired behavior, that there NOT be an edge generated, is depended upon
heavily in many state machines. (The common case of this is setting
default values for outputs, then in a case on the particular state, setting
any outputs correctly. Another state machine can have this variable in its
sensitivity list, do the same thing to its own variables, which the first
state machine could have in its sensitivity list, ...) Synopsys in fact
recommends designing state machines this way.
In fact, it's "fortunate" that the short example above fails in Verilog-XL,
because so much other real code that does the same thing (multiple transitions
in zero delay, but the final value is the same as the value entering that time
slot) DON'T cause an edge.
Rather than leave the behavior unpredictable, I think it makes sense to
codify it such that that there is a correct behavior. What I'd like to know
is if anyone would ever want a case where a zero time transition from 0, to
1, then back to 0, should be treated as an edge on the signal.
Otherwise, I think the clear behavior should be the practical case, NOT to
propagate a false edge.
-Kartik
If the signal is a clock to an edge triggered flip flop I would want to know
when this happened.
Since the working definition of "zero time" in your example seems to
be "smaller than the resolution of your simulation", it could be non
zero. Therefore the rising edge of the clock has the potential to change
the output.
This sounds a little contrived and it probably is if your time slot is
reasonably small.
i am going to experiment with applying a zero delay glitch to a gate level
circuit. Observing the output should be interesting. Does the gate circuit
reevaluate its output ?
-samir
---
Samir Palnitkar
Member of Technical Staff
Sun Microsystems
Mountain View, CA
(415) 786-6013 (W)
My definition of zero time is strictly that -- no time has elapsed
between events. I'll even restrict it further if you want -- two assignments
to the same register within the same block, with no # statements between those
assignments.
The registers are being multiply assigned for programming convenience, not
to indicate any actual value changes on the signals.
Here's some more context. I would rather write this:
initial e = 1;
always @(a or b or c) begin
d = 0; e = 0; f = 0; g = 0; h = 0; i = 1; j = 0; k = 1;
if (a) e = 1;
if (b) g = 1;
end
than:
initial e = 1;
always @(a or b or c) begin
if (a) begin
e = 1;
d = 0; f = 0; g = 0; h = 0; i = 1; j = 0; k = 1;
end
if (b) begin
g = 1;
d = 0; e = 0; f = 0; h = 0; i = 1; j = 0; k = 1;
end
end
You get the idea. Granted, you could rewrite the bottom example a bit more
simpler, but in the most general case, that's what you're left with, if you
want to strictly ensure that multiple assignments don't get made in a
single time slot.
I think the proper behavior of the simulator should be to allow the
sensible code, the top example, to work properly.
-Kartik
I would suggest that you keep clear of cause-effect chains with zero time
separation between them, or that you should not expect rational behavior out of
such a (impossible anyway) scenario.
>Practically speaking, the "edge" on b was totally false, since by the end of
>the time slice, the variable went back to zero. When you synthesize this into
>real gates, no signals are ever going to change voltage.
>
>This desired behavior, that there NOT be an edge generated, is depended upon
>heavily in many state machines. (The common case of this is setting
>default values for outputs, then in a case on the particular state, setting
>any outputs correctly. Another state machine can have this variable in its
>sensitivity list, do the same thing to its own variables, which the first
>state machine could have in its sensitivity list, ...) Synopsys in fact
>recommends designing state machines this way.
>
>In fact, it's "fortunate" that the short example above fails in Verilog-XL,
>because so much other real code that does the same thing (multiple transitions
>in zero delay, but the final value is the same as the value entering that time
>slot) DON'T cause an edge.
That real code is in danger of exploding rather messily. I am currently having
to debug a system that presumably suffers from just that problem, because the
design run O.K. in Cadence Verilog-XL, but fails in Chronologic VCS. If people
specify races in their code, they deserve everything they get, i.e. IMHO, such
constructs are design flaws.
>
>Rather than leave the behavior unpredictable, I think it makes sense to
>codify it such that that there is a correct behavior. What I'd like to know
>is if anyone would ever want a case where a zero time transition from 0, to
>1, then back to 0, should be treated as an edge on the signal.
>
>Otherwise, I think the clear behavior should be the practical case, NOT to
>propagate a false edge.
>
> -Kartik
Frank Ieromnimon,
ie...@essex.ac.uk
This model will produce NO EDGES on b or a at time 0;
Original Verilog design did not have this construct when we designed it
in 1985-86 timeframe at Gateway. The only assignment was the blocking
assignments. Our original intent was to replicate hardware behavior in
a language and also support zero delay modeling. Verilog defines
blocking assignments such that there is no glitch in the original model
posted by KSRao.
-- Vivek Sagdeo
>In article <3k2nur$n...@tadpole.fc.hp.com>
subb...@concorde.fc.hp.com(Kartik Subbarao) writes:
>>I want to get the net's perspective on whether or not zero delay
"glitches"
>>should be propagated, if the final value is the same as that when
entering
>>the time slot. Take, for example:
>>
>>module test;
>>reg a, b;
>>initial begin a = 0; b = 0; #1 a = 1; end
>>always @(a) begin $display("edge on a"); b = 0; b = 1; b = 0; end
>>always @(b) begin $display("edge on b"); a = 0; a = 1; a = 0; end
>>endmodule
>>
>>Rather than leave the behavior unpredictable, I think it makes sense
Not! I've tried this with Verilog-XL 2.1.3, and it runs forever. Now it
maybe that Verilog is in error here, but that's neither here nor there.
-Kartik
edge on a
edge on b
edge on a
edge on b
.
.
.
-----------------------module zglitch ---------------------------
module zglitch;
reg a, b;
initial begin a=0; b=0; #1 a=1; end
always @(a) begin $display("edge on a"); b=1; b=0; end
always @(b) begin $display("edge on b"); a=0; a=1; end
endmodule
------------------------------------------------------------------
If you think about how blocking assignments are usually used in the
following context when defining combinational logic:
/* set variables to default values */
a = 0;
b = 0;
/* see if any of the outputs are activated */
if(c) a=1;
if(d) b=1;
First of all, there is a performance problem here. If c and d
are assigned in another always block, due to intermediate
changes in the value of the variables assigned through blocking
assignments, even if the final value of c and d (out of their
always block) does not change. I would expect only the final
value of a variable assigned with a blocking assignment to
trigger sensitivity lists dependent on it.
We can also run into unintentional deadlock situations since
it is possible to create false dependencies between cobinational
always blocks this way.
|
\ _ /
-- (_) --
/ \
|
Stephen
--
Velilind's Laws of Experimentation:
1. If reproducibility may be a problem, conduct the test only once.
2. If a straight line fit is required, obtain only two data points.
I have avoided this fray for a bit, and perhaps it is time to jump in.
We (Chronologic Simulation) spent a long time tuning our scheduler to
mimic what Verilog-XL was doing. [Squashing out behavioral glitches]
The above code, in VCS, and I submit, in Verilog-XL 1.6, although I
can not try it, will see at minimum one edge and at maximum three.
Why "minimum 1, maximum three"?
Because the Verilog HDL does not specify any ordering between
the enabling of always blocks and the execution of initial blocks.
% simv
Contains Chronologic Simulation proprietary information. Apr 12 17:09 1995
edge on a
edge on b
edge on a
V C S S i m u l a t i o n R e p o r t
Time: 1
CPU Time: 0.017 seconds; Data structure size: 0.0Mb
These edges are the a:x->0, b:x->0, and a:x->1 edges.
Some Verilog simulator implementations will see an infinite number of
edges; it seems as if you are using such an implementation.
Currently some of our users (Hi Kartik!) especially desire this
behaviourial glitch suppression, and suggest we insure its existence
in all blocks of code.
Basically, what these folks think they want is that a
behavioral block be specified to be broken into maximally sized
regions that are bound by begin..end, or time statements.
I.E., given:
begin
a = 0;
a = 1;
b = 0;
#1
c = 0;
c = 1;
#0
c = 0;
end
there would be exactly three regions.
Each region, these folks argue, should be executed in its entirety,
before any other region or statement is executed.
The current scheduling semantics of Verilog allow the simulator to
arbitrary interleave execution of blocks of code that are scheduled
for execution during the current delta time (to borrow a VHDL term).
Essentially, this means a simulator is free to sprinkle #0's
throughout your behavioral code.
The advantage of the arbitrary execution is a rudimentary form of race
detection.
This disadvatage is that it is a pain to supply default values for a
case statement.
-mac
--
,------. Michael McNamara Send mail to in...@chronologic.com for INFO
|CHRONO|LOGIC SIMULATION to sup...@chronologic.com for SUPPORT
`------' A VIEWlogic Company For information, call 1-800-VERILOG