Synchronization of signals

A

ALuPin

Guest
Hi everybody,

I have a question concerning the following:


The signal 'valid_48' is one clock_cycle (48MHz) high.
Now I want to use it in a clock domain which has a clock of 90MHz.

How can I synchronize it correctly?

I have thought of the following:


process(Clk_90)
begin
if Reset='1' then
valid_90 <= '0';
valid_h1 <= '0';
valid_h2 <= '0';

elsif rising_edge(Clk_90) then

valid_h1 <= valid_48;
valid_h2 <= valid_h1;
valid_90 <= valid_h1 and (not valid_h2);
end if;
end process;

Are there some problems arising because of the clock-relation factor 48/90 ?

Thank you very much.

Kind regards

Andre
 
ALuPin wrote:
Hi everybody,

I have a question concerning the following:


The signal 'valid_48' is one clock_cycle (48MHz) high.
Now I want to use it in a clock domain which has a clock of 90MHz.

How can I synchronize it correctly?

I have thought of the following:


process(Clk_90)
begin
if Reset='1' then
valid_90 <= '0';
valid_h1 <= '0';
valid_h2 <= '0';

elsif rising_edge(Clk_90) then

valid_h1 <= valid_48;
valid_h2 <= valid_h1;
valid_90 <= valid_h1 and (not valid_h2);
end if;
end process;

Are there some problems arising because of the clock-relation factor 48/90 ?

Thank you very much.

Kind regards

Andre
There is a problem: the logical result of your code appears to be that valid_90 is always '0'. My guess is that you were hoping for timing differences to result in a narrow pulse for valid_90. Since you generally have little or no control over such timing, I recommend you avoid designs which depend upon it.

If this guess is wrong, then you perhaps you meant this:

ENTITY synchronize IS
PORT(
reset, valid_48, clk_90 : IN STD_LOGIC;
valid_90 : OUT STD_LOGIC);
END synchronize;
ARCHITECTURE behavior OF synchronize IS
SIGNAL v_90 : STD_LOGIC;
BEGIN
synchronize_valid_90:
PROCESS (clk_90)
BEGIN
IF reset = '1' THEN
v_90 <= '0';
ELSIF clk_90'EVENT and clk_90 = '1' THEN
IF valid_48 = '1' and v_90 = '0' THEN
v_90 <= '1';
ELSIF valid_48 = '0' and v_90 = '1' THEN
v_90 <= '0';
ELSE
NULL;
END IF;
ELSE
NULL;
END IF;
END PROCESS synchronize_valid_90;
valid_90 <= v_90;
END behavior;

I see nothing significant about the ratio 90/48. These intervals are nominally commensurate so the output waveform repeats periodically and sometimes the output signal is high (or low) for two 90 MHz periods rather than just for one but that seems reasonable in a synchronization circuit.

Charles B. Cameron
 
"Cameron, Charles B. " <cameronc@aplcenmp.apl.jhu.edu> wrote in message
news:4028D4F1.2050300@aplcenmp.apl.jhu.edu...

There is a problem: the logical result of your code appears
to be that valid_90 is always '0'.
No it's not.

He's using the 90MHz clock to register the valid_48 signal
into the 90MHz domain and do a rising edge detect on it.

The only thing I would do is register it in three times and use
valid_h2 and valid_h3 for the rising edge detection to help
avoid metastability problems. If you've data in parallel with
the valid signal you can pipeline it into the 90MHz clock domain
one extra time to compensate.

ENTITY synchronize IS
PORT(
reset, valid_48, clk_90 : IN STD_LOGIC;
valid_90 : OUT STD_LOGIC);
END synchronize;
ARCHITECTURE behavior OF synchronize IS
SIGNAL v_90 : STD_LOGIC;
BEGIN
synchronize_valid_90:
PROCESS (clk_90)
BEGIN
IF reset = '1' THEN
v_90 <= '0';
ELSIF clk_90'EVENT and clk_90 = '1' THEN
IF valid_48 = '1' and v_90 = '0' THEN
v_90 <= '1';
ELSIF valid_48 = '0' and v_90 = '1' THEN
v_90 <= '0';
ELSE
NULL;
END IF;
ELSE
NULL;
END IF;
END PROCESS synchronize_valid_90;
valid_90 <= v_90;
END behavior;

AAAAAAAAAAAAARRRRRRRRRGGGGGGGGGHHHHHHHHH I HATE mixed lower
and upper case coding, it's very hard to read through.


Nial
------------------------------------------------
Nial Stewart Developments Ltd
FPGA and High Speed Digital Design
www.nialstewartdevelopments.co.uk
 
Hi Andre,

The signal 'valid_48' is one clock_cycle (48MHz) high.
Now I want to use it in a clock domain which has a clock of 90MHz.

There are a bunch of good references on synchronizing signals across clock
domain boundaries. Here's one reference I've found handy in the past:

http://www.sunburst-design.com/papers/CummingsSNUG2001SJ_AsyncClk_rev1_1.pdf

Going from low-speed to high-speed clock domains with a single signal is
probably the easiest cross-domain transfer that can happen. From a quick
glance at your solution, it looks okay to me (except that another reader
thinks it is wrong). I don't think you need "valid_90" to be a registered
signal -- it's okay to put it outside the process and leave it as a
combinational function of valid_h1 and valid_h2, unless you are using it
down-stream as an asynchronous signal and thus care about it being
glitch-free.

I *think* you should add a third shift-register stage (call it valid_h0)
before the two you have. The reason is that the 1st register could clock
the data just as the transition in the 48-Mhz domain is occuring. The
result is a metastable flop, which you don't want to use as input to
combinational logic. It may very well work fine as is since even a
metastable flop will settle to a 1 or 0 at some point -- except that this
added delay for settling will not be checked by the timing analyser so you
run the risk of blowing your critical path if it happens to originate on
valid_h1. If valid_h1 only feeds an AND and then into another flop (as in
your currnet solution), the chances of this actually being a problem are
slim. You also run the risk that the valid_h2 sampling of the metastable
signal and the valid_90 samplings see different values since the
logic/routing/etc. could have different trip-points. By putting an extra
stage in the shift register, by the time valid_h1 samples the output of
valid_h0, it's likely that the input has settled enough that valid_h1 will
get a stable result (either '0' or '1' -- it doesn't matter).

So this is what it looks like in the end. Warning: Haven't coded in VHDL
for a year or so, so all of this could be wrong :)

process (clk90, reset)
if reset = '1' then
valid_h0 <= '0';
valid_h1 <= '0';
valid_h2 <= '0';
elsif rising_edge(clk90) then
valid_h0 <= valid_48;
valid_h1 <= valid_h0;
valid_h2 <= valid_h1;
end if;
end process;
valid_90 <= valid_h1 AND NOT valid_h2;

Regards,

Paul Leventis
Altera Corp.
 
If you've data in parallel with
the valid signal you can pipeline it into the 90MHz clock domain
one extra time to compensate.
You can't use this method for more than one signal crossing a clock domain.
There is no guarentee that your control signal (valid_48) and data signals
will arrive at their synchronizers at the exact same moment in time, and
thus you could have some signals sampled before they transition and others
sampled afterwards.

It may seem at first that you could do something like wait until valid_h1 =
'0' and valid_h2 = '1' to sample the data, but I believe that you can also
get wrong data in this case since valid_48 could be held high up to < 1
48-Mhz clock cycle after it was meant to be used, and thus data could have
toggled already by the time you sample it. Not to mention synthesis/p&r
delays from data to 90-Mhz domain will be different.

In this case, you need to start using FIFOs and other techniques I don't
recall anymore. See my other posting for PDF reference.

Paul Leventis
Altera Corp.
 
Hi,

Your suggestion should work. The ratio of clocks will only become a
problem if the asynchronous signal pulsewidth becomes close to or less
than one 90MHz period.
The valid_h1 signal will have a higher probability to enter a
metastable state, which, in theory, could be a problem. You could
place another FF in front of the queue.

Regards,
Niki



ALuPin@web.de (ALuPin) wrote in message news:<b8a9a7b0.0402100103.2134de7a@posting.google.com>...
Hi everybody,

I have a question concerning the following:


The signal 'valid_48' is one clock_cycle (48MHz) high.
Now I want to use it in a clock domain which has a clock of 90MHz.

How can I synchronize it correctly?

I have thought of the following:


process(Clk_90)
begin
if Reset='1' then
valid_90 <= '0';
valid_h1 <= '0';
valid_h2 <= '0';

elsif rising_edge(Clk_90) then

valid_h1 <= valid_48;
valid_h2 <= valid_h1;
valid_90 <= valid_h1 and (not valid_h2);
end if;
end process;

Are there some problems arising because of the clock-relation factor 48/90 ?

Thank you very much.

Kind regards

Andre
 
"Paul Leventis (at home)" <paul.leventis@utoronto.ca> wrote in message
news:Zf6Wb.13961$Ovt.8380@news04.bloor.is.net.cable.rogers.com...
If you've data in parallel with
the valid signal you can pipeline it into the 90MHz clock domain
one extra time to compensate.

You can't use this method for more than one signal crossing a clock
domain.
There is no guarentee that your control signal (valid_48) and data signals
will arrive at their synchronizers at the exact same moment in time, and
thus you could have some signals sampled before they transition and others
sampled afterwards.
This depends on the interface and relationship of the
valid_48 signal to the data.

You can't say "> You can't use this method for more
than one signal crossing a clock domain" without knowing
more about the implementation.


Nial

------------------------------------------------
Nial Stewart Developments Ltd
FPGA and High Speed Digital Design
www.nialstewartdevelopments.co.uk
 
This depends on the interface and relationship of the
valid_48 signal to the data.

You can't say "> You can't use this method for more
than one signal crossing a clock domain" without knowing
more about the implementation.
I don't know what I was thinking. This was an overly strong statement.
Obviously, if the data is guarenteed to be held in a state for the entire
duration of valid being asserted (a common way of communication), then it's
perfectly safe to sample the data.

Ugh. Must wait until all brain cells wake up before posting...

Regards,

Paul Leventis
Altera Corp.
 
You can improve the capture from the 48 MHz domain to 90 MHz domain by using
both edges of the clock to sample the valid signal. As an alternative use an
internal DLL / PLL to multiply the 90 MHz to 180 MHz and use the 180 MHz to
increase sampling resolution. The basics of this method are to have enough
samples of the valid signal to work out when the data would actually be
valid. With this method you going also need a lot of timing or placement
constraints to ensure that nothing changes significantly between builds.
Also be careful that the mark/space ration of the clock is better than
40:60. Always check that you technology can handle the clock rates. 180 MHz
for most recent FPGAs isn't usually too much of an issue. We run some things
at double that clock rate.

If you are using the both edges approach - sample the valid signal using 2
shift registers, one positive edge, one negative edge. By interleaving the
shift registers outputs you can create a signal that you can identify where
a edge occurs. For this to work reliably you need to ensure that skew
between front end registers is very small. If you have the 180 MHz available
make a single double size shift register to get your timing, or edge, timing
point. The 180 MHz shift register is also easier to get right. Given your
relative clock rates you probably need to sample the data on both edges, or
use 180 MHz, and decide afterwards which edge you take the data from.

Sounds complicated but it is mostly basic arithmetic. I will try and
schedule a article to be put on our TechiTips page but it might be 2 or 3
months before it gets there.

John Adair
Enterpoint Ltd.

This message is the personal opinion of the sender and not that necessarily
that of Enterpoint Ltd.. Readers should make their own evaluation of the
facts. No responsibility for error or inaccuracy is accepted.



"ALuPin" <ALuPin@web.de> wrote in message
news:b8a9a7b0.0402100103.2134de7a@posting.google.com...
Hi everybody,

I have a question concerning the following:


The signal 'valid_48' is one clock_cycle (48MHz) high.
Now I want to use it in a clock domain which has a clock of 90MHz.

How can I synchronize it correctly?

I have thought of the following:


process(Clk_90)
begin
if Reset='1' then
valid_90 <= '0';
valid_h1 <= '0';
valid_h2 <= '0';

elsif rising_edge(Clk_90) then

valid_h1 <= valid_48;
valid_h2 <= valid_h1;
valid_90 <= valid_h1 and (not valid_h2);
end if;
end process;

Are there some problems arising because of the clock-relation factor 48/90
?

Thank you very much.

Kind regards

Andre
 
"Paul Leventis (at home)" <paul.leventis@utoronto.ca> wrote in message
news:EC7Wb.15521$Ovt.10005@news04.bloor.is.net.cable.rogers.com...

Ugh. Must wait until all brain cells wake up before posting...

You should like here in the UK, then it would already
be late afternoon and you'd be well awake.

:)


Nial.
 

Welcome to EDABoard.com

Sponsor

Back
Top