Reputation: 795
I am testing the functionality of an 8-bit Ripple Carry Adder with a testbench that tries every single combination. For some reason, the sum of the current values of A and B is computed in the next clock cycle. I am not sure why that is happening. Initially, I assumed it was because of the delays, but the error still occurs when I change the delays. Here is my code:
//one_adder.v
module One_adder(a,b,cin,sum,carry);
output carry,sum;
input a,b,cin;
wire w0,w1,w2;
xor(sum,a,b,cin);
and(w0,a,b);
and(w1,a,cin);
and(w2,cin,b);
or(carry,w0,w1,w2);
endmodule;
//Eight_adder.v
module Eight_adder(A,B,S,Carry);
output [7:0]S, Carry;
input [7:0]A, B;
//wire [7:0]w;
wire overflow;
One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(Carry[0]));
One_adder add1(.carry(Carry[1]), .sum(S[1]), .a(A[1]), .b(B[1]), .cin(Carry[1]));
One_adder add2(.carry(Carry[2]), .sum(S[2]), .a(A[2]), .b(B[2]), .cin(Carry[2]));
One_adder add3(.carry(Carry[3]), .sum(S[3]), .a(A[3]), .b(B[3]), .cin(Carry[3]));
One_adder add4(.carry(Carry[4]), .sum(S[4]), .a(A[4]), .b(B[4]), .cin(Carry[4]));
One_adder add5(.carry(Carry[5]), .sum(S[5]), .a(A[5]), .b(B[5]), .cin(Carry[5]));
One_adder add6(.carry(Carry[6]), .sum(S[6]), .a(A[6]), .b(B[6]), .cin(Carry[6]));
One_adder add7(.carry(Carry[7]), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7]));
assign overflow= (A[7]&B[7]&~Carry[7]) | (~A[7]&~B[7]&Carry[7]);
endmodule
//tBench.v
//`timescale 1 ns/ 1 ns
module tBench;
wire [7:0]sum;
wire cin, co;
reg[7:0] A, B; // the different combinations
//module Eight_adder(A,B,Cin,S,Cout);
Eight_adder FA(A,B,sum,co);
initial begin
for(A =0; A<255; A=A+1)
begin
#10 // the period in ModelSim: 10ns
for(B=0; B<255; B=B+1)
begin
$display("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum});
#10
if({co,sum} != (A+B))
$display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co);
end
end
$finish;
end
endmodule
Upvotes: 1
Views: 1417
Reputation: 19112
I'm surprised you are not getting only Xs for your sum output. You have the carry-out bit feedback back the the carry-in of the same adder. There should be an offset so the carry-out of one adder is the carry-in of another adder.
One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(1'b0));
...
One_adder add7(.carry(carryout), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7]));
As for your display message, your {co,sum}
is being updated in the same time-stamp as A
and B
. The verilog scheduler is evaluating the $display
before there is an opportunity to calculate anything. You can either add a delay before the $display
(like you did with your error checking), replace $display
with $strobe
, or use $monitor
before the looping. (You may want to read display vs strobe vs monitor in verilog?)
Upvotes: 1
Reputation: 62164
You are computing the sum in the correct cycle, but you are displaying it at a different time. Move the $display
to a $monitor
as follows:
initial begin
$monitor("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum});
for(A =0; A<255; A=A+1)
begin
#10 // the period in ModelSim: 10ns
for(B=0; B<255; B=B+1)
begin
#10
if({co,sum} != (A+B))
$display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co);
end
end
$finish;
end
Upvotes: 1