我是VHDL的新手,我想实现一个计数器,从0开始向上计数到最大值,一旦达到最大值就自动开始向下计数。这是我的实体和架构。
entity Rev_Counter is -- self-reverting counter
generic (
counter_steps: integer:=256; -- number of steps of the counter
counter_output_size: integer:=8 -- smallest nr of bits to represent the biggest value of the counter
);
port (
clock: in std_logic; -- input clock signal
output: out std_logic_vector (counter_output_size-1 downto 0)
);
end Rev_Counter;
architecture Arh_Rev_Counter of Rev_Counter is
signal count_sig: std_logic_vector (counter_output_size-1 downto 0) := (others => '0');
signal count_dir: std_logic := '0'; -- 0 = count up, 1 = count down
begin
Count: process (clock)
begin
if (clock'event and clock = '1') then
if (count_sig = counter_steps-1) then -- revert the counting direction
count_dir <= '1'; -- reached highest value, count down
count_sig <= count_sig - 1;
elsif (count_sig = 0) then -- revert the counting direction
count_dir <= '0'; -- reached lowest value, count up
count_sig <= count_sig + 1;
end if;
if (count_dir = '0') then -- perform count up
count_sig <= count_sig + 1;
elsif (count_dir = '1') then -- preform count down
count_sig <= count_sig - 1;
end if;
end if;
end process;
output <= count_sig;
end architecture;
我的问题是: 当模拟这段代码时,我的计数器正常计数到FF, 然后它开始表现得很奇怪。在数到FF之后,它直接进入00,然后是FF,然后是00,以此类推,没有中间的数字。我希望能得到一些帮助,弄清楚它为什么会这样。
我找到了一个替代方法。我编辑了 Count
的过程,变成了这个样子。但是,我并不完全明白当初是哪里出了问题,因此,我还是希望得到一些启示。
Count: process (clock)
begin
if (clock'event and clock = '1') then
if (count_dir = '0') then
count_sig <= count_sig + 1;
if (count_sig = counter_steps - 1) then
count_sig <= count_sig - 1;
count_dir <= '1';
end if;
elsif (count_dir = '1') then
count_sig <= count_sig - 1;
if (count_sig = 0) then
count_dir <= '0';
end if;
end if;
end if;
end process;
你正在改变 count_dir
两端晚了一个刻度。
由于它是一个注册值,改变它的效果有一个时钟周期的延迟。因此,在达到0xFF count_sig
将再递增一次(0x00),然后再反转方向。然后,它会 "倒数 "到0xFF,再次反转方向,导致该值不断在0x00和0xFF之间闪烁。
改变您的条件,将方向改为 count_sig = counter_steps - 2
和 count_sig = 1
分别给你想要的行为。