n
中的位数在哪里cnt
,这是:
if cnt = n-1 then
count <= '1';
应该:
if cnt = 2**n-1 then
count <= '1';
count
一个时钟只有“1”。你有没有眨眼并错过它?您没有指定时钟频率。为了演示计数器,我将 clk 设置为 25 MHz。
这是上面的校正并n
设置为3
使其适合短波形显示:
如果没有上述校正,count
“脉冲”将在 19 个时钟之后发生。为什么您的红绿灯控制器没有响应是另一个问题。
使计数变得粘稠
在您发表评论说您想将计时器用作 19 个时钟延迟之后,您问 Jim 如何锁定计数。
假设n-1
是 的触发值count
:
elsif rising_edge(clk) and cnt /= n-1 then
cnt := cnt + 1;
end if;
这基本上使用与反相器相同的n
宽栅极输出count
来提供和启用cnt
计数器。它只会超出cnt
by的锁存触发值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 )。