首页 文章

VHDL异步波纹计数器故障

提问于
浏览
0

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

以下是问题:

1.) inout ports,我首先将Q定义为inout(因为它's obviously my output and the bits are also used as clk inputs to their following flip flops). Still, when I wanted to simulate my code, the Q output was UUUU which makes sense cause I had to initialize it with the number I wanted my count to begin with. Though I didn'知道如何设置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 as 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;
                • 试验台 - - - - - -
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

    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) 的冗余其他分配信号将保持其值,直到被分配,这些是顺序(时钟)语句 . 还消除了冗余括号对 .

  • 0

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

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

    Examples of Counter implementations

    有关计数器实现的verilog和vhdl示例,请参见上面的链接 .

相关问题