Same clock domain, but different clock names

P

Paulo Dutra

Guest
A colleage challenged that the below code will work
correctly in HW, but randomly in simulation. In HW,
A and B will exchange values on each clock cycle. In
simulation, both A and B may get A's initial value.
The simulation working or not is a matter of simulator
process scheduling, so failure is random. Is this true
that it is impossible to garauntee the results in
simulation?

Code example:

clk1 <= clk0;

process pcs1(clk0)
begin
if clk0'event and clk0='1' then
A<=B;
end if;
end process pcs1;

process pcs2(clk1)
begin
if clk1'event and clk1='1' then
B<=A;
end if;
end process pcs2;
 
Paulo Dutra wrote:
A colleage challenged that the below code will work
correctly in HW, but randomly in simulation.
So, run the sim and tell us what happens.
Note that clk1'event is one delta behind clk0'event.

-- Mike Treseler
 
The simulation behaviour is correct, do a search on delta delays, the
problem is you combinatorial clock assignment. If you have access to
Modelsim than you can see the delta's (and the problem) using the list
window.

Hans
www.ht-lab.com



"Paulo Dutra" <paulo.dutra@NOSPAM.com> wrote in message
news:dim346$okh2@cliffold.xsj.xilinx.com...
A colleage challenged that the below code will work
correctly in HW, but randomly in simulation. In HW,
A and B will exchange values on each clock cycle. In
simulation, both A and B may get A's initial value.
The simulation working or not is a matter of simulator
process scheduling, so failure is random. Is this true
that it is impossible to garauntee the results in
simulation?

Code example:

clk1 <= clk0;

process pcs1(clk0)
begin
if clk0'event and clk0='1' then
A<=B;
end if;
end process pcs1;

process pcs2(clk1)
begin
if clk1'event and clk1='1' then
B<=A;
end if;
end process pcs2;
 
How is "correct" defined here? The code itself is ambiguous as to what
the "correct" behaviour is, therefore simulation results are useless.
 
Hi,
this code is a good example why you should use the after clause
sometimes in RTL :=).

clk1 <= clk0;
process pcs1(clk0)
begin
if clk0'event and clk0='1' then
A<=B;
end if;
end process pcs1;

process pcs2(clk1)
begin
if clk1'event and clk1='1' then
B<=A;
end if;
end process pcs2;
Lets assume you had a proper initialisation of A=1 and B=0 through
Reset.
The you had the time of your first rising edge of clk0.

Delta(0): Clk0=1, Clk1=0, A=1, B=0; scheduled: Clk1=1 in Delta(1), A=0
in Delta(1)
Delta(1): Clk0=1, Clk1=1, A=0, B=0; scheduled: B=A in Delta(2).

The value of A during the assignment to B is 1 if your simulator
creates the signal assignment to B before updating the scheduled values
and 0 if the simulator works other way round. You wont have different
values of different runs using the same simulator, but may have
different results using different simulators.
For some simulators your result may change, if you move process pcs2
above pcs1 (I expect no dependency of the order when using "expensive"
simulators)

bye Thomas
 
The behaviour of VHDL in this case is well defined. clk1 will delay for
1 delta after clock0 and the signal assignment from B to A will also
occur 1 delta.

pcs2 will then see a clk1 event and always perform an assignement to A
with of the old value of A received from B.

((If you do not use shared variables or procedures with identical
actuals on more than one (in)out parameter,...)) the VHDL model is
always predictable.

Use the following:

constant TDELAY: time:=10 ns;

clk1 <= clk0 after TDELAY;


process pcs1(clk0)
begin
if clk0'event and clk0='1' then
A<=B after TDELAY;
end if;
end process pcs1;


process pcs2(clk1)
begin
if clk1'event and clk1='1' then
B<=A after TDELAY;
end if;
end process pcs2;

and use a clock of - say - 100 ns. You will see what happens. The same
happens if you set TDELAY to 0 ns, which gives your code. There is no
randomness in it.

Hubble.
 
On Thu, 13 Oct 2005 09:48:14 -0700, Paulo Dutra
<paulo.dutra@NOSPAM.com> wrote:

A colleage challenged that the below code will work
correctly in HW, but randomly in simulation. In HW,
A and B will exchange values on each clock cycle. In
simulation, both A and B may get A's initial value.
The simulation working or not is a matter of simulator
process scheduling, so failure is random. Is this true
that it is impossible to garauntee the results in
simulation?

Code example:

clk1 <= clk0;

process pcs1(clk0) --<<<<<<<<< syntax, should be pcs1: process
begin
if clk0'event and clk0='1' then
A<=B;
end if;
end process pcs1;

process pcs2(clk1)
begin
if clk1'event and clk1='1' then
B<=A;
end if;
end process pcs2;
Your colleague is exactly wrong in every possible respect;
the simulation behaviour is 100% reliable and portable,
but the hardware is probably broken and probably doesn't
agree with the simulation. I suspect your colleague of
being a Verilog programmer, and therefore rather more
familiar with race conditions in simulation than in hardware :)

As others said, the assignment clk1<=clk0 introduces
a delta delay. So the simulation sequence is:

Suppose the values of A, B at start are A0, B0.
---------------
Delta cycle #1:
---------------
SIGNAL EVENTS
clk0 rises, triggering process pcs1 and the assignment
PROCESS EXECUTION (in random order - it doesn't matter)
pcs1 executes, scheduling A<=B0 for delta #2
assignment executes, scheduling clk1<='1' for delta#2
---------------
Delta cycle #2:
---------------
SIGNAL EVENTS
A updates to contain B0
clk1 updates to contain '1', triggering process pcs2
PROCESS EXECUTION
pcs2 executes, scheduling B<=B0 for delta #3
(because A already contains B0)
---------------
Delta cycle #3:
---------------
SIGNAL EVENTS
B updates to contain B0

Because of VHDL's strict two-phase simulation semantics
there is no ambiguity whatsoever, but the design fails to
work as intended - both signals end up containing the same
value B0.

In hardware, however, it's probably true that the same clock
is supplied to both FFs and so they swap the values. However,
if you changed the clock assignment to introduce some gating...

clk1 <= clk0 and clk_enable;

then the AND gate would introduce a real time delay that would
eat into the hold time window of the pcs2 flip-flop. So you
have a race condition (thanks to potential hold violation) in
the hardware. Indeed, if the simple clock copy assignment were
to synthesise to a buffer, the same thing would happen.

Here's the (approximately) equivalent Verilog that will
simulate randomly, but probably build correct hardware,
in the way your colleague suggested:

assign clk1=clk0;
always @(posedge clk0) A = B;
always @(posedge clk1) B = A;

and here's the Verilog, properly written so that it will
simulate reliably and (if no clock buffer is introduced)
synthesise correctly as well:

assign clk1=clk0;
always @(posedge clk0) A <= B;
always @(posedge clk1) B <= A;

Hold violations caused by clock-copying assignments are
a troublesome problem in VHDL, and one reason why
some people like to add a short time delay to their
flip-flop outputs to model nonzero clock-to-output delay.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
I would even say, the example shows another thing: If the "clock tree
delay" (here: 1 delta) reaches the logic delays (also 1 delta), your
expectations, your simulation and the hardware behaviour differ. Each
VHDL simulator *must* show the same result (using signals means that
the delays and assignments are well defined).

Hubble.
 

Welcome to EDABoard.com

Sponsor

Back
Top