Lesson 6 (bonus). Decimal math: add six
In picturesAfter this lesson the adder counts in tens, like a calculator: 38 + 47 = 85 — and the display shows exactly these digits. An optional lesson: the calculator of lesson 5 is complete without it.
6.1. The idea: a digit in four bits
People count in tens, the adder in sixteens. Calculators and cash registers solved it simply: each decimal digit was kept in its own 4 bits. That is binary-coded decimal (BCD): 38 is 0011 (3) and 1000 (8), that is 0011 1000.
An ordinary ADDER4 adds the digits. While the digit sum is at most 9, all is right. If it is more, 4 bits have six codes 1010…1111 that a decimal digit never uses, and we have to jump over them: add 6. A carry into the next digit is born at the same time.
The digit sum is more than 9 when:
- the binary adder gave a carry — that is 16…19, or
s3 = 1and (s1 = 1ors2 = 1) — that is 10…15.
That is how calculators and the first microprocessors counted: the Intel 4004 has the DAA instruction for it, and the 6502 has a decimal mode (SED).
6.2. Why the display is in HEX mode
The display knows nothing about BCD: it takes 8 bits and shows them as a number in the chosen system.
- In HEX one display digit is exactly 4 bits. The low digit is bits 0–3, the high one is 4–7. And in BCD we also put one digit in every 4 bits. So the HEX display shows our digits as they are:
0011 1000→38. - In DEC the display reads the same 8 bits as one binary number:
0011 1000= 32 + 16 + 8 =56.
The "+6" correction makes sure a group of four bits never holds 1010…1111, so the display never shows the letters A…F — only digits 0–9. A letter appeared — the correction did not fire.
Real calculators did exactly this: each digit was kept in its own 4 bits and went straight to its own indicator. Converting a binary number to decimal means dividing by 10, and that is far more hardware than the "+6" correction.
6.3. Building
An optional lesson: the calculator of lesson 5 is complete without it.
The same project. Delete the lesson 5 setup (17 switches, two ADDSUB8, lamps, displays); keep Power/Ground.
The idea. People count in tens, the adder in sixteens. Let us write each decimal digit in its own 4 bits (binary-coded decimal, BCD): 38 = 0011 1000. We add the digits with an ordinary ADDER4. While the digit sum is ≤ 9, all is right. Above 9, 4 bits have six codes 1010…1111 that a decimal digit never uses — we have to jump over them: add 6. A carry into the next digit is born at the same time.
The digit sum is more than 9 when:
- the binary adder gave a carry (16…19), or
s3 = 1and (s1 = 1ors2 = 1) — that is 10…15.
That is how calculators and the first microprocessors counted: the Intel 4004 has the DAA instruction for it, the 6502 has the SED mode.
Step 1. BCD1 — one decimal digit
| Part | Pin | Label |
|---|---|---|
| Input port | out | A0 |
| Input port | out | A1 |
| Input port | out | A2 |
| Input port | out | A3 |
| Input port | out | B0 |
| Input port | out | B1 |
| Input port | out | B2 |
| Input port | out | B3 |
| Input port | out | CI |
| ADDER4 (digit sum) | A0 A1 A2 A3 B0 B1 B2 B3 CI S0 S1 S2 S3 CO | A0 A1 A2 A3 B0 B1 B2 B3 CI s0 s1 s2 s3 c |
| OR | I0 I1 O0 | s1 s2 s12 |
| AND (10…15) | I0 I1 O0 | s3 s12 big |
| OR (more than 9) | I0 I1 O0 | c big CO |
| ADDER4 (+6) | A0 A1 A2 A3 B0 B1 B2 B3 CI S0 S1 S2 S3 CO | s0 s1 s2 s3 GND CO CO GND GND D0 D1 D2 D3 — (free) |
| Output port | in | D0 |
| Output port | in | D1 |
| Output port | in | D2 |
| Output port | in | D3 |
| Output port | in | CO |
Ctrl+G → name BCD1. Pins: inputs A0–A3, B0–B3, CI; outputs D0–D3, CO.
CO is two things at once: "add 6" (it goes to B1, B2 of the second ADDER4, since 6 = 0110) and the carry into the next digit.
Step 2. Canvas: two digits
| Part | Pin | Label |
|---|---|---|
| Input | out | A0 |
| Input | out | A1 |
| Input | out | A2 |
| Input | out | A3 |
| Input | out | A4 |
| Input | out | A5 |
| Input | out | A6 |
| Input | out | A7 |
| Input | out | B0 |
| Input | out | B1 |
| Input | out | B2 |
| Input | out | B3 |
| Input | out | B4 |
| Input | out | B5 |
| Input | out | B6 |
| Input | out | B7 |
| BCD1 (units) | A0 A1 A2 A3 B0 B1 B2 B3 CI D0 D1 D2 D3 CO | A0 A1 A2 A3 B0 B1 B2 B3 GND D0 D1 D2 D3 c10 |
| BCD1 (tens) | A0 A1 A2 A3 B0 B1 B2 B3 CI D0 D1 D2 D3 CO | A4 A5 A6 A7 B4 B5 B6 B7 c10 D4 D5 D6 D7 H |
| LED («100») | in | H |
| Display | ⚙ | width 8, HEX, bus A |
| Display | ⚙ | width 8, HEX, bus B |
| Display | ⚙ | width 8, HEX, bus D |
The displays are in HEX mode: each hexadecimal digit is exactly 4 bits, so the display shows binary-coded decimal digits as they are: 0011 1000 reads as 38.
How to set the digits
The low digit is switches A0–A3 (B0–B3), the high digit is A4–A7 (B4–B7). Each digit is 0 to 9:
| Digit | Switches 3 2 1 0 |
|---|---|
| 0 | 0 0 0 0 |
| 1 | 0 0 0 1 |
| 2 | 0 0 1 0 |
| 3 | 0 0 1 1 |
| 4 | 0 1 0 0 |
| 5 | 0 1 0 1 |
| 6 | 0 1 1 0 |
| 7 | 0 1 1 1 |
| 8 | 1 0 0 0 |
| 9 | 1 0 0 1 |
6.4. Check
| A | Switches A7…A0 | B | Switches B7…B0 | Display D | Lamp | Inside |
|---|---|---|---|---|---|---|
| 23 | 0010 0011 | 45 | 0100 0101 | 68 | — | 3 + 5 = 8 and 2 + 4 = 6: no correction |
| 38 | 0011 1000 | 47 | 0100 0111 | 85 | — | 8 + 7 = 15 → +6 → 5, carry; 3 + 4 + 1 = 8 |
| 09 | 0000 1001 | 01 | 0000 0001 | 10 | — | 9 + 1 = 10 → +6 → 0, carry |
| 99 | 1001 1001 | 01 | 0000 0001 | 00 | 100 | the carry runs through both digits |
| 99 | 1001 1001 | 99 | 1001 1001 | 98 | 100 | 9 + 9 = 18: carry from the binary adder → +6 |
In the "Switches" columns the top switch (A7) is on the left and A0 on the right; 1 — on, 0 — off. Each group of 4 is one decimal digit: tens on the left, units on the right.
If the answer is right up to 9 but beyond that letters (A…F) appear on the display, the correction does not fire: check OR/AND inside BCD1 and that CO goes to B1 and B2 of the second ADDER4.
Lesson 6 paste (Cmd+I)
Needs AND, OR and ADDER4. Delete the lesson 5 setup, keep the power.
# Lesson 6 (bonus) — decimal math: BCD1 with the +6 correction.chip BCD1 { portIn(A0) portIn(A1) portIn(A2) portIn(A3) portIn(B0) portIn(B1) portIn(B2) portIn(B3) portIn(CI) portOut(D0) portOut(D1) portOut(D2) portOut(D3) portOut(CO) ADDER4(A0=A0, A1=A1, A2=A2, A3=A3, B0=B0, B1=B1, B2=B2, B3=B3, CI=CI, S0=s0, S1=s1, S2=s2, S3=s3, CO=c) OR(s1, s2, s12) AND(s3, s12, big) OR(c, big, CO) ADDER4(A0=s0, A1=s1, A2=s2, A3=s3, B0=GND, B1=CO, B2=CO, B3=GND, CI=GND, S0=D0, S1=D1, S2=D2, S3=D3)} input(A0)input(A1)input(A2)input(A3)input(A4)input(A5)input(A6)input(A7)input(B0)input(B1)input(B2)input(B3)input(B4)input(B5)input(B6)input(B7)BCD1(A0=A0, A1=A1, A2=A2, A3=A3, B0=B0, B1=B1, B2=B2, B3=B3, CI=GND, D0=D0, D1=D1, D2=D2, D3=D3, CO=c10)BCD1(A0=A4, A1=A5, A2=A6, A3=A7, B0=B4, B1=B5, B2=B6, B3=B7, CI=c10, D0=D4, D1=D5, D2=D6, D3=D7, CO=H)led(H)Stuck? Something doesn't work →