![]() |
|
|
|||||||
![]() |
VHDL - Problems with synchronization - 2 |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
>ALuPin wrote:
> Is the change from s_wait to s_state1 performed > without any problems ? IMO SETUP and HOLD violations can erase > which under circumstances can lead to an unscheduled change. >Mr Hulshoff wrote: >No, it is not performed without problems. The signal l_enable_generate_ack >needs to be synchronized to the 30 MHz domain before using it. Otherwise >you can get very unexpected behaviour in your eventual chip. >ALuPin wrote > What possiblities do I have to avoid that ? > Any synchronization method should consume little amount of time. >Mr Hulshoff wrote >Clock the signal twice on the 30 MHz signal, and use that signal instead. >You can also opt for clocking three times, and use the 2nd and 3rd FF to do >edge detection. Hi Mr Hulshoff, thank you for your answer. What do you mean by edge detection ? Do mean that I could sample the Clk_30 with Clk_90 to find out the falling edge time area of Clk_30? process(Clk_90) begin if rising_edge(Clk_90) then l_sample1 <= Clk_30; l_sample2 <= l_sample1; l_sample3 <= l_sample2; end if; end process; process(l_sample2, l_sample3) begin l_center30 <= '0'; if ((l_sample2='0') and (l_sample3='1')) then l_center30 <= '1'; end if; -- l_center30 could be used to assign a flag in the 90MHz domain. -- This flag can then be used in the 30MHz domain ? end process; Rgds André ALuPin |
|
|
|
|
#2 |
|
Posts: n/a
|
Heres what you wrote with my comments:
-- Generate_ack is synchronous to Clk_90 process(Reset, Clk_90) begin if Reset='1' then l_enable_generate_ack <= '0'; elsif rising_edge(Clk_90) then --this assignment is implied in a clocked process l_enable_generate_ack <= l_enable_generate_ack; if Generate_ack='1' then l_enable_generate_ack <= '1'; end if; if l_eop_sync='1' then l_enable_generate_ack <= '0'; end if; end if; end process; process(Reset, Clk_30) begin if Reset='1' then l_state <= s_wait; l_eop <= '0'; elsif rising_edge(Clk_30) then --these assignments are implied in a clocked process l_state <= l_state; l_eop <= '0'; case l_state is when s_wait => --you cannot use the Clk_90 signal l_enable_generate_ack --directly due to metastability issues if l_enable_generate_ack='1' then l_state <= s_state1; end if; when s_state1 => if other_condition_30MHz_domain='1' then l_state <= s_state2; end if; when s_state2 => l_state <= s_state3; l_eop <= '1'; when s_state3 => l_state <= s_state4; when s_state4 => l_state <= s_state5; when s_state5 => l_state <= s_wait; end if; end process; So the major issue is with the l_enable_generate_ack signal. Since this signal is clocked by Clk_90, it may change at or near a Clk_30 rising edge. When this happens, a setup or hold violation occurs and the state variable l_state may become corrupted. For instance, if the state variable is 2-bits, one bit may change since its circuit sees l_enable_generate_ack as a '1' while the other bit remains unchanged since its circuit sees l_enable_generate_ack as a '0'. There is a ton of literature on the web addressing this issue. You need to synchronize the signal to Clk30 prior to use. This is typically done using two flops as follows: process(Reset, Clk_30) begin if Reset='1' then l_enable_generate_ack_meta <= '0'; l_enable_generate_ack_clk30 <= '0'; elsif rising_edge(Clk_30) then l_enable_generate_ack_meta <= l_enable_generate_ack; l_enable_generate_ack_clk30 <= l_enable_generate_ack_meta; end if; end process; l_enable_generate_ack_meta is an unstable signal and should only be used to generate l_enable_generate_ack_clk30. l_enable_generate_ack_clk30 is the synchronized version of l_enable_generate_ack. Now all you have to do is change your state machine to account for the 2 cycle shift of the l_enable_generate_ack signal. Good luck... Roger |
|
|
|
#3 |
|
Posts: n/a
|
ALuPin wrote:
> What do you mean by edge detection ? Do mean that I could sample the > Clk_30 with Clk_90 to find out the falling edge time area of Clk_30? No, I meant you could use the falling or rising edge of the synchronized version of l_enable_generate_ack. Similar to what Roger wrote in his example: PROCESS BEGIN WAIT UNTIL clk_30 = '1'; -- synchronize l_enable_generate_ack to 30 MHz clock area l_enable_generate_ack_metaÂ*Â* <=Â*l_enable_generate_ack; l_enable_generate_ack_clk30 <= l_enable_generate_ack_meta; l_enable_generate_ack_clk30_d <= l_enable_generate_ack_clk30; -- Use only the double clocked signal IF l_enable_generate_ack_clk30 = '1 THEN -- etc. END IF; -- Use positive edge IF l_enable_generate_ack_clk30 = '1' AND l_enable_generate_ack_clk30_d = '0' THEN -- etc. END IF; -- Use negative edge IF l_enable_generate_ack_clk30 = '0' AND l_enable_generate_ack_clk30_d = '1' THEN -- etc. END IF; -- synchronous resets of your signals IF reset = '1' THEN l_enable_generate_ack_metaÂ*Â* <=Â*'0'; l_enable_generate_ack_clk30 <= '0'; l_enable_generate_ack_clk30_d <= '0'; END IF; END PROCESS; Regards, Pieter Hulshoff Pieter Hulshoff |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Re: Pioneer DVR-105 and Nero Problems | grams@oldtown.com | DVD Video | 1 | 08-12-2003 04:17 AM |
| Re: Pioneer DVR-105 and Nero Problems | Ron | DVD Video | 1 | 08-08-2003 06:33 PM |
| Re: Pioneer DVR-105 and Nero Problems | Flossie | DVD Video | 0 | 08-07-2003 02:25 PM |
| Re: Pioneer DVR-105 and Nero Problems | Flossie | DVD Video | 0 | 08-07-2003 08:11 AM |
| Re: Pioneer DVR-105 and Nero Problems | CAM | DVD Video | 0 | 08-07-2003 02:30 AM |