VHDL 4位无符号ALU加法功能异常,减法功能正常求助
4位无符号ALU加法功能异常排查
我首次编写VHDL测试平台,针对一款仅支持加减运算的4位无符号ALU(溢出/下溢需触发error信号),目前发现减法功能可正常输出结果,但加法功能无法正常输出预期结果。原本认为temp_result可正常赋值给result,但此处疑似存在问题。尝试过使用变量、信号,但始终存在异常,怀疑问题出在temp_result的调用、result的赋值逻辑或代码位置,也可能是测试平台的端口映射有误。
ALU主代码
entity ALU is port ( A: in unsigned(3 downto 0); B: in unsigned(3 downto 0); result: out unsigned(3 downto 0); opcode: in bit; error: out bit ); end entity ALU; architecture Behavioral of ALU is signal temp_result: unsigned(4 downto 0); begin process(A, B, opcode) begin case opcode is when '0' => temp_result <= resize(A, temp_result'length) + resize(B, temp_result'length); when '1' => temp_result <= resize(A, temp_result'length) - resize(B, temp_result'length); end case; -- Assign result result <= temp_result(3 downto 0); -- Error output if temp_result(4) = '1' then error <= '1'; else error <= '0'; end if; end process; end Behavioral;
测试平台代码
entity ALU_Testbench is end ALU_Testbench; architecture tb_arch of ALU_Testbench is -- Signals for testbench signal A_tb, B_tb: unsigned(3 downto 0); signal opcode_tb: bit; signal result_tb: unsigned(3 downto 0); signal error_tb: bit; -- Component declaration component ALU port ( A: in unsigned(3 downto 0); B: in unsigned(3 downto 0); result: out unsigned(3 downto 0); opcode: in bit; error: out bit ); end component; begin uut_instance: ALU port map ( A => A_tb, B => B_tb, opcode => opcode_tb, result => result_tb, error => error_tb ); -- Stimulus process stim_proc: process begin -- Addition test A_tb <= "0011"; B_tb <= "0010"; opcode_tb <= '0'; wait for 10 ns; -- Subtraction test A_tb <= "0011"; B_tb <= "0010"; opcode_tb <= '1'; wait for 10 ns; wait; end process stim_proc; end tb_arch;
波形截图

问题分析与解决
核心问题
代码中temp_result是信号,在进程内使用非阻塞赋值<=时,信号的更新要等到当前进程执行完毕后才会生效。这意味着在当前进程周期中,result和error的赋值使用的是temp_result的旧值(初始为全0),而非刚计算出的新值。比如加法测试时,第一次触发进程计算出temp_result的新值,但result和error用的还是初始0值,要等到下一次进程触发才会更新,导致加法结果延迟异常。
解决方法
把temp_result改为进程内部的变量,使用阻塞赋值:=,这样计算后变量值会立刻更新,后续的result和error赋值能直接用到最新计算结果:
修改后的ALU主代码片段:
architecture Behavioral of ALU is begin process(A, B, opcode) -- 把temp_result改为进程内变量 variable temp_result: unsigned(4 downto 0); begin case opcode is when '0' => temp_result := resize(A, temp_result'length) + resize(B, temp_result'length); when '1' => temp_result := resize(A, temp_result'length) - resize(B, temp_result'length); end case; -- Assign result result <= temp_result(3 downto 0); -- Error output if temp_result(4) = '1' then error <= '1'; else error <= '0'; end if; end process; end Behavioral;
其他验证点
测试平台的端口映射没有问题,减法功能正常也印证了这一点。核心问题就是信号与变量的赋值时序差异导致的结果延迟。
内容的提问来源于stack exchange,提问作者user23793022
相关产品推荐
相关产品推荐

