Hello and welcome to Part 2 of my Beginning Logic Design series!
In this lesson we are going to build a 4-bit adding machine!
Binary Numbers
In the digital world all we have is 0 and 1, so we need to come up with some clever ways to represent numbers. For now we’ll only worry about 4-bit unsigned integers.
Here’s a chart of the decimal numbers we’ll be able to represent, along with those same numbers in Binary and Hexadecimal
The digit displays in Logicly have 4 inputs, each represents a binary bit. The order for this display in Logicly goes from the least significant bit at the top to the most significant bit at the bottom.
I suggest building this design in Logicly yourself and playing with the switches if this is unfamiliar to you.
The Classic 1-Bit Adder Circuits
Probably the most famous of combinational circuits is the Adder. Take two numbers in, and output the sum. Typically we start this design by creating what is known as a half adder, it takes two 1-bit inputs and adds them together.
Let’s look at a truth table for 1 bit addition (in binary!)
As you can see, to handle all 4 possible cases, we need to output 2 binary digits due to the 1+1
case. To support addition with any set number of digits, you need one more output digit to support the carry over value that changes a higher digit. This is similar to when you do 9+9
with decimal numbers, you carry a 1
to the 10’s place so you can represent the sum as 18
instead of just 8
, which would be wrong! We’ll separate out the sum and carry out in our table so that they are easy to reference.
Looking at this table, think of what gate could take a
and b
as inputs and output carry
, as well as what could take a
and b
as inputs and output sum
.
The answer is that we can use an AND
gate to determine what the carry
should be, and an XOR
gate to determine the sum
.
This is called a half adder, named so because it provides roughly half of a more useful design called a full adder. The full adder also lets us add two 1-bit numbers together, but can also handle chaining carry values together to add numbers of any width of bits!
The full adder shares the same two outputs, but adds a carry in
input to consider the carry out
value of a lower digit. Think about how we handle long addition in decimal, with the example of adding 123 and 99.
For the middle digit of the answer here, you will add three numbers, 2 + 9 + 1(the carry in
) to land at 2 (carry out
the 1).
We follow this same principle for the full adder, the truth table for which is a wee bit more complicated, due to the additional input.
The design for the full adder will take a bit more effort to work out, but let’s look at this table and make a few observations.
- When the
carry in
input is 0, thecarry out
andsum
are the same as for the half adder, so we can use that design as a base for half of the input possibilities - When
carry in
is 1, thesum
is the opposite of what it otherwise would be - When
carry in
is 1, thecarry out
is 1 if any other input is also 1
Try on your own to make a full adder!
The Full Adder
Hopefully you found some success in building your own full adder, but if not, don’t fret! Build this design on your end and tinker with it a bit.
It takes some practice to analyze these circuits. This one only has 3 inputs and two outputs, but it’s the arrangement of the 5 logic gates inside that makes you scratch your head. To understand a circuit like this I will look at the outputs, and follow the lines back to the inputs.
In this design, the XOR
gates that lead to sum
creates a situation where sum
will be 1 if an odd number of the inputs are 1. For carry out
there are two AND
gates that result in the final OR
gate outputting 1 if either a
AND b
, or if ((a
XOR b
) AND carry in
).
With this design validated, we can save this as a custom component in logicly so we hide this complexity within a black box and get back to focusing on our goal, the adding machine!
We’ll first need to name the inputs and outputs. You can name them by clicking on the switches and light bulbs and entering the name into prompt that pops up. Next, highlight the whole design and go to Edit->Create Integrated Circuit
or right click and select Create Integrated Circuit
from the menu.
On my end, before hitting save, I moved the outputs so that sum was on top and carry_out
was below it. We now have a reusable Full Adder circuit!
Putting It All Together
Before I go too far, and make a huge mess of our schematic, I’ll make a 2-bit adder. I’ll start by adding some switches I can use to setup my inputs, along with displays to see what number it represents.
Next, I’ll add two full adders, and wire the upper switch (least significant bits) to the first adder.
Next I’ll hook up the output display by routing the sum to it.
The full adder isn’t outputting a valid state because some of its own inputs are invalid, in this case the lack of a carry in
signal. I’ll use a constant to keep it low for the lowest bit.
At this point it can handle 1 bit input, but only 1 bit output. I could hook up the carry in for the 2nd bit.
To handle 2 bit input, I’ll route the 2nd bit switches to the next adder and route the carry out
of the first adder to the carry in
of the next. To display the output here, I’ll route the sum
of the first adder to the 1st bit of display input, route the 2nd adder’s sum
to the 2nd bit input, and the final carry out
to the 3rd bit.
This same pattern can be extended to handle another 2 bits.
There’s the 4-bit adding machine! It could be made to any bit width, but 4 fits a single display. It is possible for there to be a 5th bit of output, but we’ll just drop that for now. In many adders that final carry is interpreted as an carry flag to let you know the sum digit width was larger than the input digit width.
For a messier example of how this can scale, here’s a 16-bit adder in logicly.
That covers this post on building some digital adders. If you have any feedback or questions please leave a comment! Keep tinkering!