Combinational Circuits
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 and propagate signals.
(a) Starting from the full-adder carry recurrence , prove by expansion that
State the general closed-form for using product/sum notation. (6 marks)
(b) Assume every gate has delay and unlimited fan-in. Give the propagation delay (in units of ) to produce all carry signals in a flat -bit CLA, and compare it against an -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: generation = ; the block carry-out logic = ; the final sum XOR = . (5 marks)
(d) Write a function carry_lookahead(a, b, cin) in pseudocode that takes two -bit integer arrays (LSB first), computes all , 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 multiplexer with select lines can implement any Boolean function of variables, and show that a multiplexer can implement any -variable function if the data inputs are allowed to be . Illustrate with using a MUX with select lines . (8 marks)
(b) Design a 4-bit logarithmic barrel shifter (rotate-left) using only 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 .
(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: . Substitute :
Continuing recursively down to :
Marks: recurrence stated (1); first substitution (2); recursive continuation (2); closed form (1).
(b) (5 marks)
- generated in parallel: (AND / XOR).
- Each carry is a 2-level AND-OR expression → .
- All carries produced simultaneously: total , independent of ⇒ carry delay. (2 marks)
- Ripple-carry: each stage's carry waits for previous; carry chain per bit ⇒ . (2 marks)
- Conclusion: CLA is vs ripple (constant vs linear). (1 mark)
(c) (5 marks)
- generation: .
- Within block 0 carries ready after ; block carry-out logic ⇒ block0 cout at .
- Blocks ripple: each subsequent block adds (block carry-out). For 4 blocks the carry into block 3 arrives at ; then intra-block carries then sum XOR .
- Worst-case sum bit (MSB): .
Accept . 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 MUX with select outputs where is the minterm selecting data input . Setting each to the desired functional value ( or ) reproduces the truth table exactly ⇒ any -var function realizable (Shannon expansion over all vars). (3)
For : apply Shannon expansion on first variables; each residue is a function of the single remaining variable , hence equals one of . Feed that residue to the corresponding data input. (3)
Example , select ; residues in :
| A B | minterms | residue |
|---|---|---|
| 00 | m0=0,m1=1 | |
| 01 | m2=1,m3=0 | |
| 10 | m4=1,m5=0 | |
| 11 | m6=0,m7=1 |
So . (2)
(b) (6 marks) Logarithmic barrel shifter for 4 bits needs stages. Stage 1 rotates by (controlled by ); stage 2 rotates by (controlled by ). Each stage uses one 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 per stage —2 marks).
(c) (6 marks)
Input 1011, rotate-left-by-3 ⇒ .
- Stage 1 (rotate-left by 1, ):
1011→0111. (rotate left: MSB wraps to LSB: 0111) (3) - Stage 2 (rotate-left by 2, ):
0111→1101. (2) - Result
1101. Check: rotate-left-by-3 of1011=1101. ✓ (1)
Question 3
(a) (6 marks) Truth table of :
| 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 with (i.e. , both output ). The term covers the side, covers the side; no single product covers both, so during the switch a momentary glitch can occur. (transition ID 3; explanation 3).
(b) (6 marks) Consensus of and (on variable ) is . Hazard-free: .
Redundancy proof: . But and , so . 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 ⇒ 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"}
]