Как я могу добавить максимальное значение к своему двунаправленному 4-битному счетчику (l oop)? - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть этот код, который представляет собой двунаправленный счетчик, который зацикливается.

Теперь я хочу добавить вход (возможно, от переключателей или чего-то еще), который контролирует максимальное значение счетчика, например, если максимальное значение на входе - «0111», счетчик будет считать до 0111, а затем l oop вернется к 0000, а если счетчик обратного отсчета до 0000, то l oop вернется к 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;

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Это похоже на ответ @ user1155120 (который я рекомендую вам принять в качестве ответа), но вместо этого я использовал асинхронный сброс. Также добавлен шаблон c для указания количества бит в счетчике.

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;
1 голос
/ 28 февраля 2020

Вы указали синхронный сброс. Существует, по крайней мере, одна проблема синтеза, где подразумевается, что enable обеспечивает контроль над временем. Пакет Numberri c был переключен на ieee.numeric_std в следующем (пример может быть изменен для нестандартного пакета Synopsys цифра c):

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

с вашим испытательным стендом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...