我在设计我的 ALU 时发现了一个非常奇怪的行为,希望有人可以看看它并告诉我发生了什么。
这是代码
module adder (
output logic signed[31:0] y,
output logic Cout,
input logic signed[31:0] a, b,
input logic Cin, sub
);
logic [31:0] adder_b;
assign adder_b = b ^ {32{sub}};
assign {Cout, y} = {a[31],a} + {adder_b[31],adder_b} +Cin;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module andlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a & b;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module orlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a | b;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module xorlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a ^ b;
endmodule
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
module ALU(
output logic signed[31:0] Result,
output logic N,Z,C,V,
input logic signed[31:0] a, b,
input logic [2:0] ALU_control
);
wire [31:0] adder_rlt, and_rlt, or_rlt, xor_rlt;
logic Cin;
adder adder (
.y (adder_rlt),
.a (a),
.b (b),
.Cin (Cin),
.Cout (Cout),
.sub (sub)
);
andlogic andlogic (
.y (and_rlt),
.a (a),
.b (b)
);
orlogic orlogic (
.y (or_rlt),
.a (a),
.b (b)
);
xorlogic xorlogic (
.y (xor_rlt),
.a (a),
.b (b)
);
assign C = Cout;
assign sub = ALU_control[1];
assign Cin = ALU_control[1];
assign N = Result[31];
//assign Z = (Result ==0 )? 1:0;
assign V = {{~a[31]} & {~b[31]} & Result[31]}|{a[31] & b[31] & {~Result[31]}};
always_comb
begin
if (Result == 0) Z = 1;
else Z = 0;
case(ALU_control)
3'b001: Result = adder_rlt;
3'b010: Result = adder_rlt;
3'b011: Result = and_rlt;
3'b100: Result = or_rlt;
3'b101: Result = xor_rlt;
default: Result = 0;
endcase
end
endmodule
前 4 个模块是我的 ALU 的各个功能,加法器包含加法和减法。然后这是奇怪的事情:
我的 ALU 有 4 个标志,Z 代表零,它在输出Result
值为 0 时设置。如果我用这些代码来描述 Z 的行为
always_comb
begin
if (Result == 0) Z = 1;
else Z = 0;
模拟结果是错误的,Z有的时候是1,有的时候是0,看起来完全不依赖于的值Result
。
更奇怪的是合成结果的结果。这里的图片显示了我的 synplify 合成结果的一部分。
门电平看起来是正确的,Z 是所有反转 Result 信号的与门,当 Result == 0 时,输出 Z 应该是 1。
但是,我昨天整个下午都在试图弄清楚如何修复这个错误,我发现如果我使用assign
语句而不是使用if
语句,那么模拟会给出正确的行为。assign Z = (Result ==0 )? 1:0;
我认为这两个版本的描述 Z 应该是相同的!在我使用修改我的代码之后
assign Z = (Result ==0 )? 1:0;
合成结果还是和我上图一样……
有人可以告诉我发生了什么吗?非常感谢!!!