首页 > 解决方案 > 在 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;

标签: vhdl

解决方案


count_dir在任一端更改一个刻度为时已晚。

由于它是一个注册值,因此更改它的效果会延迟 1 个时钟周期。因此,在达到 0xFF时,count_sig将在反转方向之前再增加一次 (0x00)。然后它将“向下”计数到 0xFF,再次反转方向,导致值在 0x00 和 0xFF 之间不断闪烁。

改变你的条件来改变方向count_sig = counter_steps - 2count_sig = 1分别给你你想要的行为。


推荐阅读