Question about concurrent signal assignments

M

mamu

Guest
Hi,

when i simulate the following code I see that clk1 and clk2 are not
the same clk nets and therefore reg2 takes the value of reg1 at what
looks to be the some rising edge. I can understand the result of the
simulation if it is correct that clk2 should be delayed by one delta
cycle. But in my mind clk1 and clk2 are the same net and the
simulation does not match the expected result of the circuit
described.

So, does the simulator interpret the VHDL code correctly and is this
is a case where a functional simulation will always give a mismatch
with hardware?

architecture rtl of test is
signal clk1 : std_logic := '0';
signal clk2 : std_logic := '0';

signal reg1 : std_logic := '0';
signal reg2 : std_logic;

begin

clk1 <= not clk1 after 10 ns;

clk2 <= clk1;

pSync1 : process (clk1) is
begin
if rising_edge(clk1) then
reg1 <= not reg1;
end if;
end process pSync1;

pSync2 : process (clk2) is
begin
if rising_edge(clk2) then
reg2 <= reg1;
end if;
end process pSync2;

end architecture rtl;
 
On Tue, 9 Dec 2008 00:12:36 -0800 (PST), mamu wrote:

when i simulate the following code I see that clk1 and clk2 are not
the same clk nets and therefore reg2 takes the value of reg1 at what
looks to be the some rising edge. I can understand the result of the
simulation if it is correct that clk2 should be delayed by one delta
cycle. But in my mind clk1 and clk2 are the same net and the
simulation does not match the expected result of the circuit
described.
No, that's wrong. The circuit that you and the synthesis tool
expect to build does not match the simulation. VHDL's delta
delay semantics are completely clear and well defined.

So, does the simulator interpret the VHDL code correctly
Yes. If it doesn't, there is a bug in the simulator.

and is this
is a case where a functional simulation will always give a mismatch
with hardware?
Probably. As I'm sure you can see, your reg1 FF model has a
clock-to-output delay of one delta cycle. Signal clk2 is delayed
from clk1 by one delta cycle too. So your FF model for reg2 sees
the updated value of reg1, not the "pre-clock" value that you
desire.

Real hardware of course has non-zero clock-to-output delays,
and these delays are (we hope) longer than the delays in your
clock distribution network. For this reason, some engineers
add time delays to their register updates:

if rising_edge(clk1) then
reg1 <= not reg1 after 1 ns;
end if;

The real FF's clock-to-output delay is now modelled
(albeit with a fixed and not very realistic Tco) and
your ciruit should now simulate as you expect.

I don't like doing that, because it is so easy to
forget the "after" on a few assignments, thereby introducing
subtle wrong behaviour. It may be preferable to introduce
delays in the interconnect:

reg1_delayed <= reg1 after 1 ns;
pSync2: process (clk2)
begin
if rising_edge(clk2) then
reg2 <= reg1_delayed;
...
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Dec 9, 12:12 am, mamu <magnem...@yahoo.no> wrote:
Hi,

when i simulate the following code I see that clk1 and clk2 are not
the same clk nets and therefore reg2 takes the value of reg1 at what
looks to be the some rising edge. I can understand the result of the
simulation if it is correct that clk2 should be delayed by one delta
cycle. But in my mind clk1 and clk2 are the same net and the
simulation does not match the expected result of the circuit
described.

I believe this (untested) code will eliminate the delta cycle delay
between clk1 and clk2, if that is your goal.

process
variable clk0 : std_logic := '0';
begin
clk1 <= clk0;
clk2 <= clk0;
wait for 10 ns;
clk0 := not clk0;
end process;

Barry
 
On Dec 9, 12:58 pm, Barry <barry...@gmail.com> wrote:
On Dec 9, 12:12 am, mamu <magnem...@yahoo.no> wrote:

Hi,

when i simulate the following code I see that clk1 and clk2 are not
the same clk nets and therefore reg2 takes the value of reg1 at what
looks to be the some rising edge. I can understand the result of the
simulation if it is correct that clk2 should be delayed by one delta
cycle. But in my mind clk1 and clk2 are the same net and the
simulation does not match the expected result of the circuit
described.

I believe this (untested) code will eliminate the delta cycle delay
between clk1 and clk2, if that is your goal.

process
  variable clk0 : std_logic := '0';
begin
  clk1 <= clk0;
  clk2 <= clk0;
  wait for 10 ns;
  clk0 := not clk0;
end process;

Barry
That's usually what I try to do, insert delta delays in a copy of the
original clock to match up with the delayed clock. The beauty of this
is that you only have to do it once. Otherwise, you'd have to put
delays on every signal from the early clock domain to the late clock
domain.

I've even on occasion flipped edges of the clock just to make this
work, especially if I don't have access to the original clock before
it is used in other sections I don't have access to, but need their
outputs lined up with my (delayed) clock.

Andy
 
Thank you for your answers and comments.

I ran into this problem when I was using block diagram based design
tool. The name of the clock input pin was 'IP_CLK' while I prefer
simply 'clk', so I renamed the clock net and saw strange behavior in
the simulation. Now I understand why and I will hopefully not make the
same mistake again.

I was thinking that there should be some way (with VHDL) to simply
connect nets to each other without delay, but that would be
inconsistent with regards to how VHDL handles signal assignments.
Besides, I could simply use an alias and my problem would be solved.
(It is not so easy to do it with the tool I am using though).

I am not sure I like the idea of having clocks that are delayed by
delta cycles. It can cause a lot of confusion (as it did to me). But I
see that there might be cases where it is the only solution. E.g. if
you have to interface with some component (functional model) that
forwards a clock that is already delayed by a delta cycle so that its
outputs updates at the same time as the clock.

Magne
 
On Dec 11, 5:21 am, mamu <magnem...@yahoo.no> wrote:
Thank you for your answers and comments.

I ran into this problem when I was using block diagram based design
tool. The name of the clock input pin was 'IP_CLK' while I prefer
simply 'clk', so I renamed the clock net and saw strange behavior in
the simulation. Now I understand why and I will hopefully not make the
same mistake again.

I was thinking that there should be some way (with VHDL) to simply
connect nets to each other without delay, but that would be
inconsistent with regards to how VHDL handles signal assignments.
Besides, I could simply use an alias and my problem would be solved.
(It is not so easy to do it with the tool I am using though).

I am not sure I like the idea of having clocks that are delayed by
delta cycles. It can cause a lot of confusion (as it did to me). But I
see that there might be cases where it is the only solution. E.g. if
you have to interface with some component (functional model) that
forwards a clock that is already delayed by a delta cycle so that its
outputs updates at the same time as the clock.

Magne
To simply re-name an input port signal, you can use

alias clk : std_logic is IP_CLK;

in the declarations section of the architecture.

No assignment, and hence no delta delay.

Barry
 

Welcome to EDABoard.com

Sponsor

Back
Top