combinational component
Carry-Lookahead Adder
An 8-bit adder that computes every carry directly instead of waiting for a ripple. Each bit pair first produces two flags. Generate (g = a and b) means the column creates a carry on its own. Propagate (p = a xor b) means it passes an incoming carry along.
Every carry is then a flat AND-OR expression over the flags below it. Bits 0 to 3 form one lookahead group with a group generate and a group propagate. Bits 4 to 7 form a second group, seeded by the first group's carry. Both group flags are exposed as 2-bit outputs, gg and gp, with bit 0 for the low group and bit 1 for the high group. Two gate levels per group replace an eight-stage ripple chain, so the delay stays nearly constant as the width grows. The sum is one final XOR of the propagate vector with the carry vector.
In the waveform: the third 10 ns step drives a = 0xFF, b = 0x00, cin = 1. Every column merely propagates, yet sum snaps to 0x00 and cout to 1 in a single step. Watch the flags agree: gp reads 11 because both groups pass the carry along, and gg stays 00 because neither creates one. There is no ripple to watch, and that is the point.
In the netlist: find the AND-OR trees feeding the group carries. Their product terms widen from one input to four, which is the lookahead equation laid out in gates.
The course builds adders from first principles, gate by gate, in Arithmetic Circuits.
-- 8-bit carry-lookahead adder: generate/propagate flags per bit, two 4-bit
-- lookahead groups, every carry a flat AND-OR expression instead of a ripple
library ieee;
use ieee.std_logic_1164.all;
entity carry_lookahead_adder is
port (
a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
cin : in std_logic;
sum : out std_logic_vector(7 downto 0);
cout : out std_logic;
gg : out std_logic_vector(1 downto 0); -- group generate: bit 0 = bits 3..0, bit 1 = bits 7..4
gp : out std_logic_vector(1 downto 0) -- group propagate, same split
);
end entity carry_lookahead_adder;
architecture rtl of carry_lookahead_adder is
signal g, p : std_logic_vector(7 downto 0); -- bit generate / propagate
signal c : std_logic_vector(7 downto 0); -- carry INTO each bit
begin
-- A column generates a carry when both inputs are 1, and propagates an
-- incoming carry when exactly one is
g <= a and b;
p <= a xor b;
-- Group 0 (bits 3..0): each carry expanded over the flags below it
c(0) <= cin;
c(1) <= g(0) or (p(0) and cin);
c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and cin);
c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
or (p(2) and p(1) and p(0) and cin);
gg(0) <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
or (p(3) and p(2) and p(1) and g(0));
gp(0) <= p(3) and p(2) and p(1) and p(0);
c(4) <= gg(0) or (gp(0) and cin);
-- Group 1 (bits 7..4): the same shape, seeded by the group-0 carry
c(5) <= g(4) or (p(4) and c(4));
c(6) <= g(5) or (p(5) and g(4)) or (p(5) and p(4) and c(4));
c(7) <= g(6) or (p(6) and g(5)) or (p(6) and p(5) and g(4))
or (p(6) and p(5) and p(4) and c(4));
gg(1) <= g(7) or (p(7) and g(6)) or (p(7) and p(6) and g(5))
or (p(7) and p(6) and p(5) and g(4));
gp(1) <= p(7) and p(6) and p(5) and p(4);
cout <= gg(1) or (gp(1) and c(4));
-- The sum is one final XOR of propagate with the carry vector
sum <= p xor c;
end architecture rtl;