Lesson 6 (bonus). Decimal math: add six

In pictures

After 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 = 1 and (s1 = 1 or s2 = 1) — that is 10…15.
tensunitsA = 380011100038B = 470100011147sum111115 > 9 → +6+01100101digit 5, carry 1carry +110003 + 4 + 1 = 8 ≤ 9no correctionanswer: 1000 0101 — 85 on the HEX display
38 + 47 in binary-coded decimal. Units: 8 + 7 = 1111 — that is 15, more than 9, so we add 0110 (six): the result is 1 0101 — the digit 5 and a carry into the tens. Tens: 3 + 4 + 1 = 8, no correction. The answer is 1000 0101 — 85.

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 = 1 and (s1 = 1 or s2 = 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

PartPinLabel
Input portoutA0
Input portoutA1
Input portoutA2
Input portoutA3
Input portoutB0
Input portoutB1
Input portoutB2
Input portoutB3
Input portoutCI
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
ORI0
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 portinD0
Output portinD1
Output portinD2
Output portinD3
Output portinCO

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

PartPinLabel
InputoutA0
InputoutA1
InputoutA2
InputoutA3
InputoutA4
InputoutA5
InputoutA6
InputoutA7
InputoutB0
InputoutB1
InputoutB2
InputoutB3
InputoutB4
InputoutB5
InputoutB6
InputoutB7
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»)inH
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:

DigitSwitches 3 2 1 0
00 0 0 0
10 0 0 1
20 0 1 0
30 0 1 1
40 1 0 0
50 1 0 1
60 1 1 0
70 1 1 1
81 0 0 0
91 0 0 1

6.4. Check

ASwitches A7…A0BSwitches B7…B0Display DLampInside
230010 0011450100 010168—3 + 5 = 8 and 2 + 4 = 6: no correction
380011 1000470100 011185—8 + 7 = 15 → +6 → 5, carry; 3 + 4 + 1 = 8
090000 1001010000 000110—9 + 1 = 10 → +6 → 0, carry
991001 1001010000 000100100the carry runs through both digits
991001 1001991001 1001981009 + 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 →