大家好,我最近开始使用VHDL进行编码(这里的代码是T触发器),我有一个错误,表示"进程时钟过于复杂",这是第一个代码附在下面,令我惊讶的是我的解决方案。但我不知道它是如何工作的,没有错误的代码是第二代码。我用谷歌搜索了半小时的错误,但无法找到令人满意的理由。请帮忙。
第一个代码:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY t_ff IS
PORT(t,clk,rst:IN STD_LOGIC;
q,q_bar:OUT STD_LOGIC);
END t_ff;
ARCHITECTURE t_ff OF t_ff IS
SIGNAL temp: STD_LOGIC;
BEGIN
PROCESS(clk,rst)
BEGIN
IF(clk='1' AND clk'event)THEN
IF(t='1')THEN temp<= NOT temp;
END IF;
ELSIF(rst='1')THEN temp<='0';
END IF;
q<= temp;
q_bar<= NOT temp;
END PROCESS;
END t_ff;
第二个代码:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY t_ff IS
PORT(t,clk,rst:IN STD_LOGIC;
q,q_bar:OUT STD_LOGIC);
END t_ff;
ARCHITECTURE t_ff OF t_ff IS
SIGNAL temp: STD_LOGIC;
BEGIN
PROCESS(clk,rst)
BEGIN
IF(rst='1')THEN temp<='0';
ELSIF(clk='1' AND clk'event)THEN
IF(t='1')THEN temp<= NOT temp;
END IF;
END IF;
q<= temp;
q_bar<= NOT temp;
END PROCESS;
END t_ff;
答案 0 :(得分:1)
原因很简单。但首先我们需要更改您的代码:
两个版本都没有描述T触发器的行为;两者都描述了至少2个(如果不是3个触发器)的行为。这是因为
时钟进程中的每个信号分配都会推断触发器
每个流程中有3个信号分配 - temp
,q
和q_bar
- 因此您将获得3个触发器(尽管1是冗余的,因此可能会被优化掉)由您的合成器)。因此,首先,如果您想保证只有一个触发器,则需要重写每个进程,以便只包含一个信号分配。
重写第一个流程没有意义,因为其他原因是错误的 - 请参阅后面的内容。第二个过程应该重写为:
PROCESS(clk,rst)
BEGIN
IF (rst='1') THEN temp<='0';
ELSIF (clk='1' AND clk'event) THEN
IF (t='1') THEN temp <= NOT temp;
END IF;
END IF;
END PROCESS;
q <= temp;
q_bar <= NOT temp;
换句话说,您需要将作业移至流程外的q
和q_bar
。这个新版本的第二个版本描述了带有异步复位的T型触发器的行为:
如果复位被置位,则复位触发器;否则,如果是T. 输入在时钟的上升沿被置位,然后反转 触发器
如果我重写了你的第一个版本,它会描述一些不存在的电子元件的行为,因此它无法合成。这种行为没有这样的触发器:
如果T 输入在时钟的上升沿被置位,然后反转 拖鞋;否则,如果复位被置位,则复位触发器
您可能已经描述了一个带有同步重置的T型触发器:
像这样在时钟的上升沿:如果复位被置位则复位 触发器,否则,如果T输入在上升时被置位 时钟的边沿,然后反转触发器
PROCESS(clk)
BEGIN
IF (clk='1' AND clk'event) THEN
IF (rst='1') THEN temp<='0';
ELSIF (t='1') THEN temp <= NOT temp;
END IF;
END IF;
END PROCESS;
q <= temp;
q_bar <= NOT temp;
最后,您使用的是一种相当老式的编码风格。我建议使用rising_edge
函数。你的括号也是多余的。经验丰富的VHDL代码会编写您的第二个版本:
PROCESS(clk,rst)
BEGIN
IF rst='1' THEN temp<='0';
ELSIF rising_edge(clk) THEN
IF t='1' THEN temp<= NOT temp;
END IF;
END IF;
END PROCESS;
q <= temp;
q_bar <= NOT temp;