如何向双向4位计数器(循环)添加最大值?

问题描述 投票:0回答:2

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

我现在想添加一个输入(可能来自开关等),该输入控制计数器的最大值,例如,如果输入的最大值为“ 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;
vhdl fpga electronics quartus vhd
2个回答
1
投票

您已指定同步重置。至少存在一个综合问题,其中推断出使能以控制时钟。在以下情况下,数字软件包已切换到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

使用您的测试台。


1
投票

这类似于@ user1155120的答案(建议您接受为答案),但是我改用了异步重置。还添加了通用名称以指定计数器中的位数。

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

entity UpdownCounter is
    generic
    (
        COUNTER_BITS: natural := 4
    );
    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(COUNTER_BITS - 1 downto 0); -- max value counter
        counter: out std_logic_vector(COUNTER_BITS - 1 downto 0) -- output N-bit counter
     );
end UpdownCounter;

architecture V1 of UpdownCounter is
    signal counter_updown: unsigned(COUNTER_BITS - 1 downto 0);
begin
    process(clk, reset)
    begin
        if reset then
            -- Do asynchronous reset.
            counter_updown <= (others => '0');
        elsif rising_edge(clk) then
            -- Do synchronous stuff.
            if enable then
                if up_down then
                    -- Count down to zero cyclically.
                    if counter_updown = 0 then
                        counter_updown <= unsigned(max);
                    else
                        counter_updown <= counter_updown - 1;
                    end if;
                else
                    -- Count up to max cyclically.
                    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 V1;

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

entity UpdownCounter_TB is
end UpdownCounter_TB;

architecture V1 of UpdownCounter_TB is

    component UpdownCounter
        generic
        (
            COUNTER_BITS: natural := 4
        );
        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(COUNTER_BITS - 1 downto 0); -- max value counter
            counter: out std_logic_vector(COUNTER_BITS - 1 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);

    signal halt_clk: boolean := false;

begin
    DUT: UpdownCounter
        generic map
        (
            COUNTER_BITS => 4
        )
        port map
        (
            clk => clk,
            reset => reset,
            enable => enable,
            up_down => up_down,
            max => max,
            counter => counter
        );

    -- Clock
    ClockProocess :process
    begin
        while not halt_clk loop
            clk <= '0';
            wait for 10 ns;
            clk <= '1';
            wait for 10 ns;
        end loop;
        wait;
    end process;

    StimulusProcess: 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 for 1000 ns;
        halt_clk <= true;

        wait;
    end process;

end V1;
© www.soinside.com 2019 - 2024. All rights reserved.