我试图检查ALU的结果是否为零。我从测试中得到零结果,但模拟显示alu_zero
不是' 1'。有人可以告诉我为什么吗?
Library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY alu IS
PORT(
alu_operand_A,alu_operand_B:in std_logic_vector(31 downto 0);
alu_control:in std_logic_vector(1 downto 0);
alu_result:out std_logic_vector(31 downto 0);
alu_zero:out std_logic
);
END alu;
ARCHITECTURE behavioral OF alu IS
signal s_alu_result:std_logic_vector(31 downto 0);
BEGIN
PROCESS(alu_operand_A,alu_operand_B,alu_control)
BEGIN
CASE alu_control IS
WHEN "00"=>s_alu_result<=alu_operand_A + alu_operand_B;
alu_result<=alu_operand_A + alu_operand_B;
WHEN "01"=>s_alu_result<=alu_operand_A - alu_operand_B;
alu_result<=alu_operand_A - alu_operand_B;
WHEN "10"=>s_alu_result<=alu_operand_A and alu_operand_B;
alu_result<=alu_operand_A and alu_operand_B;
WHEN "11"=>s_alu_result<=alu_operand_A or alu_operand_B;
alu_result<=alu_operand_A or alu_operand_B;
WHEN OTHERS=>alu_result<=(others=>'X');
END CASE;
if s_alu_result="00000000000000000000000000000000" then
alu_zero<='1';
else
alu_zero<='0';
end if;
END PROCESS;
END behavioral;
答案 0 :(得分:0)
代码中的概念错误是,信号分配不会立即发生。相反,如果未指定带有after
子句的延迟,则会为下一个增量周期安排新的信号值。但是,该过程不会再次执行,因为s_alu_result
不是敏感列表。因此,alu_zero
未分配给&#39; 1&#39;,因为s_alu_result
仍然是全部&#39; U&#39;在检查。最短的修复方法是将s_alu_result
添加到敏感度列表中:
PROCESS(alu_operand_A,alu_operand_B,alu_control,s_alu_result)
为了更好地理解,可以通过分配所有&#39; 0的常数值来进一步最小化代码。发信号s_alu_result
并删除所有不必要的信号和分配:
Library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY alu2 IS
PORT(
alu_zero : out std_logic
);
END alu2;
ARCHITECTURE behavioral OF alu2 IS
signal s_alu_result : std_logic_vector(31 downto 0);
BEGIN
PROCESS
BEGIN
s_alu_result <= (others => '0');
if s_alu_result="00000000000000000000000000000000" then
alu_zero<='1';
else
alu_zero<='0';
end if;
wait; -- empty sensitivity list
END PROCESS;
END behavioral;
灵敏度列表现在是空的,所以我必须在末尾插入一个wait;
语句来模仿正确的行为。如果你模拟这个,alu_zero
将是&#39; 0&#39;再次,而不是&#39; 1&#39;。价值全部&#39; 0&#39;被分配给信号s_alu_result
以进行下一个增量循环。因此,检查所有零,仍然使用旧的值,即全部&#39; U&#39;。因此,条件是错误的,并且&#39; 0&#39; 0被分配到all_zero
。
进一步评论:
要摆脱计算alu_result
和s_alu_result
的重复行,您应首先分配s_alu_result
,然后再分配alu_result <= s_alu_result
。
请勿使用Synopsys的非标准VHDL包std_logic_unsigned
。请改用numeric_std
。然后,您的操作数必须是unsigned
类型而不是std_logic_vector
,以指示应将位序列视为无符号数。然后,您还可以将检查简化为:s_alu_result = 0
。
最终代码如下所示:
Library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY alu IS
PORT(
alu_operand_A : in unsigned(31 downto 0);
alu_operand_B : in unsigned(31 downto 0);
alu_control : in std_logic_vector(1 downto 0);
alu_result : out unsigned(31 downto 0);
alu_zero : out std_logic
);
END alu;
ARCHITECTURE behavioral OF alu IS
signal s_alu_result : unsigned(31 downto 0);
BEGIN
PROCESS(alu_operand_A, alu_operand_B, alu_control, s_alu_result)
BEGIN
CASE alu_control IS
WHEN "00" => s_alu_result <= alu_operand_A + alu_operand_B;
WHEN "01" => s_alu_result <= alu_operand_A - alu_operand_B;
WHEN "10" => s_alu_result <= alu_operand_A and alu_operand_B;
WHEN "11" => s_alu_result <= alu_operand_A or alu_operand_B;
WHEN OTHERS => s_alu_result <= (others => 'X');
END CASE;
alu_result <= s_alu_result;
if s_alu_result = 0 then
alu_zero <= '1';
else
alu_zero <= '0';
end if;
END PROCESS;
END behavioral;