[英]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
。 在此之上:
ctrl
需要为4位宽。 IE input [3:0] ctrl
always @(ctrl)
,模拟器将不会使用iA
或iB
see更改。 而是always @*
使用always @*
进行自动敏感。 除非限于1995年版的IEEE Std 1364(可能不是,否则),否则应始终对组合逻辑使用自动敏感度(在这种情况下,不是),在这种情况下,您always @(ctrl or iA or iB or iCin)
需要always @(ctrl or iA or iB or iCin)
。 自敏感度( @*
或@(*)
)已于2001年添加到标准中。 <=
)与组合逻辑一起使用,而应使用阻塞分配( =
)。 非阻塞应用于分配触发器和锁存器。 在所有情况下, out
和oCarry
均未分配已知值,因此将其推断为闩锁。 锁存器逻辑设计易于出现时序问题,需要谨慎使用。 大多数FPGA的锁存器数量有限,有些则有些。 更改编码样式可以删除推断出的闩锁,主要有两种方法。
在每种情况下分配输出。 确保在案例陈述中声明了默认条件:
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
在案例陈述之前将这些值分配给默认值。 案例陈述将覆盖默认值。
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
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)
其他建议(可选)
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 );
您建议在那里iA*iB
和iA/iB
出现错误。 在verilog中,没有任何错误。 综合工具可能会出现问题,因为32位乘32位乘法器/除法器往往会占用大量资源。 您可能需要在单独的模块中管道化操作。 FPGA可能具有预定义的模块,因此请检查数据表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.