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

4位移位相加乘法器在Vivado仿真中陷入无限循环的问题

4位移位相加乘法器仿真无限循环的问题分析与修复

你的代码存在几个核心的VHDL行为模型错误,直接导致了while循环无法终止,具体问题和修复方案如下:


问题根源

  1. 信号赋值的非即时性
    VHDL中进程内的信号赋值(<=)不会立即生效,所有赋值操作都会在整个进程执行完毕后才统一更新。你在while循环里对N、B、Q的赋值,在循环运行期间这些信号的当前值完全不会改变——N始终保持初始值4,所以N>0的循环条件永远成立,直接陷入死循环。

  2. 组合逻辑建模的逻辑错误
    移位相加乘法是多步迭代的时序逻辑,需要时钟驱动完成每一步的移位和相加操作,但你用了组合逻辑进程来实现。组合逻辑进程会在敏感列表中任意信号变化时反复执行,再加上错误的循环写法,必然导致仿真异常。

  3. 信号初始化与重复触发的冲突
    你将N声明为带初始值的信号并加入敏感列表,同时每次进程触发时都会重新把B、Q赋值为输入x、y的扩展值,相当于每次循环都重置了迭代的起始状态,完全违背了移位相加的迭代逻辑。


修复后的代码(时序逻辑实现)

改用时钟驱动的时序逻辑实现,用寄存器存储迭代状态,避免组合循环的死循环问题:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity four_bit_multiplier is
  Port ( 
    clk : in STD_LOGIC;
    rst_n : in STD_LOGIC;  -- 低有效复位信号
    x : in STD_LOGIC_VECTOR(3 downto 0);
    y : in STD_LOGIC_VECTOR(3 downto 0);
    result : out STD_LOGIC_VECTOR(7 downto 0);
    done : out STD_LOGIC   -- 乘法完成标志
  );
end four_bit_multiplier;

architecture Behavioral of four_bit_multiplier is

component eight_bit_adder is
  Port (
    x : in STD_LOGIC_VECTOR(7 downto 0);
    y : in STD_LOGIC_VECTOR(7 downto 0);
    c_in: in STD_LOGIC;
    c_out: out STD_LOGIC;
    sum : out STD_LOGIC_VECTOR(7 downto 0) 
  );
end component;

signal B_reg : STD_LOGIC_VECTOR(7 downto 0);
signal A_reg : STD_LOGIC_VECTOR(7 downto 0);
signal Q_reg : STD_LOGIC_VECTOR(7 downto 0);
signal adder_out : STD_LOGIC_VECTOR(7 downto 0);
signal c_out : STD_LOGIC;
signal count : integer range 0 to 4;  -- 迭代计数器

begin

p1: eight_bit_adder port map(B_reg, A_reg, '0', c_out, adder_out);

-- 时序进程:完成移位相加迭代
process(clk, rst_n)
begin
  if rst_n = '0' then
    A_reg <= (others => '0');
    B_reg <= (others => '0');
    Q_reg <= (others => '0');
    count <= 4;
    done <= '0';
    result <= (others => '0');
  elsif rising_edge(clk) then
    if count > 0 then
      -- 判断Q最低位,决定是否累加
      if Q_reg(0) = '1' then
        A_reg <= adder_out;
      end if;
      -- 执行移位操作
      B_reg <= B_reg(6 downto 0) & '0';
      Q_reg <= '0' & Q_reg(7 downto 1);
      -- 计数器递减
      count <= count - 1;
    else
      -- 迭代完成,输出结果
      result <= A_reg;
      done <= '1';
    end if;
  end if;
end process;

-- 输入加载进程:复位或迭代完成时重新加载输入
process(clk, rst_n)
begin
  if rst_n = '0' then
    B_reg <= "0000" & x;
    Q_reg <= "0000" & y;
  elsif rising_edge(clk) then
    if count = 0 then
      B_reg <= "0000" & x;
      Q_reg <= "0000" & y;
      count <= 4;
      done <= '0';
    end if;
  end if;
end process;

end Behavioral;

关键修复说明

  • 改用时钟+复位的时序逻辑实现,符合数字电路的实际工作方式;
  • 用寄存器信号(A_reg、B_reg、Q_reg)存储每一步的迭代状态,在时钟沿更新;
  • 用count计数器控制迭代次数,每次时钟沿递减,彻底避免组合循环的死循环问题;
  • 添加done标志位,方便测试bench判断乘法运算是否完成。

内容的提问来源于stack exchange,提问作者Kudor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:38:18