这是一个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 回答
TL; DR答案是
q(3)
未显示在您的过程敏感性列表中 .对于您的过程敏感性列表,您已经发现了一个如何根据由原色组成的表达式构建灵敏度列表的功能 -
clk, q(0), q(1), q(2)
.来自IEEE Std 1076 -1993,8.1等待声明:
我只包含了这里感兴趣的规则元素,第一个包含时钟,显示的最后一个元素覆盖了由所选名称指定的std_logic_vector元素 .
它有助于理解最长静态前缀的含义 . 这在-1993中解释了6.1名称 .
原色(索引名称)是静态名称(
q(0), q(1), q(2)
),每个索引名称的每个表达式都是静态的 .这意味着最长的静态前缀是包含每个主要的索引名称 .
这使得过程信号分配声明在微风中悬空
q(3)
:如果没有对
q(3)
的敏感度,q_out
的值直到敏感度列表中的下一个事件才会更新,该事件恰好在clk
上:有两种方法可以解决这个问题,您可以在流程语句之外移动
q_out
赋值,它将成为并发信号分配(具有精确的等效过程,灵敏度列表设置为q
),或者您可以更改灵敏度列表 . 现在的过程:因此
q_out
更新为q(3)
上的事件(注意上面8.1中最后引用的段落) .此行为也适用于标准的后续修订 .
过程灵敏度列表是固定的:
你的计数器行为正常 .
另请注意,我注释掉
q(0)
,q(1)
,q(2)
和q(3)
的冗余其他分配信号将保持其值,直到被分配,这些是顺序(时钟)语句 . 还消除了冗余括号对 .在可实现的硬件(ASIC或FPGA)中实现计数器时,不应使用纹波计数器 . 通过将触发器输出用作下一个时钟,您将具有次优时序,工具将无法准确验证设置和保持时间,并且您无法利用专用时钟路由 . 通常,异步设计对于实际实现来说是个坏主意 .
一个真正的同步设计对于综合来说会更好,并且在VHDL代码中更容易推断 .
Examples of Counter implementations
有关计数器实现的verilog和vhdl示例,请参见上面的链接 .