繁体   English   中英

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

[英]Design 32 bit arithmetic logic unit (ALU)

我为ALU编写此编码器。 该ALU由ctrl信号控制,并执行一些工作,如加,减和或...,当输出为零时,应激活oZero信号。

我在标记行中有一些错误。 我怎么了

module ALU_32 (iA, iB ,iCin ,ctrl, oCarry,oZero, out);    
input [31:0] iA,iB;
output [31:0] out;
input iCin,ctrl;
output oCarry,oZero;
reg [31:0] out;
reg oCarry;
reg oZero;
always@ (ctrl)
    begin 
        case(ctrl)
            4'b0: out<=iA&iB;
            4'b0001: out<=iA|iB;
            4'b0010: {oCarry ,out}<=iA+iB;
            4'b0011: out<=iA~|iB;    //error
            4'b0100: 
            begin 
                if(iA==iB)
                    out<=32'b1;
            end  
            4'b0101: out<=iA-iB;  //error
            4'b0110:    //error
            begin 
                if(iA<iB)
                    out<=32'b1;
                else
                    out<=32'b0;
                end
            4'b0111:   out<=iA*iB;     //error
            4'b1000: out<=iA/iB;        //error

        end
       always@(out)
           begin
               if(out==0)
                   oZero<=1;
               end

      endmodule

~| 您在4'b0011: out<=iA~|iB;使用的运算符4'b0011: out<=iA~|iB; IDE将其视为归约运算符,而不是NOR运算。 为了解决这个问题,您可以使用以下结构:

out <= ~(iA | iB);

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

检查edaplayground以查看那些更改已应用于您的代码。

正如邱指出的那样, iA~|iB应该是~(iA|iB)而您缺少一个endcase 在此之上:

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

    1. 在每种情况下分配输出。 确保在案例陈述中声明了默认条件:

       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. 在案例陈述之前将这些值分配给默认值。 案例陈述将覆盖默认值。

       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);合并always块oZero = (out==0); endcase以下
    • assign oZero = (out==0); // Make sure 'oZero' is a wire (not reg)

其他建议(可选)

  1. ANSI样式标头。 在IEEE Std 1364-2001中添加,并受所有现代模拟器和合成器的支持。 它比IEEE Std 1364-1995的Non-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可能具有预定义的模块,因此请检查数据表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM