【问题标题】:Counter 4bit with synchronous load and enable and asynchronous reset.具有同步加载和启用以及异步复位的 4 位计数器。
【发布时间】:2016-03-19 17:25:44
【问题描述】:

我有一个由 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;

【问题讨论】:

  • 有什么问题?你试过什么?
  • @damage 我尝试模拟它,但它不起作用。另外我想让我的负载和启用同步,我不知道怎么做。我必须制定一个流程吗?
  • 您尚未发布您的 D-FlipFlop,但我怀疑 D 输入实际上是同步输入。这些输入由多路复用器驱动,由名为enabledload 的信号控制。因此,根据我的假设,您的启用/加载逻辑实际上是同步的。所以,不清楚你在问什么。您可以提供一个测试平台和一个屏幕截图来解释出了什么问题。 (小点:h 的方程不是结构描述。)
  • @MartinZabel 当我尝试模拟 counterOut 没有任何反应时。计数器不开始计数

标签: load vhdl counter synchronous updown


【解决方案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;

【讨论】:

  • 您的代码缺少end if;,而count 的最后一个分配可能是一个错误。还有一个尾随^。您应该描述&lt;somevalue&gt; 的用途。如果你想让它保持打开状态,那么最好在它后面添加一个 VHDL 注释。
  • 最后一次分配给计数信号只是在你想在未启用时将计数器归零。除非您当然想保留旧值。原始规范含糊不清,因此解决方案也含糊不清。我知道可能存在拼写错误,因此帖子中的索赔人“类似”。如果需要完整的可编译和验证代码 - 那么我恐怕必须为此收费;)我相信没有人只是从互联网上复制/粘贴代码 - 或者如果他们这样做了,他们应该得到什么......跨度>
【解决方案2】:

因为您没有包含 D_FlipFlop 或 MUX 的实体/架构对,所以我想我会用一个替代所有 4 个 FF 的过程和替代多路复用器的并发条件信号分配语句来演示。

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

启用并向上计数为 FF 输入提供一个等于 counterout + 1 的值,我们称之为增量,并且计数器和进位树的每个元素只需要一个 xor。

同样的倒计时表示递减输入。

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

(作为芯片设计人员,我们曾经在更早的时代记住这些东西。您支付了使用算术元素(例如“+”或“-”运算符)的许可证。一种“你有 '0's? 回溯当我们过去常常把'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 输入多路复用器并为两个输入提供 not 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 以匹配 counterout。

所以是一个快速而肮脏的测试平台来练习抽象模型:

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;

这给了我们:

这表明增量和减量是正确的,以及多路复用器输入。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多