You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
Circuit design is the capstone of this entire course — the lesson where logic gates, Boolean algebra, truth tables, Karnaugh maps, adders and flip-flops stop being separate techniques and become one connected design workflow. Up to now each tool was studied for its own sake; here they are deployed together to answer the real engineering question: given a description of what a circuit must do, how do you produce the cheapest, fastest correct circuit that does it? The OCR H446 specification expects you to take a problem stated in words, turn it into a truth table, derive and minimise a Boolean expression, and draw the resulting circuit — and, for richer problems, to combine combinational blocks with adders and flip-flops into a complete design.
The discipline that ties the topic together is a fixed design pipeline: requirements → truth table → expression → minimise → circuit → verify. Each arrow is a translation you have already practised in isolation; circuit design is the habit of running them in sequence, never skipping a stage, and always minimising before committing to gates. The reason minimisation is non-negotiable is economic and physical: every gate removed saves silicon area, power, heat and propagation delay, and across a real design those savings compound. This lesson works through a sequence of designs of increasing ambition — a majority voter, an alarm, a don't-care-rich display decoder, and finally a full end-to-end problem combining a comparator, an adder and a register — to show the pipeline at every scale. Every truth table and K-map is a markdown table and every circuit a diagram; ASCII art is never used.
This lesson covers the circuit-design and application strand of OCR H446 section 1.4.3 (Boolean algebra and its application), drawing together the whole module:
It is the synthesis of every earlier lesson — gates, laws, De Morgan's, simplification, K-maps, logic circuits, adders and flip-flops — and is the natural endpoint of section 1.4.3.
| Step | Action | Tools from earlier lessons |
|---|---|---|
| 1 | Understand the requirement | careful reading; identify inputs and outputs |
| 2 | Construct the truth table | list every input combination and its desired output |
| 3 | Derive a Boolean expression | sum-of-products from the rows where output = 1 |
| 4 | Minimise | Boolean algebra laws and/or Karnaugh maps (with don't-cares) |
| 5 | Draw the circuit | gate symbols, building from the output gate inward |
| 6 | Verify | trace test inputs (especially boundary cases) back through the circuit |
Skipping step 4 produces a working but wasteful circuit; skipping step 6 risks a subtle wiring error reaching the final answer. The pipeline is deliberately the same every time, so that even an unfamiliar problem becomes a routine you can execute under exam pressure.
Requirement: three inputs A, B, C; output 1 when at least two are 1 (a voting / fault-tolerance circuit).
Step 1–2 — truth table:
| A | B | C | Q |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |
Step 3 — sum of products (one product per output-1 row):
Q=A⋅B⋅C+A⋅B⋅C+A⋅B⋅C+A⋅B⋅C
Step 4 — minimise with a K-map:
| BC=00 | BC=01 | BC=11 | BC=10 | |
|---|---|---|---|---|
| A=0 | 0 | 0 | 1 | 0 |
| A=1 | 0 | 1 | 1 | 1 |
Three overlapping groups of two cover the 1s:
Q=A⋅B+A⋅C+B⋅C
Step 5 — circuit (three ANDs into a 3-input OR; B and C fan out to two gates each):
flowchart LR
A((A)) --> AB{{"AND"}}
B((B)) --> AB
A --> AC{{"AND"}}
C((C)) --> AC
B --> BC{{"AND"}}
C --> BC
AB -- "A·B" --> OR{{"OR (3-input)"}}
AC -- "A·C" --> OR
BC -- "B·C" --> OR
OR --> Q["Q"]
Step 6 — verify: test A=1,B=1,C=0 → A⋅B=1, so Q=1 ✓ (two inputs high); test A=1,B=0,C=0 → all products 0, Q=0 ✓ (only one high). The minimised form is four gates against the seven-plus of the raw four-minterm version. This is the majority function met in the simplification lesson, now carried all the way to a verified circuit.
Requirement: an alarm sounds (Q=1) when the system is armed (A=1) and either the door sensor (D=1) or the window sensor (W=1) is triggered.
The requirement translates almost directly to an expression — recognising when a truth table is unnecessary is itself a design skill:
Q=A⋅(D+W)
A confirming truth table:
| A | D | W | D+W | Q=A⋅(D+W) |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 1 | 1 |
| 1 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 1 |
flowchart LR
D((D)) --> OR{{"OR"}}
W((W)) --> OR
A((A)) --> AND{{"AND"}}
OR -- "D+W" --> AND
AND --> Q["Q"]
Just two gates. The factored form A⋅(D+W) is already minimal; expanding it to the SoP A⋅D+A⋅W would need three gates, a reminder that a factored (product-of-sums-like) form is sometimes the cheaper target, as discussed in the simplification lesson.
Minimisation is the step that distinguishes a design from a mere implementation. The pay-off touches every engineering metric:
| Factor | Unminimised | Minimised |
|---|---|---|
| Gate count | higher | lower |
| Cost (silicon area) | higher | lower |
| Power and heat | higher | lower |
| Speed | more levels → slower | fewer levels → faster |
| Reliability | more parts to fail | fewer failure points |
The minimisation toolkit, in order of typical use:
Exam Tip: If a question says "minimised" or "simplified", an unsimplified-but-correct circuit will lose marks. Always run step 4 before step 5.
Real designs lean heavily on don't-care conditions, and the 7-segment decoder is the classic example. A 7-segment display shows the digits 0–9 using segments a–g; we design the logic for segment a (the top bar), driven by a 4-bit BCD input A (MSB), B, C, D.
Segment a is on for 0, 2, 3, 5, 6, 7, 8, 9 and off for 1 and 4. The BCD codes 10–15 never occur, so they are don't-cares:
| Digit | A | B | C | D | Segment a |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 1 |
| 1 | 0 | 0 | 0 | 1 | 0 |
| 2 | 0 | 0 | 1 | 0 | 1 |
| 3 | 0 | 0 | 1 | 1 | 1 |
| 4 | 0 | 1 | 0 | 0 | 0 |
| 5 | 0 | 1 | 0 | 1 | 1 |
| 6 | 0 | 1 | 1 | 0 | 1 |
| 7 | 0 | 1 | 1 | 1 | 1 |
| 8 | 1 | 0 | 0 | 0 | 1 |
| 9 | 1 | 0 | 0 | 1 | 1 |
| 10–15 | — | — | — | — | X (don't care) |
The K-map, with the don't-cares marked X:
| CD=00 | CD=01 | CD=11 | CD=10 | |
|---|---|---|---|---|
| AB=00 | 1 | 0 | 1 | 1 |
| AB=01 | 0 | 1 | 1 | 1 |
| AB=11 | X | X | X | X |
| AB=10 | 1 | 1 | X | X |
Grouping greedily, using the don't-cares as 1s wherever they enlarge a group:
Together these cover every 1, giving the minimised expression:
a=A+C+B⋅D+B⋅D
A quick check confirms it: digit 1 (0001) gives 0+0+0+0=0 (off ✓); digit 5 (0101) gives 0+0+(1⋅1)+0=1 (on ✓); digit 0 (0000) gives 0+0+0+(1⋅1)=1 (on ✓). Without the don't-cares the terms would be longer and more numerous; exploiting the six unused codes is what makes the decoder cheap. This corrects a common pitfall — do not abandon a decoder K-map as "too messy"; group the don't-cares aggressively and a tidy four-term expression falls out.
The richest H446 questions combine combinational and sequential logic. Here is a complete design problem solved end to end.
Requirement. A simple "score-on-match-and-store" unit takes two 2-bit numbers X=X1X0 and Y=Y1Y0. On each clock pulse it must: (1) output a signal EQ that is 1 when X=Y; and (2) when X=Y, add 1 to a stored running total held in a register, otherwise leave the total unchanged. We design the equality detector and the increment-and-store path, combining a comparator, an adder and a register.
Part 1 — the equality comparator (combinational). Two single bits are equal when they are both 0 or both 1 — that is XNOR, Xi⊕Yi. Two 2-bit numbers are equal when both bit-pairs match, so:
EQ=(X1⊕Y1)⋅(X0⊕Y0)
flowchart LR
X1((X1)) --> XN1{{"XNOR"}}
Y1((Y1)) --> XN1
X0((X0)) --> XN0{{"XNOR"}}
Y0((Y0)) --> XN0
XN1 -- "bit1 equal" --> AND{{"AND"}}
XN0 -- "bit0 equal" --> AND
AND --> EQ["EQ"]
Part 2 — the increment path (combinational adder). The running total is incremented by 1 only when EQ=1. Feeding the adder a value of 1 when EQ=1 and 0 otherwise is achieved by wiring EQ itself into the adder's least-significant input: adding EQ to the stored total adds 1 exactly when there is a match and 0 otherwise. For an n-bit total this is an n-bit adder whose B input is 0…0EQ — or, more economically, a chain of half adders that ripples the single incoming carry:
flowchart LR
EQ((EQ)) --> HA0[["Half Adder<br/>bit 0"]]
T0(("total bit 0")) --> HA0
HA0 -- "new bit 0" --> R0["to register bit 0"]
HA0 -- "carry" --> HA1[["Half Adder<br/>bit 1"]]
T1(("total bit 1")) --> HA1
HA1 -- "new bit 1" --> R1["to register bit 1"]
HA1 -- "carry" --> MORE["… higher bits"]
Part 3 — storing the result (sequential register). The adder's output is captured by a register of D-type flip-flops, one per total bit, all sharing the clock. On each rising edge the register loads the adder output, so the new total is stored and then fed back to the adder for the next cycle:
flowchart LR
ADD["adder output (new total)"] --> REG[["D-type register<br/>(running total)"]]
CLK((CLK)) --> REG
REG -- "stored total (feedback)" --> ADDIN["back to adder B-side total inputs"]
Putting it together. The comparator produces EQ combinationally; the adder combinationally computes total + EQ; the register sequentially latches the sum on the clock edge and feeds it back. When X=Y, EQ=0, the adder adds 0, and the register simply reloads its current value — the total is unchanged, as required. When X=Y, EQ=1, the adder adds 1, and the register stores the incremented total.
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.