这是一个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;
答案 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
上:
有两种方法可以解决这个问题,您可以在流程语句之外移动q_out
赋值,它将成为并发信号分配(具有精确的等效流程,灵敏度列表设置为q
),或者您可以在当前过程中更改敏感度列表:
process (clk, q)
为q_out
上的活动更新q(3)
(注意上面8.1中最后引用的段落)。
此行为也适用于以后的标准修订版。
过程敏感度列表已修复:
你的计数器表现正常。
另请注意,我已注释掉q(0)
,q(1)
,q(2)
和q(3)
的多余其他分配信号将保留其值,直到分配为这些是顺序(时钟)语句。还消除了多余的括号对。