VHDLの遅延要素。 別の外観

良い一日

VHDLの遅延要素 」というトピックへの回答は、FPGAでの信号遅延の可能な実装のアイデアを提供するために準備されました。



非同期リセット回路は、同期回路より悪くありません。 ただし、入力に到達する信号間の遅延と、FPGAでの実装の計算された遅延についての確かな知識がある場合のみです。 しかし、ここではFPGAの主な利点が失われます-回路に新しい機能を追加したり、入出力信号の使用済みの接点を変更したりする機能です。新しい実装ごとに、新しい遅延時間を考慮に入れる必要があります。



「VHDLの遅延要素」というトピックのスキームの場合、遅延はほとんど特別な場合にのみ必要です。reftimeフロントは基準周波数のフロントの直後になります。 そして、なぜこの派手なロジックですか?



わずかな遅延が必要な場合、基準周波数からの同期で複数のDフリップフロップを配置する方がはるかに簡単です。 この場合、遅延はclk20Mhz基準周波数周期の倍数になります。 以下の例では、各エッジにリセット信号がない場合、信号Bは信号Aを繰り返し、信号Cは信号Bを繰り返します。信号AとCの間の遅延は、基準周波数の2周期になります。 新しいDトリガーを追加して、目的の遅延を実現します。



  1. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  2. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  3. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  4. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  5. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  6. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  7. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  8. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  9. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;



  10. process (clk20Mhz,reset,A) -- begin if reset = '1' then B <= '0'; C <= '0'; elsif (clk20Mhz'event and clk20Mhz = '1') then B <= A; C <= B; end if; end process;







基準周波数よりも短い遅延を取得する場合(つまり、より高い周波数でトリガーをクロックする場合)は、 デジタルクロックマネージャーを使用する必要があります。 ブロックの入力で、基準周波数と新しい周波数のパラメーターを入力します(2倍の周波数の出力が用意されていますが、整数係数の比率を掛けた周波数を出力できます。周波数分割も可能です)。 取得した周波数を使用して、トリガーを使用してプロセスをクロックし、水晶発振器からFPGAに含まれる基準周波数期間よりも短い遅延を取得します。



信号エッジ条件(clk20Mhz'eventおよびclk20Mhz = '1')、信号変化条件(clk20Mhz'event)を使用する代わりに、DCMを使用せずに2倍の周波数を簡単に取得することができます。つまり、基準周波数の各エッジまたは立ち下がりで高レベルは低レベル期間と同等でした。



3番目のケースは、基準周波数周期よりもはるかに長い時間遅延を取得する必要がある場合です。 DCM全体で「遅い」周波数を作成するのは賢明ではありません。 カウンターを作成する方がはるかに有益です。 各エッジにリセット信号がない場合、カウントされたティックの値を格納する論理ベクトルは、10進数255に等しい定数x“ FF”に到達する条件が満たされ、信号Aの値が反対に変わるまで増加します。 これは、254の係数で信号周波数Aに信号を送る単純な基準分周器です。コメントのOcelotのおかげで、これはカウンターの単純な基準分周器です。それぞれ、新しい周波数の周期の最大256マークまでカウントします。 結果の周波数は、基準の512倍になります。 FPGAの多数のビットからの論理ベクトルの使用を禁止する人はいませんが、ここでは配線の複雑さが増します。 カウンターのカスケードをより適切に使用します。



  1. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  2. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  3. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  4. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  5. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  6. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  7. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  8. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  9. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  10. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  11. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  12. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  13. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  14. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  15. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





  16. process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;





process (clk,reset) begin if reset = '1' then A <= '0'; count <= (others=>'0'); -- count else if rising_edge(clk) then if count=x"FF" then count <= (others=>'0'); A <= not A; else count <= count + 1; end if; end if; end if; end process;









結論として、FPGAに実装された同期回路では、遅延は常に周波数周期の倍数になります。 同期入力信号の場合、FPGAのトリガーステージ間の信号の伝播時間以下の精度で遅延を取得することができます。 非同期入力信号の場合、基準周波数の周期の少なくとも倍数の遅延を取得することが可能です。 このため、遅延時間間隔を狭めるために周波数乗算が行われます。



そして、 自己同期回路を詳しく見る価値があります-FPGAはその背後にあります。



ありがとう



All Articles