source
import xor "<builtin>/xor.circ"
import or "<builtin>/or.circ"
// Four-bit operands and a four-bit sum, plus the carry that falls off the top.
input[4] a, b
// A bus has to be taken apart to reach a single lane. Each slice goes
// through a wire, which is what gives the lane a name to wire from.
wire a0(in=a[0])
wire a1(in=a[1])
wire a2(in=a[2])
wire a3(in=a[3])
wire b0(in=b[0])
wire b1(in=b[1])
wire b2(in=b[2])
wire b3(in=b[3])
// Bit 0 is a half adder: nothing carries into it.
xor s0(a=a0.out, b=b0.out)
and c0(a=a0.out, b=b0.out)
// Bits 1 to 3 are full adders, each fed by the carry below it. Every one is
// the same five gates: propagate, sum, generate, this bit's carry, and the
// or that lets either source of a carry through.
xor p1(a=a1.out, b=b1.out)
xor s1(a=p1.out, b=c0.out)
and g1(a=a1.out, b=b1.out)
and t1(a=p1.out, b=c0.out)
or c1(a=g1.out, b=t1.out)
xor p2(a=a2.out, b=b2.out)
xor s2(a=p2.out, b=c1.out)
and g2(a=a2.out, b=b2.out)
and t2(a=p2.out, b=c1.out)
or c2(a=g2.out, b=t2.out)
xor p3(a=a3.out, b=b3.out)
xor s3(a=p3.out, b=c2.out)
and g3(a=a3.out, b=b3.out)
and t3(a=p3.out, b=c2.out)
or c3(a=g3.out, b=t3.out)
// Low bit first, which is how a concat reads.
output[4] s(in={s0.out, s1.out, s2.out, s3.out})
output cout(in=c3.out)
circ-compile --preview
╭──────╮ ╭───╮
│ a[4] ├●●──▶┤ │
╰──────╯ │ │AND├○─────╮
│╭─▶┤ │ │
╭──────╮ ││ ╰───╯ │
│ b[4] ├●┼╯ │
╰──────╯ ││ ╭────────╮ │
●┼─▶┤ │ │
││ │[xor:s0]├ │
│●─▶┤ │ │
││ ╰────────╯ │
││ │
││ ╭───╮ │
●┼─▶┤ │ │
││ │AND├○─────┼╮
│●─▶┤ │ ││
││ ╰───╯ ││
││ ││
││ ╭────────╮ ││
●┼─▶┤ │ ││ ╭────────╮
││ │[xor:p3]├○┼┼●──────────────────────────────────────────────────────────▶┤ │ ╭──────╮
│●─▶┤ │ ╰┼┼────────────────────────────────────────────────────────╮ │[xor:s3]├○─────────────────▶┤ s[4] │
││ ╰────────╯ ╰┼─────────────────────────────────────────╮ ╭───────╮ ╭┼─▶┤ │ ╰──────╯
││ │ ╰──▶┤ │ ││ ╰────────╯ ╭───────╮
││ ╭───╮ │ │[or:c2]├○╮╰────────────────▶┤ │ ╭──────╮
●┼─▶┤ │ │ ╭──▶┤ │ │ │[or:c3]├○───▶┤ cout │
││ │AND├○─────╮ │ │ ╰───────╯ │ ╭──▶┤ │ ╰──────╯
│●─▶┤ │ │ │ │ │ │ ╰───────╯
││ ╰───╯ │ │ │ │ │
││ │ │ │ │ │
││ ╭────────╮ │ │ │ │ │
●┼─▶┤ │ │ │ ╭───╮ │ │ │
││ │[xor:p2]├○┼●┼─────────────────────────────▶┤ │ │ │ │
│●─▶┤ │ ││╰───────────────────────────╮ │AND├○─────╯ │ │
││ ╰────────╯ ╰┼───────────────╮ ╭───────╮ ╭┼─▶┤ │ │ │
││ ╰──────────────╮╰▶┤ │ ││ ╰───╯ │ ╭───╮ │
││ ╭────────╮ │ │[or:c1]├○╯╰───────────────────────────┼──▶┤ │ │
●┼─▶┤ │ ╭───╮ ╭┼─▶┤ │ │ │ │AND├○─────╯
││ │[xor:p1]├○─●─▶┤ │ ││ ╰───────╯ │ ╭────────╮ ╰──▶┤ │
│●─▶┤ │ │ │AND├○─────╯╰────────────┼──▶┤ │ ╰───╯
││ ╰────────╯ ╭┼─▶┤ │ │ │[xor:s2]├
││ ││ ╰───╯ ╰──▶┤ │
││ ╭───╮ ││ ╰────────╯
╰┼─▶┤ │ ││ ╭────────╮
│ │AND├○─────╯╰─▶┤ │
╰─▶┤ │ │ │[xor:s1]├
╰───╯ ╰──▶┤ │
╰────────╯