【问题标题】:Carry output issue during VHDL ALU synthesisVHDL ALU 综合期间的进位输出问题
【发布时间】:2013-09-26 23:02:48
【问题描述】:

我正在尝试用 VHDL 构建和综合 ALU,但我一综合就遇到了问题。 我希望我的 ALU 有一个操作码,用于添加我的两个 N 位输入和一个进位,该进位可以由输入或之前计算的总和设置。 我感兴趣的部分代码如下:

process (a, b, op) -- a and b are n bits input en op is the op-code
    case op is
        when "011" => -- add a + b + c (with c as carry)
            y <= ('0' & a) + ('0' & b) + c; -- y is the N-bit output
...
end process;

process (clk)
   if (clk'event and clk = '1') then
       if (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) > (2**N)) then --basically I'm testing if there is an overflow during the calculation
           c <= '1';
       elsif (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) < ((2**N)+1))
           c <= '0';
...
end process;

我不确定代码是否可以在这里工作,因为我没有定义信号类型,但基本上它归结为我上面写的。 这样做的问题是,当我使用适当的测试平台模拟我的 VHDL 时,它可以正常工作,但是当我合成此代码并使用相同的测试平台模拟合成代码时,它无法正常工作,因为不知何故第一个过程是即使 a、b 或 op 没有改变,也会再次重复。所以当总和的结果有进位时,用这个新的进位再次进行计算,即使 a、b 或 op 没有改变,结果也会加 1!

后来我发现这篇文章说that the sensitivity list is "ignored" by the compiler 认为他比你更了解该程序并制作了自己的敏感度列表。如果这是真的,我会在第一个进程的敏感度列表中添加 clk,以便在 op = "011" 时在每个 clk 周期运行计算。

现在我的问题来了:我该如何解决这个问题,以便计算运行一次,然后改变进位?

亲切的问候

【问题讨论】:

  • 停止编写代码。先画一张图。编码你的图片。你打算连接执行携带吗?
  • 你能澄清一下你说I'd like my ALU to have a op-code for adding my two N-bits inputs and a carry that may be set by an input or by a sum that was calculated earlier.的意思吗?看来你在carryincarryout之间感到困惑。通常这是两个不同的东西。为什么要将加法器(carryout)生成的进位再次添加到输入数字中?

标签: compiler-construction vhdl addition synthesis alu


【解决方案1】:

正如其他人所指出的,您的代码存在一些问题。我将尝试提出一些改进建议,然后展示一种计算进位标志的可能方法:

  1. 区分进位信号和进位信号。为您的信号使用交流名称,例如 carry_incarry_out。这将消除大部分混乱。

  2. 为您的 ALU 运算定义一个常量或枚举类型。例如:

    subtype opcode_type is std_logic_vector(2 downto 0);
    constant ADC: opcode_type := "011";  -- ADC: add with carry
    
  3. 最后,如果您使用的是 VHDL 2008,您可以使用聚合作为分配目标来生成您的执行:

    (carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
    

您的代码最终将如下所示:

process (all)
    case op is
        when ADC => -- add a + b + c (with c as carry)
            (carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
    ...
end process;

process (clk)
    if rising_edge(clk) then
        carry_flag <= carry_out;
    ...
end process;

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多