首页 > 解决方案 > 如何向双向 4 位计数器(循环)添加最大值?

问题描述

我有这个代码,它是一个循环的双向计数器。

我现在想添加一个输入(可能来自开关或其他东西),它控制计数器的最大值,例如,如果输入的最大值为“0111”,则计数器将计数到 0111,然后循环返回0000,如果计数器倒计时到 0000,它将循环回到 0111。我对如何/在哪里执行此操作有点困惑,因为我使用嵌套 ifs 来实现启用和重置输入。

这是代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity UPDOWN_COUNTER is
    Port ( clk: in std_logic; -- clock input
           reset: in std_logic; -- reset input 
           up_down: in std_logic; -- up or down
            enable: in std_logic; -- enable

            max: in std_logic_vector(3 downto 0); -- max value counter 

           counter: out std_logic_vector(3 downto 0) -- output 4-bit counter
     );
end UPDOWN_COUNTER;

architecture Behavioral of UPDOWN_COUNTER is
signal counter_updown: std_logic_vector(3 downto 0);
begin
process(clk,reset,enable,max)
begin
if(enable ='1') then
if(rising_edge(clk)) then
    if(reset='1') then
         counter_updown <= x"0";
    elsif(up_down='1') then
         counter_updown <= counter_updown - x"1"; -- count down 
    else 
         counter_updown <= counter_updown + x"1"; -- count up
    end if;
  end if;
 end if;
end process;

 counter <= counter_updown;

end Behavioral;

这是测试台:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tb_counters is
end tb_counters;

architecture Behavioral of tb_counters is

component UPDOWN_COUNTER 
    Port ( clk: in std_logic; -- clock input
           reset: in std_logic; -- reset input 
           up_down: in std_logic; -- up or down input
            enable: in std_logic; -- enable input
            max: in std_logic_vector(3 downto 0); -- max value counter 
           counter: out std_logic_vector(3 downto 0) -- output 4-bit counter
     );
end component;
signal reset,clk,enable,up_down: std_logic;
signal max,counter:std_logic_vector(3 downto 0);

begin
dut: UPDOWN_COUNTER port map (clk => clk, reset=>reset,enable => enable, up_down => up_down, max => max,counter => counter);
   -- Clock 
clock_process :process
begin
     clk <= '0';
     wait for 10 ns;
     clk <= '1';
     wait for 10 ns;
end process;

stim_proc: process
begin        

    max <= "1000"; -- Test value for Counter max value
    enable <= '1'; 
     reset <= '1';
   up_down <= '0';
    wait for 20 ns;    
    reset <= '0';
  wait for 300 ns;    
  up_down <= '1';
  --
  wait for 50 ns;
  enable <= '0';
  wait for 50 ns;
  enable <= '1';
   wait;
end process;
end Behavioral;

标签: vhdlfpgaquartusintel-fpga

解决方案


您已指定同步重置。至少存在一个综合问题,其中推断启用以门控时钟。下面的数值包已经切换为ieee.numeric_std(示例可以修改为非标准的Synopsys数值包):

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity updown_counter is
    port ( 
        clk:        in  std_logic;
        reset:      in  std_logic;
        up_down:    in  std_logic;
        enable:     in  std_logic;
        max:        in  std_logic_vector(3 downto 0); 
        counter:    out std_logic_vector(3 downto 0) 
     );
end entity updown_counter;

architecture behavioral of updown_counter is
    signal counter_updown:  unsigned(3 downto 0);
begin
    process (clk) -- other signals evaluated inside clock edge
    begin
        if rising_edge(clk) then
            if enable = '1' then  -- don't gate the clock
                if reset = '1' then
                    counter_updown <= (others => '0');
                elsif up_down = '1' then             -- down
                    if counter_updown = 0 then
                        counter_updown <= unsigned(max);
                    else
                        counter_updown <= counter_updown - 1;
                    end if;
                else -- count up
                    if counter_updown = unsigned(max) then
                        counter_updown <= (others => '0');
                    else
                        counter_updown <= counter_updown + 1;
                    end if;
                end if;
            end if;
        end if;
    end process;
     counter <= std_logic_vector(counter_updown);
end architecture behavioral;

这给出了:

tb_counters.jpg

与您的测试台。


推荐阅读