Level 5 — MasteryCombinational Circuits

Combinational Circuits

90 minutes60 marksprintable — key stays hidden on paper

Time limit: 90 minutes Total marks: 60 Instructions: Answer all three questions. Show all working, derivations, and truth tables. Coding may be in pseudocode or any HDL-like syntax. Marks are indicated per part.


Question 1 — Carry-Lookahead Adder: Derivation, Delay Proof, and Code (22 marks)

A carry-lookahead adder (CLA) uses generate gi=aibig_i = a_i \, b_i and propagate pi=aibip_i = a_i \oplus b_i signals.

(a) Starting from the full-adder carry recurrence ci+1=gi+picic_{i+1} = g_i + p_i\, c_i, prove by expansion that

ci+1=gi+pigi1+pipi1gi2++(k=0ipk)c0.c_{i+1} = g_i + p_i g_{i-1} + p_i p_{i-1} g_{i-2} + \cdots + \left(\prod_{k=0}^{i} p_k\right) c_0.

State the general closed-form for ci+1c_{i+1} using product/sum notation. (6 marks)

(b) Assume every gate has delay τ\tau and unlimited fan-in. Give the propagation delay (in units of τ\tau) to produce all carry signals c1cnc_1 \ldots c_n in a flat nn-bit CLA, and compare it against an nn-bit ripple-carry adder. State the asymptotic complexity of each. (5 marks)

(c) A practical 16-bit adder is built from four 4-bit CLA blocks connected in ripple fashion (block-carry rippled, intra-block lookahead). Derive the worst-case gate delay assuming: g,pg,p generation = 1τ1\tau; the block carry-out logic = 2τ2\tau; the final sum XOR = 1τ1\tau. (5 marks)

(d) Write a function carry_lookahead(a, b, cin) in pseudocode that takes two nn-bit integer arrays (LSB first), computes all gi,pig_i, p_i, then all carries via the closed form, and returns the sum array plus final carry-out. Do not use a ripple loop for the carries. (6 marks)


Question 2 — Multiplexer Logic Synthesis and a Barrel Shifter (20 marks)

(a) Prove that a single 2n:12^n{:}1 multiplexer with nn select lines can implement any Boolean function of nn variables, and show that a 2n1:12^{n-1}{:}1 multiplexer can implement any nn-variable function if the data inputs are allowed to be {0,1,xn,xn}\{0,1,x_n,\overline{x_n}\}. Illustrate with f(A,B,C)=Σm(1,2,4,7)f(A,B,C) = \Sigma m(1,2,4,7) using a 4:14{:}1 MUX with select lines A,BA,B. (8 marks)

(b) Design a 4-bit logarithmic barrel shifter (rotate-left) using only 2:12{:}1 multiplexers. State how many MUX stages and how many total MUXes are required, and justify the stage structure (which shift amount each stage handles). (6 marks)

(c) Given input 1011 (MSB left), trace the rotate-left-by-3 operation stage-by-stage through your shifter, showing the intermediate word after each stage. (6 marks)


Question 3 — Static Hazard Analysis and a Proof (18 marks)

Consider F(A,B,C)=AB+ACF(A,B,C) = AB + \overline{A}C.

(a) Draw/state the truth table and identify the input transition where a static-1 hazard may occur. Explain, in terms of adjacent minterms sharing no common product term, why the hazard exists. (6 marks)

(b) Derive the redundant consensus term that eliminates the hazard, and give the hazard-free expression. Prove algebraically that the added term does not change the function (i.e., it is logically redundant). (6 marks)

(c) Prove the general theorem: a two-level SOP realization of a function is free of static-1 hazards if and only if every pair of adjacent minterms (differing in one variable) is covered by at least one common product term (prime implicant) in the implementation. Give the forward and reverse directions concisely. (6 marks)

Answer keyMark scheme & solutions

Question 1

(a) (6 marks) Recurrence: ci+1=gi+picic_{i+1} = g_i + p_i c_i. Substitute ci=gi1+pi1ci1c_i = g_{i-1} + p_{i-1}c_{i-1}:

ci+1=gi+pi(gi1+pi1ci1)=gi+pigi1+pipi1ci1.c_{i+1} = g_i + p_i(g_{i-1} + p_{i-1}c_{i-1}) = g_i + p_i g_{i-1} + p_i p_{i-1} c_{i-1}.

Continuing recursively down to c0c_0:

ci+1=gi+j=0i1(k=j+1ipk)gj+(k=0ipk)c0.c_{i+1} = g_i + \sum_{j=0}^{i-1}\left(\prod_{k=j+1}^{i}p_k\right)g_j + \left(\prod_{k=0}^{i}p_k\right)c_0.

Marks: recurrence stated (1); first substitution (2); recursive continuation (2); closed form (1).

(b) (5 marks)

  • gi,pig_i,p_i generated in parallel: 1τ1\tau (AND / XOR).
  • Each carry is a 2-level AND-OR expression → 2τ2\tau.
  • All carries produced simultaneously: total =1τ+2τ=3τ= 1\tau + 2\tau = 3\tau, independent of nnO(1)O(1) carry delay. (2 marks)
  • Ripple-carry: each stage's carry waits for previous; carry chain =2τ= 2\tau per bit ⇒ 2nτ=O(n)\approx 2n\,\tau = O(n). (2 marks)
  • Conclusion: CLA is O(1)O(1) vs ripple O(n)O(n) (constant vs linear). (1 mark)

(c) (5 marks)

  • g,pg,p generation: 1τ1\tau.
  • Within block 0 carries ready after +2τ+2\tau; block carry-out logic 2τ2\tau ⇒ block0 cout at 1+2=3τ1+2=3\tau.
  • Blocks ripple: each subsequent block adds 2τ2\tau (block carry-out). For 4 blocks the carry into block 3 arrives at 1+2×3=7τ1 + 2\times3 = 7\tau; then intra-block carries 2τ2\tau then sum XOR 1τ1\tau.
  • Worst-case sum bit (MSB): 1τ(g,p)+2τ×3(ripple through 3 block-carries)+2τ(intra-block carry)+1τ(sum XOR)=10τ1\tau (g,p) + 2\tau\times3 (\text{ripple through 3 block-carries}) + 2\tau (\text{intra-block carry}) + 1\tau (\text{sum XOR}) = 10\tau.

Accept 10τ10\tau. Marks: g/p (1); block carry model (1); ripple 3 blocks = 6τ (2); +intra+sum = 10τ (1).

(d) (6 marks)

function carry_lookahead(a, b, cin):
    n = length(a)
    g = array(n); p = array(n)
    for i in 0..n-1:
        g[i] = a[i] AND b[i]
        p[i] = a[i] XOR b[i]
    c = array(n+1)
    c[0] = cin
    for i in 0..n-1:               # closed-form, no dependence chain
        term = g[i]
        prodP = 1
        for j from i down to 0:    # build products of p's
            prodP = prodP AND p[j]... 
        # explicit closed form:
        c[i+1] = g[i]
        acc = 1
        for j from i-1 down to 0:
            acc = acc AND p[j+1]           # product p_{j+1..i}
            c[i+1] = c[i+1] OR (acc AND g[j])
        acc = acc AND p[0]
        c[i+1] = c[i+1] OR (acc AND c[0])
    sum = array(n)
    for i in 0..n-1:
        sum[i] = p[i] XOR c[i]
    return (sum, c[n])

Marks: g/p generation (1); parallel carry via closed form / no ripple dependency (3); sum = p XOR c (1); return cout (1).


Question 2

(a) (8 marks) A 2n:12^n{:}1 MUX with select =(x1xn)= (x_1\ldots x_n) outputs Y=k(mkDk)Y=\sum_{k}(m_k \cdot D_k) where mkm_k is the minterm selecting data input DkD_k. Setting each DkD_k to the desired functional value (00 or 11) reproduces the truth table exactly ⇒ any nn-var function realizable (Shannon expansion over all nn vars). (3)

For 2n1:12^{n-1}{:}1: apply Shannon expansion on first n1n-1 variables; each residue fx1..xn1f|_{x_1..x_{n-1}} is a function of the single remaining variable xnx_n, hence equals one of {0,1,xn,xn}\{0,1,x_n,\overline{x_n}\}. Feed that residue to the corresponding data input. (3)

Example f(A,B,C)=Σm(1,2,4,7)f(A,B,C)=\Sigma m(1,2,4,7), select =A,B=A,B; residues in CC:

A B minterms residue
00 m0=0,m1=1 CC
01 m2=1,m3=0 C\overline{C}
10 m4=1,m5=0 C\overline{C}
11 m6=0,m7=1 CC

So D0=C, D1=C, D2=C, D3=CD_0=C,\ D_1=\overline C,\ D_2=\overline C,\ D_3=C. (2)

(b) (6 marks) Logarithmic barrel shifter for 4 bits needs log24=2\log_2 4 = 2 stages. Stage 1 rotates by 20=12^0=1 (controlled by s0s_0); stage 2 rotates by 21=22^1=2 (controlled by s1s_1). Each stage uses one 2:12{:}1 MUX per bit = 4 MUXes/stage ⇒ 2 stages, 8 MUXes total. Each MUX selects between the un-rotated bit and the rotated-in bit. (stages 2 —2 marks; count 8 —2 marks; justification of 2k2^k per stage —2 marks).

(c) (6 marks) Input 1011, rotate-left-by-3 ⇒ s1s0=11s_1 s_0 = 11.

  • Stage 1 (rotate-left by 1, s0=1s_0=1): 10110111. (rotate left: MSB wraps to LSB: 0111) (3)
  • Stage 2 (rotate-left by 2, s1=1s_1=1): 01111101. (2)
  • Result 1101. Check: rotate-left-by-3 of 1011 = 1101. ✓ (1)

Question 3

(a) (6 marks) Truth table of F=AB+ACF=AB+\overline A C:

A B C F
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 0
1 1 0 1
1 1 1 1

Static-1 hazard on transition A:01A:0\to1 with B=1,C=1B=1,C=1 (i.e. ABC=011111ABC=011\to111, both output =1=1). The term AC\overline A C covers the 011011 side, ABAB covers the 111111 side; no single product covers both, so during the switch a momentary 00 glitch can occur. (transition ID 3; explanation 3).

(b) (6 marks) Consensus of ABAB and AC\overline A C (on variable AA) is BCBC. Hazard-free: F=AB+AC+BCF = AB + \overline A C + BC.

Redundancy proof: BC=BC(A+A)=ABC+ABCBC = BC(A+\overline A) = ABC + \overline A BC. But ABCABABC \subseteq AB and ABCAC\overline A BC \subseteq \overline A C, so AB+AC+BC=AB+ACAB+\overline A C+BC = AB+\overline A C. Function unchanged. (consensus term 2; hazard-free expr 1; algebraic redundancy proof 3).

(c) (6 marks) Forward: If every pair of adjacent 1-minterms is covered by a common product term, then during a single-variable transition between two 1-cells, that common product term stays at 1 throughout (its literals don't include the changing variable), holding F=1F=1 ⇒ no static-1 hazard. (3)

Reverse (contrapositive): If some adjacent 1-pair has no common product term, the two minterms are covered only by distinct terms whose activating literals differ in the changing variable; there is a delay window where the falling term is already 0 and the rising term not yet 1, producing a momentary 0 ⇒ static-1 hazard exists. Hence hazard-freedom ⇔ every adjacent 1-pair shares a covering prime implicant. (3)

[
{"claim":"16-bit block CLA worst-case delay = 10 tau","code":"gp=1; ripple=2*3; intra=2; sumx=1; result=(gp+ripple+intra+sumx)==10"},
{"claim":"Flat CLA carry delay is 3 tau constant","code":"result=(1+2)==3"},
{"claim":"f=Sigma m(1,2,4,7) residues for MUX select A,B are C,~C,~C,C","code":"m={0:0,1:1,2:1,3:0,4:1,5:0,6:0,7:1}; A,B,C=symbols('A B C'); rows=[( (m[0],m[1]),'C'),((m[2],m[3]),'~C'),((m[4],m[5]),'~C'),((m[6],m[7]),'C')]; ok=[(r[0]==(0,1) and r[1]=='C') or (r[0]==(1,0) and r[1]=='~C') for r in rows]; result=all(ok)"},
{"claim":"rotate-left-by-3 of 1011 = 1101","code":"v=0b1011; n=4; r=((v<<3)|(v>>(n-3)))&0b1111; result=r==0b1101"},
{"claim":"AB+~A C+BC == AB+~A C (consensus redundant)","code":"A,B,C=symbols('A B C'); from sympy.logic.boolalg import simplify_logic; lhs=simplify_logic((A&B)|(~A&C)|(B&C)); rhs=simplify_logic((A&B)|(~A&C)); result=lhs==rhs"}
]