Option C: Carry Select Adder
The Carry Select Adder trades extra hardware for reduced waiting on part of the carry path. The upper half computes both possible answers in advance and selects the correct one when the lower-half carry arrives.
Overview
Split the 8-bit addition into two four-bit halves.
The lower half computes normally:
bits 3:0
At the same time, the upper half computes twice:
bits 7:4 assuming carry-in = 0
bits 7:4 assuming carry-in = 1
When the lower-half carry is finally known, a mux selects the correct upper result.
Conceptually:
+--> upper add, cin=0 --+
lower add --> carry ---| |--> mux --> final upper sum
+--> upper add, cin=1 --+
Prerequisites
- ALU specification
- Ripple Carry Adder concept
- multiplexers
Steps
1. Create a four-bit Ripple Carry helper
Create rtl/adder8.v.
module rca4 (
input wire [3:0] a,
input wire [3:0] b,
input wire cin,
output wire [3:0] sum,
output wire cout
);
wire [4:0] c;
assign c[0] = cin;
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : GEN_FA
assign sum[i] = a[i] ^ b[i] ^ c[i];
assign c[i+1] =
(a[i] & b[i]) |
(a[i] & c[i]) |
(b[i] & c[i]);
end
endgenerate
assign cout = c[4];
endmodule
2. Compute the upper half twice
Add the top-level module below it:
module adder8 (
input wire [7:0] a,
input wire [7:0] b,
input wire cin,
output wire [7:0] sum,
output wire cout
);
wire [3:0] sum_low;
wire carry_low;
wire [3:0] sum_high_0;
wire [3:0] sum_high_1;
wire carry_high_0;
wire carry_high_1;
rca4 u_low (
.a (a[3:0]),
.b (b[3:0]),
.cin (cin),
.sum (sum_low),
.cout (carry_low)
);
rca4 u_high_if_0 (
.a (a[7:4]),
.b (b[7:4]),
.cin (1'b0),
.sum (sum_high_0),
.cout (carry_high_0)
);
rca4 u_high_if_1 (
.a (a[7:4]),
.b (b[7:4]),
.cin (1'b1),
.sum (sum_high_1),
.cout (carry_high_1)
);
assign sum[3:0] = sum_low;
assign sum[7:4] =
carry_low ? sum_high_1 : sum_high_0;
assign cout =
carry_low ? carry_high_1 : carry_high_0;
endmodule
3. Understand the tradeoff
The upper arithmetic is duplicated.
That means the source design contains more logic than a simple ripple structure, but the upper half does not need to wait before beginning its arithmetic.
The final selection still waits for carry_low.
4. Add it to the ALU
Your files should now be:
rtl/
├── adder8.v
├── alu_core.v
└── alu_top.v
5. Continue to the common flow
You are done with the adder branch.
Continue to Verify the complete ALU — page 7.
Results
Later, inspect whether the duplicated structure survives synthesis and how Vivado maps it to FPGA resources.
Do not assume source-code area equals physical area. Synthesis can remove, merge, or transform logic.
Checklist
-
Created the
rca4helper - Computed both upper-half carry cases
- Added the output mux
-
Did not use
a + binside the adder -
Connected the adder to
alu_core - Continued to page 7
Questions? Ask in the network Discord.