我在确定代码无法正常工作的原因时遇到了一些困难。我正在尝试使用3位操作码创建一个ALU。
除了一个条件之外的所有条件都不能正常工作;操作码011(SEQ)。它被定义为(a == b)z< ='0'并且输出< ='0'。 a和b是输入,z是零标志。我希望通过以下VHDL代码获得此功能
....
BEGIN
result <= dummy_result;
PROCESS (a, b, op)
VARIABLE carry: STD_LOGIC:='0';
--DEFINE ALIAS TO SEPERATE ALU-OP SIGNAL
alias NEG_TSEL : STD_LOGIC IS op(2);
alias ALU_SELECT : STD_LOGIC_VECTOR(1 downto 0) IS op(1 downto 0);
BEGIN
if ALU_SELECT="11" THEN
if NEG_TSEL='0' THEN -- SEQ
if a = b THEN
dummy_result <="00000";
end if;
elsif NEG_TSEL='1' THEN --SCO
cout <= '1';
result <= "XXXXX";
end if;
elsif ALU_SELECT="00" THEN...
使用此代码,当op = 011时,结果始终设置为零。
当我将代码更改为:
时 .....
if a = b THEN
dummy_result <="00000";
else
dummy_result <= "10101";
end if;
.....
它工作正常,但结果不能改变,所以而不是“10101”向量,我将其更改为“dummy_result&lt; = dummy_result;”但这给了我原始案例给我的相同结果。
有什么建议吗?我做错了吗?
答案 0 :(得分:0)
以下是我的代码问题:
就我个人而言,我觉得在每个周期中你应该输出一些内容result
,cout
和zero
。目前,您始终输出到zero
,但您只能有条件地输出到其他两个端口。这可能是创建锁存器,这可能不是你想要的。因此,例如,SCO操作也应该将某些内容推送到cout
,并且SCO操作应该将某些内容推送到dummy_result
信号。
您的减法实施方式无法实现您的预期效果。
when "110" => -- SUB
tmp_b <= NOT b;
carry := '1';
for i in 0 to 4 loop
dummy_result(i) <= carry XOR a(i) XOR tmp_b(i);
carry := (a(i) AND tmp_b(i)) OR (tmp_b(i) AND carry) OR (carry AND a(i));
end loop;
cout <= carry;
tmp_b
是一个信号。在那里发生的逻辑将与此过程中的其他所有内容同时发生,而不是顺序发生。你可能希望它是一个变量,就像carry
一样。
我还想让您了解案例陈述(与链条相对)。您的代码可能如下所示:
PROCESS (a, b, op)
VARIABLE carry: STD_LOGIC:='0';
BEGIN
case op is
when "011" => -- SEQ
dummy_result <= "00000";
when "111" => -- SCO
cout <= '1';
when "000" => -- AND
dummy_result <= a AND b;
...
when others =>
dummy_result <= "00000";
cout <= '0';
end case;
end process;
要回到原始问题SEQ
,原始代码如下:
when op = "011" =>
if a = b then
dummy_result <= "00000";
end if;
正如我上面提到的,这里的问题是这可能是一个闩锁。当a / = b时,您需要输出您期望值的值,并且不能只是dummy_result <= dummy_result
。如果你把它推到物理线和芯片上,你会怎么想?
相反,你应该将最后一个dummy_result的值传递给这个实体,或者如果一个特定的操作应该保存结果的值,你应该输出&#34; 00000&#34;并且还输出一个附加信号,表示无论持有之前的值(在寄存器中),都不应该更新它。
答案 1 :(得分:0)
这里的意图是除非另有指定,否则dummy_result旨在保留“result”的先前值。不幸的是,这个单元已经实现为一个没有时钟的组合过程。
因此,本机无法可靠地实施存储 因此必须在本单元外实施 几乎可以肯定的是;在作为计时过程实现的寄存器中。
因此,将该寄存器的输出作为新的输入端口“prev_result”重新输入,并使用对dummy_result的默认赋值。这不仅会克服到目前为止发现的特定故障,而且还会克服“dummy_result”(还有另一个)的所有其他缺失分配,以同步方式保留“结果”的旧值。
PROCESS (a, b, op, prev_result)
-- declarations here
BEGIN
-- default assignment
dummy_result <= prev_result;
if ALU_SELECT="11" THEN
if NEG_TSEL='0' THEN -- SEQ
if a = b THEN
dummy_result <="00000";
end if;
...
END PROCESS;
我认为你会更好地重组设计,使ALU成为一个时钟进程,但如果你不遵守指示,那么你将不得不采用这个(或类似的)解决方案。