1

主な編集:

Will Dean のコメントを読んだ後、問題は解決しました。元の質問は、改訂されたコードの下にあります。

-- REVISED CODE (NOW WORKS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity CLOCK_DIVIDER is
    port(
        reset   :   in std_logic;
        clk :   in std_logic;
        half_clk    :   out std_logic
        );
end CLOCK_DIVIDER;


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;

begin

    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                tick <= '1';
            elsif tick = '1' then
                tick <= '0';
            end if;
        end if;
    end process;

    process(tick)
    begin
        half_clk <= tick;
    end process

end CLOCK_DIVIDER;

修正されたコードの合成ロジック ブロックは、half_clk を出力として取り、反転した half_clk を入力として取る単一の非同期リセット DFF です。これは、half_clk の値が clk の立ち上がりエッジごとに変化することを意味します。

ありがとう、ウィルディーン:)

==== ==== ==== ==== ====

以下の元の質問:

==== ==== ==== ==== ====

シンプルなクロック分周器 (2 で分周するだけ) が必要なので、テンプレートを使用する代わりに、自分で作成してトレーニングを続けることにしました。

残念ながら、合成されたロジック ブロックは機能していないようです。ロジック ブロックとコード (実際に機能するはずだと思います) をこの順序で提示します。

論理ブロック http://img808.imageshack.us/img808/3333/unledly.png

私が本当に疑問に思っているのは、悪魔が「ティック」DFF で何をしているのかということです。明らかに、マルチプレクサ セレクタから入力を取得します。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity CLOCK_DIVIDER is
    port(
        reset   :   in std_logic;
        clk :   in std_logic;
        half_clk    :   out std_logic
        );
end CLOCK_DIVIDER;


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;

begin
    process(clk, reset)
    begin
        if reset = '1' then
            half_clk <= '0';
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                half_clk <= '0';
                tick <= '1';
            elsif tick = '1' then
                half_clk <= '1';
                tick <= '0';
            end if;
        end if;
    end process;
end CLOCK_DIVIDER;

コードのエラーは明らかだと思いますが、それを見つけようとして盲目的に自分自身を見つめてきました。

4

4 に答える 4

3

halfclk を真のクロックではなくイネーブルとして使用する場合は、このアドバイスを無視してください...

これが FPGA ターゲット用であり、"half_clk" が実際にクロックとして使用されている場合 (たとえば、イネーブル ピンではなく DFF のクロック ピンに接続されている場合)...これを実行しないでください

一般的な FPGA ロジック/ファブリックを使用して派生クロックを作成すると、ビルド ツールで問題が発生し、最終的にビルドが失敗する (タイミングが満たされない) か、制約がすべてのクロック ネットワークに正しく渡されないためにビルドが期待どおりに動作しない可能性があります。 .

代わりに、特にこの目的のために FPGA ファブリックに組み込まれているクロック管理ブロックを使用してください。ザイリンクス パーツの世界では、これらはデジタル クロック マネージャー (DCM) または混合モード クロック マネージャー (MMCM) と呼ばれます。同等のアルテラ コンポーネントが何であるかはわかりません。ドキュメントを読んで、アプリケーションの最適な使用法を判断してください。

于 2011-06-07T12:02:03.657 に答える
1

改訂されたコードに基づいて、アーキテクチャに次の変更を加えます。

-- REVISED CODE (NOW WORKS) and simplified and synthesisable
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
    signal tick : std_logic;
begin
    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif rising_edge(clk) then -- use of rising_edge() is the correct idiom these days
            tick <= not tick;
        end if;
    end process;

    half_clk <= tick;
end CLOCK_DIVIDER;

このプロセスを削除し、同時割り当てに置き換えました。

    process(tick)
    begin
        half_clk <= tick;
    end process

これが求めているのは、の両端でクロックされるフリップフロップですtick

これは、波形が希望どおりに揺れるという点で目的を達成しているように見えますが、合成されません。また、出力に追加のデルタ遅延を追加します。これは、「将来」のクロックとして使用する場合に問題を引き起こす場合と引き起こさない場合があります。他の人がコメントしているように、これはほとんどのアーキテクチャではとにかく良い計画ではありません(しかし、一部の人にとっては「正しい方法」です)。

于 2011-06-10T09:32:09.470 に答える
0

起動時にリセットしていますか?tick の条件を定義した方法では、tick が 0 または 1 でない場合 (つまり、U、Z、X など)、何も起こりません。

一般的に、すべてのケースを条件式でカバーすることをお勧めします。つまり、次のようになります。

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        else 
            half_clk <= '1';
            tick <= '0';
        end if;

また

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        elsif tick = '1' then
            half_clk <= '1';
            tick <= '0';
        else
            -- Throw error or something here
        end if;
于 2011-06-07T12:15:56.550 に答える
0

シンプルなカウンターがそのトリックを行います (適切な方法はもちろん DCM です):

signal cnt : std_logic_vector(3 downto 0);

...

clk_div_2  <= cnt(0);
clk_div_4  <= cnt(1);
clk_div_8  <= cnt(2);
clk_div_16 <= cnt(3);

...

process(clk)
 if clk'event and clk = '1' then
  cnt <= cnt + 1;
 end if;
end process;
于 2011-11-17T14:42:15.700 に答える