在 VHDL 中实现反向计数器
Implementing a reversing counter in VHDL
我是 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
两端都晚了一个刻度。
因为它是一个注册值,改变它的效果有 1 个时钟周期的延迟。因此,在达到 0xFF count_sig
时,将在反转方向之前再增加一次 (0x00)。然后它会计数'down'到0xFF,再次反转方向,导致值在0x00和0xFF之间不断闪烁。
改变条件以将方向改变为 count_sig = counter_steps - 2
和 count_sig = 1
分别为您提供所需的行为。
我是 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
两端都晚了一个刻度。
因为它是一个注册值,改变它的效果有 1 个时钟周期的延迟。因此,在达到 0xFF count_sig
时,将在反转方向之前再增加一次 (0x00)。然后它会计数'down'到0xFF,再次反转方向,导致值在0x00和0xFF之间不断闪烁。
改变条件以将方向改变为 count_sig = counter_steps - 2
和 count_sig = 1
分别为您提供所需的行为。