我正在开发一个项目,该项目将采用 0-9 之间的两个 4 位数字并对它们进行加/减操作以显示在七段显示器中。
我的纹波进位加法器/减法器代码:
module full_adder(
input A, B, C,
output F, G
);
assign F = A^B^C; // boolean algebra for sum
assign G = (A&B)|(B&C)|(A&C); // boolean algebra for carry
endmodule
module ripple_carry_adder(
input [3:0] A, B,
input C,
output [4:0] S
);
wire W3, W2, W1, W0;
full_adder U0(.A(A[0]), .B(B[0]^C), .C(C), .F(S[0]), .G(W0));
full_adder U1(.A(A[1]), .B(B[1]^C), .C(W0), .F(S[1]), .G(W1));
full_adder U2(.A(A[2]), .B(B[2]^C), .C(W1), .F(S[2]), .G(W2));
full_adder U3(.A(A[3]), .B(B[3]^C), .C(W2), .F(S[3]), .G(W3));
endmodule
我的5位解码器代码:
module decoder_5bits(
input [4:0] sum,
output reg [3:0] tens, ones
);
always @(sum)
begin
case(sum)
5'b10111: // -9
begin
tens = 4'b1011;
ones = 4'b1001;
end
5'b11000: // -8
begin
tens = 4'b1011;
ones = 4'b1000;
end
5'b11001: // -7
begin
tens = 4'b1011;
ones = 4'b0111;
end
5'b11010: // -6
begin
tens = 4'b1011;
ones = 4'b0110;
end
5'b11011: // -5
begin
tens = 4'b1011;
ones = 4'b0101;
end
5'b11100: // -4
begin
tens = 4'b1011;
ones = 4'b0100;
end
5'b11101: // -3
begin
tens = 4'b1011;
ones = 4'b0011;
end
5'b11110: // -2
begin
tens = 4'b1011;
ones = 4'b0010;
end
5'b11111: // -1
begin
tens = 4'b1011;
ones = 4'b0001;
end
5'b00000: // 0
begin
tens = 4'b0000;
ones = 4'b0000;
end
5'b00001: // 1
begin
tens = 4'b0000;
ones = 4'b0001;
end
5'b00010: // 2
begin
tens = 4'b0000;
ones = 4'b0010;
end
5'b00011: // 3
begin
tens = 4'b0000;
ones = 4'b0011;
end
5'b00100: // 4
begin
tens = 4'b0000;
ones = 4'b0100;
end
5'b00101: // 5
begin
tens = 4'b0000;
ones = 4'b0101;
end
5'b00110: // 6
begin
tens = 4'b0000;
ones = 4'b0110;
end
5'b00111: // 7
begin
tens = 4'b0000;
ones = 4'b0111;
end
5'b01000: // 8
begin
tens = 4'b0000;
ones = 4'b1000;
end
5'b01001: // 9
begin
tens = 4'b0000;
ones = 4'b1001;
end
5'b01010: // 10
begin
tens = 4'b1010;
ones = 4'b0000;
end
5'b01011: // 11
begin
tens = 4'b1010;
ones = 4'b0001;
end
5'b01100: // 12
begin
tens = 4'b1010;
ones = 4'b0010;
end
5'b01101: // 13
begin
tens = 4'b1010;
ones = 4'b0011;
end
5'b01110: // 14
begin
tens = 4'b1010;
ones = 4'b0100;
end
5'b01111: // 15
begin
tens = 4'b1010;
ones = 4'b0101;
end
5'b10000: // 16
begin
tens = 4'b1010;
ones = 4'b0110;
end
5'b10001: // 17
begin
tens = 4'b1010;
ones = 4'b0111;
end
5'b10010: // 18
begin
tens = 4'b1010;
ones = 4'b1000;
end
default:
begin
tens = 4'b1111;
ones = 4'b1111;
end
endcase
end
endmodule
当我创建整个项目的波形时,我似乎被纹波进位加法器和 5 位解码器所吸引。 5 位输出似乎没有像应有的那样解释溢出。我假设这就是我出错的地方。
这是一个带有测试平台的最小可重现示例:
module full_adder(
input A, B, C,
output F, G
);
assign F = A^B^C; // boolean algebra for sum
assign G = (A&B)|(B&C)|(A&C); // boolean algebra for carry
endmodule
module ripple_carry_adder(
input [3:0] A, B,
input C,
output [4:0] S
);
wire W3, W2, W1, W0;
full_adder U0(.A(A[0]), .B(B[0]^C), .C(C), .F(S[0]), .G(W0));
full_adder U1(.A(A[1]), .B(B[1]^C), .C(W0), .F(S[1]), .G(W1));
full_adder U2(.A(A[2]), .B(B[2]^C), .C(W1), .F(S[2]), .G(W2));
full_adder U3(.A(A[3]), .B(B[3]^C), .C(W2), .F(S[3]), .G(W3));
endmodule
module decoder_5bits(
input [4:0] sum,
output reg [3:0] tens, ones
);
always @(sum)
begin
case(sum)
5'b11111: // -1
begin
tens = 4'b1011;
ones = 4'b0001;
end
5'b00000: // 0
begin
tens = 4'b0000;
ones = 4'b0000;
end
5'b00001: // 1
begin
tens = 4'b0000;
ones = 4'b0001;
end
5'b10010: // 18
begin
tens = 4'b1010;
ones = 4'b1000;
end
default:
begin
tens = 4'b1111;
ones = 4'b1111;
end
endcase
end
endmodule
module top(
input [3:0] A, B,
input C,
output [3:0] tens, ones
);
wire [4:0] SUM;
ripple_carry_adder U1(
.A (A),
.B (B),
.C (C),
.S (SUM)
);
decoder_5bits U2(
.sum (SUM),
.tens (tens),
.ones (ones)
);
endmodule
module testbench;
reg C;
reg [3:0] A, B;
wire [3:0] tens, ones;
top UUT(A, B, C, tens, ones);
initial begin
$dumpfile("MRE.vcd");
$dumpvars(0, testbench);
A = 4'b1001; B = 4'b1001; C = 0; #10
A = 4'b0001; B = 4'b0010; C = 1; #10
A = 4'b0000; B = 4'b1001; C = 1; #10
$finish;
end
endmodule
从波形输出中可以看出,每当我加到两位数或减到负数时,我都会遇到纹波进位加法器/减法器的 5 位输出问题。
正如您在波形中看到的,位
SUM[4]
是 z
,这意味着它未被驱动。您可以追溯到 ripple_carry_adder
,其中 S[4]
也未驱动,因为您没有连接到它。
没有理由使用任何比 Verilog 中的加法器的单行代码更复杂的模式:
module ripple_carry_adder(
input [3:0] A, B,
input C,
output [4:0] S
);
assign S = A + B + C;
endmodule
这消除了未驱动的
z
值。