You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

波形截图

Waveform screenshot

问题分析与解决

核心问题

代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:14:54