![]() |
|
|
|||||||
![]() |
VHDL - synchronization of state machine between clocks |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi,
There are two clocks in my design. On the main clock, a state machine runs. It is encoded as a type (leaving the decision on the exact encoding to the synthesizer). I want to set a signal on "enable" when the machine is in a certain state, so I do: if reset ... elsif rising_edge(clk1) then if machine_state = active then my_enable <= '1'; else my_enable <= '0'; end if; end if; This works fine, of course. But suppose I have another enable signal, which should depend on the same event but works with a different clock. How do I synchronize the state of the machine between the two clocks ? At the moment I do a process: if reset ... elsif rising_edge(clk2) then my_enable_sync <= my_enable; my_enable2 <= my_enable_sync; end if; This works, because I know that the "Active" state is very long and I'm not sensitive to exact timing. This double FF ensures no metastability and correct syncing of my_enable to the clk2 domain. Questions: 1) Is this a valid way to accomplish my goal ? 2) What is a faster / tighter way to do this synchronization, if I care about every clock cycle ? 10x R richard.melikson@gmail.com |
|
|
|
|
#2 |
|
Posts: n/a
|
On Nov 25, 6:09 am, richard.melik...@gmail.com wrote:
> 1) Is this a valid way to accomplish my goal ? > 2) What is a faster / tighter way to do this synchronization, if I > care about every clock cycle ? > > 10x > R It's very common. This makes it mostly valid on metastability, it's all probabilities. One flop gets you the biggest bang for th buck. I tend to be paranoid and flop more than once, but this costs you delay. It also depends on the relative clock rates. One gotcha is that if you assume that the pulse in the sending domain is a certain number of clocks wide, it may not be so on the other side. In particular, single pulse "events" may get deleted or stretched. Also, make sure you use the flopped output in *exactly* one place, and make sure you decorate it with do-not-replicate and do-not-retime attributes. Otherwise the synthesizer may introduce all kinds of problems when signals reconverge after undergoing a statistically distributed and unequal number of clock delays at each crossing. Another fairly common approach is to build a hand-shake (an SR-flop idea), possibly with intervening metastability flops, which guarantees to hold the signal until seen properly at the other side. You can couple this with edge-detctors to get single clock wide pulse ouputs. This lets you cross from slow to fast clocks safely but again, can cost delays. If you need absolute speed (like in a CPU pipeline), and are willing to do some serious work to achieve it, look at some of the neat ideas in the paper "Efficient Self-Timed Interfaces for Crossing Clock Domains" by Chakraborty and Greenstreet: http://www.cs.utah.edu/classes/cs694.../async2003.pdf These techniques may be easier to implement in ASIC than FPGA, though. I'm sure there are a thousand other neat ideas out there, too. Best regards, - Kenn kennheinrich@sympatico.ca |
|
|
|
#3 |
|
Posts: n/a
|
schrieb:
> if reset > ... > elsif rising_edge(clk2) then > my_enable_sync <= my_enable; > my_enable2 <= my_enable_sync; > end if; > > This works, because I know that the "Active" state is very long and > I'm not sensitive to exact timing. This double FF ensures no > metastability and correct syncing of my_enable to the clk2 domain. > > Questions: > > 1) Is this a valid way to accomplish my goal ? > 2) What is a faster / tighter way to do this synchronization, if I > care about every clock cycle ? Synchronisation of asynchronous processes can be done by detecting a one bit signal change. With this method you can avoid in many situations that the duration of the synchronisation signal could become too short. I would never use a pulse to synchronise between two clock domains. -- trigger process 2 from process 1, clock domain #1: if have_to_trigger_proc2 then trigger_proc2 <= not trigger_proc2; end if; -- detect trigger from process 1 in process 2, clock domain #2: trigger_proc2_sync <= trigger_proc2; -- synchronise signal from proc1 trigger_proc2_sync_old <= trigger_proc2_sync; if trigger_proc2_sync /= trigger_proc2_sync_old then ... end if; You have to care about that the trigger signals in both processes have the same reset value. Best regards Wolfgang Grafen Wolfgang Grafen |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| combinational lock state machine | harikanth | General Help Related Topics | 0 | 04-06-2009 05:38 AM |
| Using BRAM in state machines | zoki111 | Hardware | 0 | 09-18-2007 09:38 AM |
| Judge: File-swapping tools are legal | Citizen Bob | DVD Video | 140 | 11-08-2006 06:42 PM |
| BUSH WILL LIKELY INSTALL A DRAFT | Jas | DVD Video | 165 | 10-20-2004 09:39 PM |
| Re: Can't login to XP Pro machine | Gary | A+ Certification | 3 | 09-22-2004 10:17 PM |