VHDL异步波纹计数器故障

时间:2015-11-19 10:28:10

标签: vector vhdl counter

这是一个4位异步纹波计数器的设计(使用T触发器,但我没有为Tff定义一个组件,只是编码了关于T信号的电路行为)。

以下是问题:

1。) inout 端口,我首先将Q定义为inout(因为它显然是我的输出,这些位也被用作后续触发器的clk输入) 。不过,当我想模拟我的代码时,Q输出是UUUU,这是有道理的因为我不得不用我想要开头的数字来初始化它。虽然我不知道如何设置inout初始值(我试过Process ... Q <= "0000"; wait; end process但它没有用)!

2.。)为了解决上述问题,我将输入端口改为输出(Q_out)并将Q定义为信号,这工作但是...我的计数器只改变了Q(0)位而不是其他......因此它像:0,1,0,1,0,1,......

3.)我想调试这段代码。我尝试了另一种风格,而不是4位输出我定义了4个1位输出信号(Q_out1到Q_out2)以及4个内部信号Q0到Q1,这完美地起作用 我只是想知道为什么第一种风格(Q作为4_bit向量)没有成功。 提前感谢您的帮助。

这是我的代码及其测试平台:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity four_bit_Asynch_Counter is
    Port ( T0,T1,T2,T3 : in  STD_LOGIC;
           clk : in  STD_LOGIC;
              Q_out: out STD_LOGIC_VECTOR (3 downto 0));
end four_bit_Asynch_Counter;

architecture Behavioral of four_bit_Asynch_Counter is   

signal Q : STD_LOGIC_VECTOR (3 downto 0) := "0000";

begin
    Process (clk,Q(0),Q(1),Q(2))
        begin
            if (falling_edge(clk)) then
                if (T0 = '1') then
                    Q(0) <= not Q(0);
                else 
                    Q(0) <= Q(0);
                end if;
            end if;

            if (falling_edge(Q(0))) then
                if (T1 = '1') then
                    Q(1) <= not Q(1);
                else 
                    Q(1) <= Q(1);
                end if;
            end if;

            if (falling_edge(Q(1))) then
                if (T2 = '1') then
                    Q(2) <= not Q(2);
                else 
                    Q(2) <= Q(2);
                end if;
            end if;

            if (falling_edge(Q(2))) then
                if (T3 = '1') then
                    Q(3) <= not Q(3);
                else 
                    Q(3) <= Q(3);
                end if;
            end if;

            Q_out <= Q;
    end Process;
end Behavioral;

--------------- Test Bench ------------

     LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;


    ENTITY tb_counter IS
    END tb_counter;

    ARCHITECTURE behavior OF tb_counter IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT four_bit_Asynch_Counter
    PORT(
         T0 : IN  std_logic;
         T1 : IN  std_logic;
         T2 : IN  std_logic;
         T3 : IN  std_logic;
         clk : IN  std_logic;
         Q_out : OUT  std_logic_vector(3 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal T0 : std_logic := '1';
   signal T1 : std_logic := '1';
   signal T2 : std_logic := '1';
   signal T3 : std_logic := '1';
   signal clk : std_logic := '0';

    --Outputs
   signal Q_out : std_logic_vector(3 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: four_bit_Asynch_Counter PORT MAP (
          T0 => T0,
          T1 => T1,
          T2 => T2,
          T3 => T3,
          clk => clk,
          Q_out => Q_out
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  

      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

2 个答案:

答案 0 :(得分:0)

在可实现的硬件(ASIC或FPGA)中实现计数器时,不应使用纹波计数器。通过将触发器输出用作下一个时钟,您将具有次优时序,工具将无法准确验证设置和保持时间,并且您无法利用专用时钟路由。通常,异步设计对于实际实现来说是个坏主意。

真正的同步设计对于综合来说会更好,并且在VHDL代码中更容易推断。

Examples of Counter implementations

请参阅以上链接,了解计数器实现的verilog和vhdl示例。

答案 1 :(得分:0)

TL; DR答案是q(3)没有显示在您的过程敏感度列表中。

architecture behavioral of four_bit_asynch_counter is   
    signal q:  std_logic_vector (3 downto 0) := "0000";
begin
    process (clk, q(0), q(1), q(2))
    begin
        if  falling_edge(clk) then
            if t0 = '1' then
                q(0) <= not q(0);
            -- else
            --     q(0) <= q(0);
            end if;
        end if;

        if  falling_edge(q(0)) then
            if t1 = '1' then
                q(1) <= not q(1);
            -- else
            --     q(1) <= q(1);
           end if;
        end if;

        if falling_edge(q(1)) then
            if t2 = '1' then
                q(2) <= not q(2);
            -- else
            --     q(2) <= q(2);
            end if;
        end if;

        if falling_edge(q(2)) then
            if t3 = '1' then
                q(3) <= not q(3);
            -- else
            --     q(3) <= q(3);
            end if;
        end if;

        q_out <= q;

    end process;
end  architecture behavioral;

对于您的过程敏感度列表,您发现了一个如何根据由原色组成的表达式构建灵敏度列表的功能 - clk, q(0), q(1), q(2)

来自IEEE Std 1076-1993,8.1等待声明:

  

...
  灵敏度设置最初为空。对于条件子句条件下的每个主要,如果主要是

     
    

- 表示信号的简单名称,将名称的最长静态前缀添加到灵敏度集

         

- 前缀表示信号的选定名称,将名称的最长静态前缀添加到灵敏度集

         

- 扩展名称,其前缀表示信号,将名称的最长静态前缀添加到灵敏度集

         

- 索引名称,其前缀表示信号,将名称的最长静态前缀添加到敏感度集,并将此规则应用于索引名称中的所有表达式     ......

  
     

...
  此规则还用于在并发过程调用语句(9.3),并发断言​​语句(9.4)和并发信号赋值语句(9.5)的等效过程语句中构造等待语句的敏感性集。

     

如果表示复合类型信号的信号名称出现在敏感度列表中,则效果就好像该信号的每个标量子元素的名称出现在列表中。 >   ...

我只包含了这里感兴趣的规则元素,第一个包含时钟,显示的最后一个元素涵盖了由所选名称指定的std_logic_vector元素。

有助于理解最长静态前缀的含义。这在-1993中解释了6.1名称。

原色(索引名称)是静态名称(q(0), q(1), q(2)),每个索引名称的每个表达式都是静态的。

这意味着最长的静态前缀是包含每个主要的索引名称。

这使得q(3)悬挂在过程信号分配语句的微风中:

        q_out <= q;

如果对q(3)不敏感,则q_out的值不会更新,直到敏感列表中的下一个事件发生在clk上:

tb_counter

有两种方法可以解决这个问题,您可以在流程语句之外移动q_out赋值,它将成为并发信号分配(具有精确的等效流程,灵敏度列表设置为q ),或者您可以在当前过程中更改敏感度列表:

        process (clk, q)

q_out上的活动更新q(3)(注意上面8.1中最后引用的段落)。

此行为也适用于以后的标准修订版。

过程敏感度列表已修复:

sensitivity list fixed

你的计数器表现正常。

另请注意,我已注释掉q(0)q(1)q(2)q(3)的多余其他分配信号将保留其值,直到分配为这些是顺序(时钟)语句。还消除了多余的括号对。