0

私は今 VHDL を勉強しています。非常に簡単な宿題があります。0 から 9 までカウントし、9 に達すると 0 に戻る同期 BCD カウンターを作成する必要があります。少し実験したかったのです。そのため、(少なくとも私が見ているように) 従来の方法 (if、elseif を使用) ではなく、when-else ステートメントを使用してコードを実行することにしました (ほとんどの場合、カウンターは 0 から 9 までであり、 9 に達したら 0 に戻ります)。

library IEEE;
    use IEEE.std_logic_1164.all;

Entity sync_counter is
    port (rst, clk: in std_logic);
end Entity;

Architecture implement of sync_counter is
    signal counter: integer range 0 to 10;
Begin
        counter <=    0 when (rst = '1') else
                      counter + 1 when (clk='1' and clk'event) else
                      0 when (counter = 10);
end Architecture;

したがって、すべてがコンパイルされますが、シミュレーションでは、最初にカウンターが 0 から 2 にジャンプしますが、サイクル (0-9 - 0) の後、正常に動作します。つまり、カウンターは本来あるべきように 0 から 1 になります。rst = '1' を強制する場合も同様です。

シミュレーション画像: BCDカウンターシミュレーション

最初に 0 から 2 にジャンプするのはなぜですか?

ありがとうございました。

4

1 に答える 1

2

0 から 2 になる理由を説明できない場合があります。その前にテストベンチ コードを投稿してください。しかし、あなたのコードは悪いです。このコードは、コメント付きで次のように変換されます。

process(rst, clk, counter)
begin
    if rst = '1' then -- Asynchronous reset, so far so good
        counter <= 0;
    elsif clk'event and clk = '1' then -- Rising edge, we got an asynchronous flip-flop?
        counter <= counter + 1;
    elsif counter = 10 then -- What is this!?! not an asynchronous reset, not a synchronous reset, not a clock. How does this translate to hardware?
        counter <= 0;
    end if;
end process;

これがハードウェアで機能するかどうかはわかりませんが、実装方法がすぐにはわかりません。必要なのは次のとおりです。

process(rst, clk)
begin
    if rst = '1' then -- Asynchronous reset
        counter <= 0;
    elsif clk'event and clk = '1' then
        if counter = 9 then -- Synchronous reset
            counter <= 0;
        else
            counter <= counter + 1;
        end if;
    end if;
end process;

「when-else」ステートメントは、純粋な組み合わせコード、またはせいぜい 1 行に残しますreg <= value when rising_edge(clk)

于 2015-03-28T19:22:02.217 に答える