Simulating two clock domains

A

arkaitz

Guest
Hi,

I have some problems when using two clock domains in my design.

My main clock works at a frequency of 60 Mhz. The clock port is routed
to the input port of the internal DLL which provides two clock
sources, one of the same frequency (60 Mhz) and the other of 20Mhz.

There is a rising edge detector FF excited with 20 Mhz clock

re_detect:
block is
signal aux : std_logic;
begin
process( rst, clk_20 )
begin
if ( rst = '1' ) then
aux <= '0';
elsif ( clk_20 = '1' and clk_20'event ) then
aux <= input;
end if;
end process;

re_edge <= not(aux) and input;

Note: the input is synchronized to avoid glitches and metastability.

Then I have another FF whose set and reset are separate conditions
that is
excited with 60 Mhz clock.

process ( rst, clk_60 )
begin
if ( rst = '1' ) then
out <= '0';
elsif ( clk_60'event and clk = '1' ) then
if ( input = '1' ) then
out <= '1';
end if;
if ( re_edge = '1' ) then
out <= '0';
end if;
end if;
end process;

I have simulated functionally the design with Modelsim 5.6f and I see
that "out" signal doesn´t become low when "re_edge" is active. Note
that the if clauses are writen in such way so that the reset condition
has the biggest priority.

This might be because the "re_edge" signal is a 0 ps wide pulse, I
mean is asserted and dessaserted in the same simulation step and in
the same time with the rising edge of the clock signal.

I don't know certainly why, but I believe that it can be because I use
the DLL. I have created the same design using a clock divider instead
of a DLL and it works but there are several differences in the
functional simulation:

- "re_edge" signal is a clk_20 period wide signal instead of a glitch
- "aux" signal is asserted 1 clk_20 period later than the "input"
signal

Anybody any suggestion?

Thanks in advance,

Arkaitz
-------------------------------
Ikerlan
Electronics Area
Pş J. M. Arizmendiarrieta, 2
20500 Arrasate (Gipuzkoa)
-------------------------------
 
"arkaitz" <arkagaz@yahoo.com> escribió en el mensaje
news:c1408b8c.0404260712.444a63e6@posting.google.com...
Hi,

I have some problems when using two clock domains in my design.
hadnt you posted this problem before?

My main clock works at a frequency of 60 Mhz. The clock port is routed
to the input port of the internal DLL which provides two clock
sources, one of the same frequency (60 Mhz) and the other of 20Mhz.

There is a rising edge detector FF excited with 20 Mhz clock

re_detect:
block is
signal aux : std_logic;
begin
process( rst, clk_20 )
begin
if ( rst = '1' ) then
aux <= '0';
elsif ( clk_20 = '1' and clk_20'event ) then
aux <= input;
end if;
end process;

re_edge <= not(aux) and input;

Note: the input is synchronized to avoid glitches and metastability.
what do you mean by "synchronized"? to what? besides "input" should be
stable before (and after) the clock edge, they shouldnt change at the same
time (if that's what you meant with "synchronised")
and i would have thought that a glitch is what you're getting with those "0
ps" pulses

Then I have another FF whose set and reset are separate conditions
that is
excited with 60 Mhz clock.

process ( rst, clk_60 )
begin
if ( rst = '1' ) then
out <= '0';
elsif ( clk_60'event and clk = '1' ) then
if ( input = '1' ) then
out <= '1';
end if;
if ( re_edge = '1' ) then
out <= '0';
end if;
end if;
end process;

I have simulated functionally the design with Modelsim 5.6f and I see
that "out" signal doesn´t become low when "re_edge" is active. Note
that the if clauses are writen in such way so that the reset condition
has the biggest priority.
you could write it otherwise, like

elsif ( clk_60'event and clk = '1' ) then
if ( re_edge = '1') then
out <= '0';
elsif ( input = '1' ) then
out <= '1';
end if;
end if;


This might be because the "re_edge" signal is a 0 ps wide pulse, I
mean is asserted and dessaserted in the same simulation step and in
the same time with the rising edge of the clock signal.
dont you think you should correct that? do you think that's a good sign?
besides that's completely normal from your "re_edge <= not aux and input"
even on real logic that pulse wouldnt be large, how large do you want it to
be? and even then it should arrive a bit later than the clk60 edge, so you'd
probably miss it anyway



I don't know certainly why, but I believe that it can be because I use
the DLL.
what, the 0 ps pulse is due to the DLL? or "out" not going low?


I have created the same design using a clock divider instead
of a DLL and it works but there are several differences in the
functional simulation:

- "re_edge" signal is a clk_20 period wide signal instead of a glitch
- "aux" signal is asserted 1 clk_20 period later than the "input"
signal
and what do you want?

Anybody any suggestion?
why are you synchronizing the reset of the second FF with a clock that's
running slower than this FF clock?

if what you want is to reset your second FF on a rising_edge of input, then
i wouldnt do its reset "synchronous"

why dont you use a "digital oneshot" clocked by the fastest clock (so that
your output stays low or high just for one cycle), that could be a FSM that
would wait for a high (that'd be the rising_edge of input) value of input,
and then wait for it to become low to start waiting again.

anyway, i know shit, what is what you're trying to do anyway?

Thanks in advance,
dont worry, i dont think i know better than you :)

Arkaitz
-------------------------------
Ikerlan
Electronics Area
Pş J. M. Arizmendiarrieta, 2
20500 Arrasate (Gipuzkoa)
-------------------------------
 
Hi Paris,

First of all, thanks for answering to my message.
I'll try to answer to all of your questions.

hadnt you posted this problem before?
Yes and no. The post I wrote before had to do a lot with this one but
now I think that the problem comes from another source.


what do you mean by "synchronized"? to what? besides "input" should be
stable before (and after) the clock edge, they shouldnt change at the same
time (if that's what you meant with "synchronised")
and i would have thought that a glitch is what you're getting with those "0
ps" pulses
The "input" signal is an asynchronous input port and it must be
synched before I use in my design, just to avoid metastability and
glitches. Even if its asynchronous it's active during several clock
hundreds of clock cycles. Here you are the synch:

entity top
port (
...
in : in std_logic;
...
);
end top;

architecture arch of top is
...
signal input : std_logic;
signal i_filter : std_logic_vector(1 downto 0);
...
begin
process ( rst, clk )
begin
if ( rst = '1' ) then
i_filter <= (others => '0');
elsif ( clk'event and clk = '1' ) then
i_filter(0) <= in;
i_filter(1) <= i_filter(0);
end if;
end process;

input <= i_filter(1);

you could write it otherwise, like

elsif ( clk_60'event and clk = '1' ) then
if ( re_edge = '1') then
out <= '0';
elsif ( input = '1' ) then
out <= '1';
end if;
end if;
yes, that's true, but the result would be the same.


dont you think you should correct that? do you think that's a good sign?
besides that's completely normal from your "re_edge <= not aux and input"
even on real logic that pulse wouldnt be large, how large do you want it to
be? and even then it should arrive a bit later than the clk60 edge, so you'd
probably miss it anyway
just a clock period wide to allow to use it as a clock enable signal.
I have done used this code several time and it has always worked.

I don't know certainly why, but I believe that it can be because I use
the DLL.

what, the 0 ps pulse is due to the DLL? or "out" not going low?
both, because one comes from the other, I mean, the "out" doesn't go
low because the rising edge signal is not detected correctly.

and what do you want?
just to know if somebody has ever got any trouble using two different
clock domains and when both clocks are provided by the DLL.

My reflexion: it might work in physically but I would like ensure with
functional simulation before implementing the design.

why are you synchronizing the reset of the second FF with a clock that's
running slower than this FF clock?
Because that's requirement of my design. I know that I could do with
some clock enables but the DLL might be necessary in order to improve
the required max. frequency.

if what you want is to reset your second FF on a rising_edge of input, then
i wouldnt do its reset "synchronous"
do you mean using asynchronous signals in a syncronous design? I don't
think that'd be a great idea.

why dont you use a "digital oneshot" clocked by the fastest clock (so that
your output stays low or high just for one cycle), that could be a FSM that
would wait for a high (that'd be the rising_edge of input) value of input,
and then wait for it to become low to start waiting again.
That's another posibility but it might use more resources than what
I've done.


Thanks a lot for your patience,

Arkaitz
-------------------------------
Ikerlan
Electronics Area
Pş J. M. Arizmendiarrieta, 2
20500 Arrasate (Gipuzkoa)
-------------------------------
 
You want out to be low for 3 clk_60 cycles (1 clk_20) when input rise.

To avoid problem of passing from one clk domain to the other (because both
clks must be balanced at both aux and out registers), you can do this if
input high time and low time are both at least 3 clk_60 cycles width all the
time and it's synchronous with clk_60.

signal aux : std_logic_vector(2 downto 0);

process( rst, clk_60 )
begin
if ( rst = '1' ) then
aux <= (others => '0');
elsif ( clk_60 = '1' and clk_60'event ) then
aux <= aux(1 downto 0) & input;
end if;
end process;

re_edge <= not(aux(2)) and input; -- 3 clk cycles pulse width

If you use Xilinx, the shift register is free but I don't know if you can
reset it.

regards
fe
 
"arkaitz" <arkagaz@yahoo.com> escribió en el mensaje
news:c1408b8c.0404270111.5597b66a@posting.google.com...
Hi Paris,

First of all, thanks for answering to my message.
I'll try to answer to all of your questions.

hadnt you posted this problem before?

Yes and no. The post I wrote before had to do a lot with this one but
now I think that the problem comes from another source.


what do you mean by "synchronized"? to what? besides "input" should be
stable before (and after) the clock edge, they shouldnt change at the
same
time (if that's what you meant with "synchronised")
and i would have thought that a glitch is what you're getting with those
"0
ps" pulses

The "input" signal is an asynchronous input port and it must be
synched before I use in my design, just to avoid metastability and
glitches. Even if its asynchronous it's active during several clock
hundreds of clock cycles. Here you are the synch:
if you want to sync to avoid metastability, maybe you could check out

http://www.fpga-faq.com/FAQ_Pages/0017_Tell_me_about_metastables.htm




entity top
port (
...
in : in std_logic;
...
);
end top;

architecture arch of top is
...
signal input : std_logic;
signal i_filter : std_logic_vector(1 downto 0);
...
begin
process ( rst, clk )
begin
if ( rst = '1' ) then
i_filter <= (others => '0');
elsif ( clk'event and clk = '1' ) then
i_filter(0) <= in;
i_filter(1) <= i_filter(0);
end if;
end process;

input <= i_filter(1);

you could write it otherwise, like

elsif ( clk_60'event and clk = '1' ) then
if ( re_edge = '1') then
out <= '0';
elsif ( input = '1' ) then
out <= '1';
end if;
end if;

yes, that's true, but the result would be the same.
no it wouldnt, cause in your design, there's a problem is "re_edge" and
"input" are both high
this one only if re_edge is not high, the second statement (the elsif) would
be executed, in your code, both if's will always execute

dont you think you should correct that? do you think that's a good sign?
besides that's completely normal from your "re_edge <= not aux and
input"
even on real logic that pulse wouldnt be large, how large do you want it
to
be? and even then it should arrive a bit later than the clk60 edge, so
you'd
probably miss it anyway

just a clock period wide to allow to use it as a clock enable signal.
I have done used this code several time and it has always worked.
you've used this same code before and it worked and now it's not working?

I don't know certainly why, but I believe that it can be because I use
the DLL.

what, the 0 ps pulse is due to the DLL? or "out" not going low?

both, because one comes from the other, I mean, the "out" doesn't go
low because the rising edge signal is not detected correctly.

and what do you want?

just to know if somebody has ever got any trouble using two different
clock domains and when both clocks are provided by the DLL.

My reflexion: it might work in physically but I would like ensure with
functional simulation before implementing the design.
then you should get rid of the 0ps glitch caused by "re_edge <= not aux and
input;"

why are you synchronizing the reset of the second FF with a clock that's
running slower than this FF clock?

Because that's requirement of my design. I know that I could do with
some clock enables but the DLL might be necessary in order to improve
the required max. frequency.

if what you want is to reset your second FF on a rising_edge of input,
then
i wouldnt do its reset "synchronous"

do you mean using asynchronous signals in a syncronous design? I don't
think that'd be a great idea.
but i thought that's what you were doing, aint you trying to avoid the
metastability caused by an async signal entering your synchronous system?
anyway, the link might help you, as it contains code similar to yours (i
think)

why dont you use a "digital oneshot" clocked by the fastest clock (so
that
your output stays low or high just for one cycle), that could be a FSM
that
would wait for a high (that'd be the rising_edge of input) value of
input,
and then wait for it to become low to start waiting again.

That's another posibility but it might use more resources than what
I've done.


Thanks a lot for your patience,

Arkaitz
-------------------------------
Ikerlan
Electronics Area
Pş J. M. Arizmendiarrieta, 2
20500 Arrasate (Gipuzkoa)
-------------------------------
 

Welcome to EDABoard.com

Sponsor

Back
Top