67 lines
1.5 KiB
Verilog
67 lines
1.5 KiB
Verilog
|
|
/*
|
|
* Generate a combinational adder of any width. The width parameter can
|
|
* be any integer value >0. The A and B inputs have WID bits, and the Q
|
|
* output has WID+1 bits to include the overflow.
|
|
*/
|
|
module addN
|
|
#(parameter WID = 4)
|
|
(input wire [WID-1:0] A,
|
|
input wire [WID-1:0] B,
|
|
output wire [WID:0] Q
|
|
/* */);
|
|
|
|
wire [WID-1:0] Cout;
|
|
|
|
/* The least significant slice has no Cin */
|
|
add1 U0 (.A(A[0]), .B(B[0]), .Cin(1'b0), .Q(Q[0]), .Cout(Cout[0]));
|
|
|
|
/* Generate all the remaining slices */
|
|
genvar i;
|
|
for (i = 1 ; i < WID ; i = i+1) begin : U
|
|
add1 Un (.A(A[i]), .B(B[i]), .Cin(Cout[i-1]), .Q(Q[i]), .Cout(Cout[i]));
|
|
end
|
|
|
|
assign Q[WID] = Cout[WID-1];
|
|
|
|
endmodule // add
|
|
|
|
/*
|
|
* This is a single-bit combinational adder used by the addH module
|
|
* above.
|
|
*/
|
|
module add1(input A, input B, input Cin, output Q, output Cout);
|
|
|
|
assign Q = A ^ B ^ Cin;
|
|
assign Cout = A&B | A&Cin | B&Cin;
|
|
|
|
endmodule // hadd
|
|
|
|
`ifdef TEST_BENCH
|
|
module main;
|
|
|
|
parameter WID = 4;
|
|
reg [WID-1:0] A, B;
|
|
wire [WID:0] Q;
|
|
|
|
addN #(.WID(WID)) usum (.A(A), .B(B), .Q(Q));
|
|
|
|
int adx;
|
|
int bdx;
|
|
initial begin
|
|
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
|
|
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
|
|
A <= adx[WID-1:0];
|
|
B <= bdx[WID-1:0];
|
|
#1 if (Q !== (adx+bdx)) begin
|
|
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
|
|
$finish;
|
|
end
|
|
end
|
|
end
|
|
$display("PASSED");
|
|
end
|
|
|
|
endmodule // main
|
|
`endif
|