I am trying to create a 4-bit ripple carry adder using 4 full adders each comprised of two half-adders. This is the code for my half-adder:
module HA (input a, b,
output reg cout,
output reg sum);
reg [1:0] temp;
always @ (a or b) begin
temp = a + b;
#2 cout = temp[1];
#1 sum = temp[0];
end
endmodule
I have written a test bench for the half adder and it works as expected. This is the code for my full adder:
module FA(input a, b, cin,
output cout, sum);
wire c1, c2;
wire s;
HA h0 (.a(a), .b(b), .cout(c1), .sum(s));
HA h1 (.a(s), .b(cin), .cout(c2), .sum(sum));
or o1 (cout, c1, c2);
endmodule
The full adder also has a test bench that shows it works as expected.
Now this is the code for my ripple adder:
module PAdder(input [3:0] a,
input [3:0] b,
input cin,
output [3:0] sum,
output cout);
wire [2:0] c;
FA f0 (a[0], b[0], cin, c[0], sum[0]);
FA f1 (a[1], b[1], c[0], c[1], sum[1]);
FA f2 (a[2], b[2], c[1], c[2], sum[2]);
FA f3 (a[3], b[3], c[2], cout, sum[3]);
endmodule
But when I run a testbench on this one, I get queer results! This is the waveform of trying to add 0 and 0 with cin
=0:
I found that the second half adder of the second full adder (f1/h1) is the first half adder malfunctioning. I included its signals in the waveform and this is the result:
Note how at time 5ns, both the a
and b
input of h1
are non-X (both are 0) but still its output, or the temp register inside it, remain X-valued. Why does the always block of the HA
not run to update temp
to be 0 + 0 which is [0, 0]?
I tried recompiling and redoing the waveforms, but I kept getting the same results.
Here is the testbench:
module PAddertb;
reg [3:0] a;
reg [3:0] b;
reg cin;
wire [3:0] sum;
wire cout;
integer i;
PAdder p0(a, b, cin, sum, cout);
initial begin
$monitor("a=%d(%0b) b=%d(%0b) cin=%0b cout=%0b sum=%d(%0b)", a, a, b, b, cin, cout, sum, sum);
for (i = 0; i < 1; i = i + 1) begin
{a, b, cin} = i;
#20;
end
end
endmodule