(私はこれを EE に投稿したいと思いますが、VHDL に関する質問がはるかに多いようです...)
背景: Xilinx ISE 14.4 (webpack) で Xilinx Spartan-6LX9 FPGA を使用しています。
今日、恐ろしい「PhysDesignRules:372 - Gated clock」という警告に出くわしました。一般的に、それに関して多くの議論が行われているようです。コンセンサスは、FPGA 上の DCM の 1 つを使用してクロック分周を行うことのようですが...私の DCM は 32 MHz から 4.096 KHz に移行できないようです (ウィザードによると、 32MHz...そして、この低周波数の目的で複数の DCM をチェーンしようとするのはばかげているようです)。
私の現在の設計では、clk_in を使用して指定された値 (15265) までカウントアップし、その値をゼロにリセットして clk_out ビットをトグルします (したがって、50% のデューティ サイクル (FWIW) になります)。それは仕事をし、clk_out の立ち上がりエッジを簡単に使用して、デザインの次の段階を駆動できます。うまく動作しているように見えますが...ゲート付きクロックです(クロックスキューが非常に関連する範囲ではありませんが)。(注: すべてのクロック テストは、指定されたクロックに敏感なプロセスで、rising_edge() 関数を使用して実行されます。)
だから、私の質問:
はるかに高速な clk_in から比較的低速な clk_out を導出することについて話している場合、ゲーティングは依然として悪いと見なされますか? または、この種の「x までカウントしてパルスを送信する」ことは、FPGAが KHz 範囲で「クロック」を生成するのに非常に一般的であり、代わりに他の不要な副作用がこの警告をトリガーしている可能性がありますか?
ここで複数の DCM を使用するのはやり過ぎのように見えることを念頭に置いて、MHz 範囲のマスター クロックから低 KHz 範囲のクロックを作成するより良い方法はありますか (出力周波数が非常に低い場合に可能であれば)。50% のデューティ サイクルは不必要かもしれませんが、オンボード DCM を使用せずにクロックを 1 つ入力すると仮定すると、FPGA で主要なクロック分周を実行するにはどうすればよいでしょうか?
編集:次の場合(CLK_MASTERは32 MHzの入力クロックで、CLK_SLOWは目的の低速クロックであり、LOCAL_CLK_SLOWはデューティサイクル全体のクロックの状態を保存する方法でした)、この構成を学びました警告を引き起こします:
architecture arch of clock is
constant CLK_MASTER_FREQ: natural := 32000000; -- time := 31.25 ns
constant CLK_SLOW_FREQ: natural := 2048;
constant MAX_COUNT: natural := CLK_MASTER_FREQ/CLK_SLOW_FREQ;
shared variable counter: natural := 0;
signal LOCAL_CLK_SLOW: STD_LOGIC := '0';
begin
clock_proc: process(CLK_MASTER)
begin
if rising_edge(CLK_MASTER) then
counter := counter + 1;
if (counter >= MAX_COUNT) then
counter := 0;
LOCAL_CLK_SLOW <= not LOCAL_CLK_SLOW;
CLK_SLOW <= LOCAL_CLK_SLOW;
end if;
end if;
end process;
end arch;
この構成では警告は発生しません。
architecture arch of clock is
constant CLK_MASTER_FREQ: natural := 32000000; -- time := 31.25 ns
constant CLK_SLOW_FREQ: natural := 2048;
constant MAX_COUNT: natural := CLK_MASTER_FREQ/CLK_SLOW_FREQ;
shared variable counter: natural := 0;
begin
clock_proc: process(CLK_MASTER)
begin
if rising_edge(CLK_MASTER) then
counter := counter + 1;
if (counter >= MAX_COUNT) then
counter := 0;
CLK_SLOW <= '1';
else
CLK_SLOW <= '0';
end if;
end if;
end process;
end arch;
したがって、この場合、それはすべてelseの欠如によるものでした(私が言ったように、50%のデューティサイクルはもともと興味深いものでしたが、最終的には要件ではありませんでした。「ローカル」クロックビットのトグルは非常に巧妙に見えました時間...) 私はほとんど正しい軌道に乗っていたようです。
この時点ではっきりしないのは、カウンター (多くのビットを格納する) を使用しても警告が発生しない理由ですが、格納されてトグルされた出力ビットでは警告が発生する理由です。考え?