计数器4bit具有同步加载和启用以及异步复位。

时间:2016-03-19 17:25:44

标签: load vhdl counter synchronous updown

我有一个由D触发器和多路复用器组成的4位计数器。它最多可达1111,然后降至0000.我的设计是结构性的。虽然我不知道如何使启用和负载同步。 这是我的尝试:

entity counter4Bit is
    Port ( clock : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           load : in  STD_LOGIC;
           enable : in  STD_LOGIC;
           ud : in  STD_LOGIC;
           counterOut : out  STD_LOGIC_VECTOR (3 downto 0));
end counter4Bit;

architecture Behavioral of counter4Bit is

Component MUX
    Port ( sel : in  STD_LOGIC_VECTOR (1 downto 0);
           a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           c : in  STD_LOGIC;
           d : in  STD_LOGIC;
           f : out  STD_LOGIC);
end component;

Component D_FlipFlop
    Port ( D : in  STD_LOGIC;
           Resetn : in  STD_LOGIC;
           Clock : in  STD_LOGIC;
           Q : out  STD_LOGIC);
end component;

signal w: std_logic_vector(3 downto 0);
signal h: std_logic_vector(3 downto 0);
signal q0,q1,q2,q3 :std_logic;
signal nq0,nq1,nq2,nq3 :std_logic;

begin

FF0 : D_FlipFlop
    port map( D => w(0),
                 Resetn => reset,
                 Clock => clock,
                 Q => q0);

FF1 : D_FlipFlop
    port map( D => w(1),
                 Resetn => reset,
                 Clock => clock,
                 Q => q1);

FF2 : D_FlipFlop
    port map( D => w(2),
                 Resetn => reset,
                 Clock => clock,
                 Q => q2);

FF3 : D_FlipFlop
    port map( D => w(3),
                 Resetn => reset,
                 Clock => clock,
                 Q => q3);

MUX0 : MUX
    port map( sel(0) => h(0),
                 sel(1) => load,
                 a => q0,
                 b => nq0,
                 c => '1',
                 d => '1',
                 f => w(0) );

MUX1 : MUX
    port map( sel(0) => h(1),
                 sel(1) => load,
                 a => q1,
                 b => nq1,
                 c => '1',
                 d => '1',
                 f => w(1) );

MUX2 : MUX
    port map( sel(0) => h(2),
                 sel(1) => load,
                 a => q2,
                 b => nq2,
                 c => '0',
                 d => '0',
                 f => w(2) );   

MUX3 : MUX
    port map( sel(0) => h(3),
                 sel(1) => load,
                 a => q3,
                 b => nq3,
                 c => '0',
                 d => '0',
                 f => w(3) );                    

h(0) <= (ud and enable) or (enable and (not ud) );
nq0 <= not q0;

h(1) <= (ud and enable and q0) or (enable and (not ud) and nq0) ;
nq1 <= not q1;

h(2) <= (ud and enable and q0 and q1 ) or (enable and (not ud) and nq1 and nq0);
nq2 <= not q2;

h(3) <= (ud and enable and q0 and q1 and q2 ) or (enable and (not ud) and nq1 and nq2 and nq0);
nq3 <= not q3;

counterOut(0) <= q0;
counterOut(1) <= q1;
counterOut(2) <= q2;
counterOut(3) <= q3;
end Behavioral;

2 个答案:

答案 0 :(得分:1)

这是一些学术作业还是类似的东西?如果没有,扔掉所有那些触发器实例和多路复用器,只需编写一个时钟程序。类似的东西:

signal count : integer range 0 to 15;

process(clk, rst)
  begin
    if rst = '0' then
      count <= 0;    
    elsif rising_edge(clk) then
      if enable = '1' then
        if load = '1' then
          count <= <somevalue>;
        elsif count < 15 then
          count <= count + 1;
        else
          count <= 0;
        end if;^
      else
        count <= 0;
    end if;
end process;

答案 1 :(得分:1)

因为你没有为D_FlipFlop或MUX包含实体/体系结构对,所以我想用一个过程代替所有4个FF和并发条件信号赋值语句来代替多路复用器。

这里的想法是演示如何使用位宽的四输入多路复用器,尽管我们可以根据整个计数器值来描述一些事情。

启用和向上计数表示FF输入的值等于计数器+ 1,我们称之为递增,对于计数器的每个元素和进位树只需要一个xor。

同样倒计时显示减量输入。

事实证明LSB在启用时总是切换,因此计数器的LSB可以有一个非计数器LSB输入。

(作为芯片设计师,我们曾经在早期的时代记住这些东西。你支付了使用算术元素的许可证(例如“+”或“ - ”运算符)。有点“你有'0'?回来当我们过去常常把'1'放在他们身边时“那种回忆。无论如何你倾向于记住捷径,加法器的B输入的'0'值的递增和递减会降低一个XOR并且需要非值。)

多路复用器的四个输入需要两个选择输入。您可以任意为输入分配功能并选择值。例如:

hold (no enable, no load) 00  
load                      01  
enable and up             10  
enable and down           11  

该选择行将是:

sel(1) <= enable and not load;  -- overriding load
sel(0) <= load or (not load and enable and ud);

其中加载优先于计数。 sel输入用于所有四个多路复用器。注意,“10”和“11”值的等式 sel组合在以下代码的MUX0上,您可以使用4输入多路复用器,并且不向两个输入提供q(0):

library ieee;
use ieee.std_logic_1164.all;

entity counter4bit is  -- updown counter sync load, enable, async reset
    port ( 
        clock:       in  std_logic;
        reset:       in  std_logic;
        load:        in  std_logic;
        enable:      in  std_logic;
        ud:          in  std_logic;  -- assume up  = '0', down = '1'
        counterin:   in  std_logic_vector (3 downto 0); -- ADDED
        counterout:  out std_logic_vector (3 downto 0)
    );
end entity counter4bit;

architecture foo of counter4bit is
    signal sel:     std_logic_vector (1 downto 0); -- mux selects
    signal din:     std_logic_vector (3 downto 0); -- outputs of muxes to FFs
    signal q:       std_logic_vector (3 downto 0); -- output of FFs
    signal incr:    std_logic_vector (3 downto 1);
    signal decr:    std_logic_vector (3 downto 1);
begin

FLIPFLOPS:  -- abstract the structural FFs away, no MCVE provided.
    process (reset, clock)
    begin
        if reset = '0' then  -- resetn on FF component declaraiton 
            q <= (others => '0');  -- reset all FFs to '0'
        elsif rising_edge(clock) then
            q <= din;
        end if;
    end process;

    -- Pick values of select for the conditions 
    -- hold (no enable, no load) 00
    -- load                      01
    -- enable and up             10
    -- enable and down           11

    sel(1) <= enable and not load;  -- overriding load
    sel(0) <= load or (not load and enable and ud);

    -- UP incrementer

--  incr(0) <= not q(0);
    incr(1) <= q(1) xor q(0);
    incr(2) <= q(2) xor (q(0) and q(1));
    incr(3) <= q(3) xor (q(0) and q(1) and q(2));

    -- DOWN decrementer

-- decr(0) <= not q(0);
    decr(1) <= q(1) xor not q(0);
    decr(2) <= q(2) xor (not q(0) and not q(1));
    decr(3) <= q(3) xor (not q(0) and not q(1) and not q(2));

-- no MCVE provided multiplexers either

MUX0:
    din(0) <= (q(0)         and not sel(1) and not sel(0)) or  -- hold "00"
              (counterin(0) and not sel(1) and     sel(0)) or  -- load "01"
           -- (incr(0)      and     sel(1) and not sel(0)) or  -- up   "10"
           -- (decr(0)      and     sel(1) and     sel(0));    -- down "11"
              (not q(0)     and     sel(1));                   -- "10" | "11"

              --  din(0) only requires a 3 input mux

MUX1:
    din(1) <= (q(1)         and not sel(1) and not sel(0)) or  -- hold "00"
              (counterin(1) and not sel(1) and     sel(0)) or  -- load "01"
              (incr(1)      and     sel(1) and not sel(0)) or  -- up   "10"
              (decr(1)      and     sel(1) and     sel(0));    -- down "11"

            -- din(1) through din(3) require 4 input muxes

MUX2:
    din(2) <= (q(2)         and not sel(1) and not sel(0)) or  -- hold "00"
              (counterin(2) and not sel(1) and     sel(0)) or  -- load "01"
              (incr(2)      and     sel(1) and not sel(0)) or  -- up   "10"
              (decr(2)      and     sel(1) and     sel(0));    -- down "11"

MUX3:
    din(3) <= (q(3)         and not sel(1) and not sel(0)) or  -- hold "00"
              (counterin(3) and not sel(1) and     sel(0)) or  -- load "01"
              (incr(3)      and     sel(1) and not sel(0)) or  -- up   "10"
              (decr(3)      and     sel(1) and     sel(0));    -- down "11"           
OUTPUT:
    counterout <= q; 

end architecture;

另外需要注意的是,有一个额外的输入端口来提供负载值,任意命名为counterin以匹配计数器。

这是一个快速而肮脏的测试平台来运用抽象模型:

library ieee;
use ieee.std_logic_1164.all;

entity counter4bit_tb is
end entity;

architecture foo of counter4bit_tb is
    signal clock:       std_logic := '0';
    signal reset:       std_logic;  -- '0' for reset
    signal load:        std_logic;
    signal enable:      std_logic;
    signal ud:          std_logic; -- up  = '0', down = '1'
    signal counterin:   std_logic_vector (3 downto 0);
    signal counterout:  std_logic_vector (3 downto 0);
begin
DUT:
    entity work.counter4bit
        port map (
            clock => clock,
            reset => reset,
            load  => load,
            enable => enable,
            ud => ud,
            counterin => counterin,
            counterout => counterout
        );
CLKGEN:
    process
    begin
        wait for 5 ns;
        clock <= not clock;
        if now > 380 ns then
            wait;
        end if;
    end process;

STIMULIS:
    process
    begin
        wait for 6 ns;
        reset <= '0';
        load <= '0';
        enable <= '0';
        ud <= '0';  -- up
        counterin <= (others => '1');
        wait for 20 ns;
        reset <= '1';
        load <= '1';
        wait for 10 ns;
        load <= '0';
        wait for 10 ns;
        enable <= '1';  
        wait for 160 ns;
        ud <= '1';  -- down
        wait for 160 ns;
        enable <= '0';
        wait;
    end process;
end architecture;

这给了我们:

counter4bit_tb.png

其中显示增量和减量是正确的,以及多路复用器输入。

因此,这是组织四个输入多路复用器以提供保持(无增量,无减量,无负载),负载,增量和减量的一种方法。您还可以注意到它预计会异步重置。