设计32位算术逻辑单元(ALU)

时间:2015-05-20 13:20:20

标签: verilog alu

我为ALU编写了这个编码器。此ALU由artisan serve信号控制,并执行一些工作,如加,减,和或......当输出为零时,ctrl信号应处于活动状态。

我在标记的行中有一些错误。我的错是什么?

oZero

2 个答案:

答案 0 :(得分:1)

您在~|中使用的

4'b0011: out<=iA~|iB;运算符被IDE视为简化运算符而不是NOR运算。要解决此问题,您可以使用例如以下构造:

out <= ~(iA | iB);

第二个问题是您忘记在endcase构造的末尾使用case关键字。

选中edaplayground以查看应用于您的代码的更改。

答案 1 :(得分:1)

正如邱指出的那样,iA~|iB应该是~(iA|iB)而你错过了endcase。除此之外:

  1. ctrl需要为4位宽。 IE input [3:0] ctrl
  2. 组合块需要声明灵敏度列表中的所有元素或使用自动灵敏度。使用always @(ctrl)模拟器将不会使用iAiB中的更改。而是使用always @*进行自动感知。您应该始终对组合逻辑使用自动敏感性,除非您仅限于1995年版本的IEEE Std 1364(可能性不大),在这种情况下您需要always @(ctrl or iA or iB or iCin)。自动敏感度(@*@(*))已于2001年添加到标准中。
  3. 您不应将非阻塞分配(<=)与组合逻辑一起使用,使用阻止分配(=)。应使用非阻塞来分配触发器和锁存器。
  4. outoCarry未在每种情况下分配已知值,因此将其推断为锁存器。锁存逻辑设计容易出现时序问题,需要谨慎使用。大多数FPGA的锁存器数量有限,有些则有一些。编码样式的更改可以删除感应锁存器,有两种主要方法可以实现。

    1. 在每种情况下分配输出。确保在case语句中声明了一个默认条件:

      always @* begin
        case(ctrl)
        4'b0000 :
          begin
            out = iA&iB;
            oCarry = 1'b0;
          end
        // conditions assigning both 'out' and 'oCarry'
        default:
          begin
            out = 32'0;
            oCarry = 1'b0;
          end
        endcase
      end
      
    2. 在case语句之前将值分配给默认值。 case语句将覆盖默认值。

      always @* begin
        // default value
        out = 32'd0;
        oCarry = 1'b0;
        // calculate value, override default
        case(ctrl)
          4'b0000 : out = iA&iB;
          // ...
          4'b0010: {oCarry ,out} = iA+iB;
          // ...
          4'b1000: out = iA/iB;
        endcase
      end
      
  5. oZero也是推断锁存器。它只能分配给1,没有0的路径。您可以:

    • always @* oZero = (out==0);
    • 将始终屏蔽与oZero = (out==0);
    • 下方的endcase合并
    • assign oZero = (out==0); // Make sure 'oZero' is a wire (not reg)
  6. 其他建议(可选)

    1. ANSI样式标题。在IEEE Std 1364-2001中添加,并得到所有现代模拟器和合成器的支持。它比IEEE标准1364-1995的非ANSI风格更紧凑。

      module ALU_32 (    
        input [31:0] iA, iB,
        input        iCin,
        input [3:0]  ctrl,
        output reg  oCarry, oZero,
        output reg [31:0] out );
      
    2. 您建议iA*iBiA/iB出现错误。在verilog中,没有任何错误。合成工具可能存在问题,因为32位乘32位乘法器/分频器往往会占用大量资源。您可能需要在单独的模块中管理操作。 FPGA可能有预定义的模块,因此请查看数据表。