Beginning Logic Design – Part 2

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 numbers we’ll be able to represent with 4 bits

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.

Logicly digit display showing the hexadecimal value for 0101

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.

Half adder truth table

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.

A half adder circuit

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.

Very Math

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, the carry out and sum 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, the sum is the opposite of what it otherwise would be
  • When carry in is 1, the carry 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.

Create integrated circuit prompt

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.

My two bit operands

Next, I’ll add two full adders, and wire the upper switch (least significant bits) to the first adder.

Starting to wire it up

Next I’ll hook up the output display by routing the sum to it.

The display is angry!

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.

Setting the carry input to 0

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.

Reading both output bits

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.

A working 2 bit adder

This same pattern can be extended to handle another 2 bits.

A 4 bit adder!

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.