I am working on a project that will take two 4-bit numbers between 0-9 and add/subtract them to be displayed in a seven segment display. Here is a big picture idea of what I am trying to create
My ripple carry adder/subtractor code:
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
My 5-bit Decoder code:
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
When I create a waveform of my whole project, I seem to be caught up at the ripple carry adder and 5-bit decoder. The 5-bit output does not seem to account for the overflow like it should. I am assuming this is where I am going wrong.
Here is the waveform output if that helps.
Here is a minimal reproducible example with a testbench:
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
As seen in the waveform output, any time I add up to a double digit number or subtract to a negative number, I run into issues with the 5-bit output from the ripple-carry adder/subtractor.

As you can see in your waveforms, bit
SUM[4]isz, which means it is undriven. You can trace that back toripple_carry_adder, whereS[4]is also undriven because you did not connect to it.There is never a reason to use anything more complicated than a single line of code for an adder in Verilog:
This gets rid of the undriven
zvalue.