は のビットn
数ですcnt
。これは次のとおりです。
if cnt = n-1 then
count <= '1';
次のようにする必要があります。
if cnt = 2**n-1 then
count <= '1';
count
は 1 クロックで '1' のみです。まばたきして見逃しましたか?クロックレートを指定しませんでした。カウンターのデモを行う目的で、clk を 25 MHz に設定しました。
これは上記の補正を使用しており、短い波形表示に収まるようにn
設定されています。3

上記の修正がなければ、count
「パルス」は 19 クロック後に発生します。信号機のコントローラーが応答しなかった理由は別の問題です。
カウントをスティッキーにする
タイマーを19クロックの遅延として使用したいとコメントした後、ジムにカウントをラッチする方法を尋ねました。
n-1
が のトリガー値であると仮定しcount
ます。
elsif rising_edge(clk) and cnt /= n-1 then
cnt := cnt + 1;
end if;
これは基本的に、インバーターと同じn
広いゲート出力を使用して、カウンターに提供して有効にします。ラッチされたトリガ値から だけ抜けます。count
cnt
cnt
reset
また、この場合は 5 ビットの長さしか必要ないのに、宣言でビット値cnt
として指定されるのはなぜですか?n
タイマーを一般化するために、トリガー カウントを個別に指定する予定はありますか? その場合、同期リセットが適切であると思われます。
最も簡単な全体的な解決策は次のとおりです-
cnt と整数型を作成します。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity timer is
generic (
trigger_cnt: natural := 19
);
port (
clk: in std_logic;
reset: in std_logic;
count: buffer std_logic
);
end entity timer;
architecture behavioural of timer is
begin
o0: process (clk, reset) IS
variable cnt : natural range 0 to trigger_cnt;
begin
if reset = '0' then
cnt := 0;
elsif rising_edge(clk) and count = '0' then
cnt := cnt + 1;
end if;
if cnt = trigger_cnt then
count <= '1';
else
count <= '0';
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity tb_timer is
end entity;
architecture foo of tb_timer is
signal clk: std_logic := '0';
signal reset: std_logic;
signal count: std_logic;
begin
DUT:
entity work.timer
generic map (
trigger_cnt => 7
)
port map (
clk => clk,
reset => reset,
count => count
);
CLOCK:
process
begin
wait for 20 ns;
clk <= not clk;
if Now > 360 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
reset <= '0';
wait for 40 ns;
reset <= '1';
wait;
end process;
end architecture;
これにはスティッキーがあることに注意してくださいcount
:

ジェネリックとしての代わりにn
、値trigger_cnt
(整数型と互換性があります) がジェネリックとして提示されます。
プロセスでは、適切なビット数の合成カウンターを取得するtrigger_cnt
範囲を制限するために使用されます。cnt
cnt
カウンターはリセットされるまで停止するため、その範囲を超える整数型に基づく厄介なエラーはありません。
これは、VHDL 実装の整数範囲 (ここに示されている自然な範囲subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
。INTEGER'HIGH は実装定義であり、少なくとも 2**31-1 (+2147483647、事前定義された整数型、IEEE Std 1076 を参照) )。