# Exploring How Computers Work

Hi everyone, I spend a lot of time mashing\h away at a keyboard, trying to tell the\h\h
computer what I would like it to do. Even\h my oddly shaped computer (that constantly\h\h
gets teased for looking like a trash can) is\h unbelievably good at following instructions.\h\h
Unfortunately I’m not so good at giving them,\h so the results are inevitably a little wonky,\h\h
but nevertheless it’s always been such a\h mysterious thing to me, that this inanimate lump\h\h
of metal and sand and whatever else, arranged in\h an some extremely clever way, is able to do maths,\h\h
and logic and remember things, and ultimately\h allows us to create pretty much anything we\h\h
set our minds to. It’s kinda bizarre, and I’d\h really like to understand better how it works.
So here’s a little circuit with a light\h and two switches A and B, and clearly,\h\h
the light can only go on if I close both of these\h switches. Already this is a kind of simple logic:\h\h
we’re testing if two conditions are true:\h switch A is closed, AND switch B is closed.\h\h
If we represent an open switch with\h a zero, and closed switch with a 1,\h\h
these are the different configurations we could\h have, and here’s the output: 0 meaning the light\h\h
would be off, and 1 meaning it’d be on. Since\h that’s only the case when A AND B are 1, this\h\h
is known as the logical AND operation. This kind\h of table, by the way, is called a truth table.
Here’s a bit of a different circuit — this time\h we only have 1 switch, and even though it’s open,\h\h
the light is currently on. If I close the switch,\h now the light will go off, because we’ve created\h\h
an easier path for the current to travel. So we’re\h essentially inverting the input: if the state of\h\h
the switch is 0, the output is 1 and vice versa,\h and this is known as the logical NOT operation.
Now I’ve been controlling these switches\h with my fingers, which computers sadly lack,\h\h
so in the very early days, electromagnets\h were used to open and close the switches,\h\h
but this was kinda clunky and slow, so then came\h fancier technologies like vacuum tubes and finally\h\h
transistors. As a tiny example of what transistors\h do, this is essentially that same NOT thing from\h\h
before, just setup on a breadboard, and with a\h transistor in the place of the paperclip switch.
If we think of the current flowing in this\h circuit, it would look something like this.\h\h
It can’t flow through the transistor at the\h moment, because its currently acting as an\h\h
open switch. However, if we send power to to the\h middle pin of the transistor, establishing a small\h\h
flow of current like this, the fancy physics of\h the transistor will make it act like a closed\h\h
switch instead, allowing the main current to flow\h through it like so. Like before, the light has\h\h
turned off because we’ve created a much easier\h path for the current to take. So essentially,\h\h
the transistor is a switch, which we can open and\h close with electricity instead of our fingers.
### Simulation I’d love to one day try and build a simple\h\h
computer out of components like this — which is\h what Ben Eater has done in his very cool 8bit\h\h
breadboard computer series, but that’s a little\h intimidating for me at the moment, so instead I’ve\h\h
made a simplified and abstracted little simulation\h where we have our two logical building blocks:\h\h
AND and NOT, and we can play around and try\h figure some stuff out. So on the left here\h\h
are some inputs, which can be turned on and off,\h or we can also think of it as true and false, or\h\h
1 and 0, it doesn’t really matter — but I’ll wire\h these up to the inputs of the AND gate, and if you\h\h
recall my sophisticated circuitry from earlier,\h the two inputs simply control whether these\h\h
switches are open or closed, which should achieved\h used transistors, not paperclips of course.\h\h
Now I’ll connect the result of this AND\h operation up to my output node over here,\h\h
and so this will only light up if both inputs are\h on. Let’s get the NOT gate participating as well,\h\h
so I’ll connect it up over here, and wire\h the result of THAT to the output instead.\h\h
So the output is now inverted: it’s off when\h both inputs are on, but in all other cases its\h\h
on. Here’s a truth table for this thing we’ve just\h built, and it actually has a name: this is the NOT\h\h
AND, or rather — NAND gate. If I click on this\h Create button down here, it’ll package that up\h\h
into its own little chip, and we now have a nand\h gate to mess about with. I guess this is a good\h\h
moment to mention NAND2Tetris, which along with\h Ben’s videos is a fantastic free resource I’ve\h\h
Anyway, to take this a little further we\h could maybe try inverting both of the inputs\h\h
before feeding them into the nand gate, and let’s\h see what that does. So with both inputs off,\h\h
the output is off, if I turn either of them\h on, the output goes on, and if both are on,\h\h
the output is still on. So we’ve created what’s\h called an OR gate, and I’ll turn that into its\h\h
own little chip as well, because it seems pretty\h useful. And here is the truth table for that.
All right, let’s take a moment to think about\h something that’s pretty important to computers:\h\h
numbers.
In the decimal system that we know and love,\h there are 10 digits, zero through nine,\h\h
and if we want to go higher than that,\h we need to add another place to the left,\h\h
where each digit actually represents 10\h times as much as those in the previous spot.\h\h
And we can have as many places as we need, so\h here would be 100s, then thousands, and so on.
With electronics though, it’s easier to work\h with just two digits, because they can be\h\h
naturally represented with a low voltage\h or a high voltage. So the binary system\h\h
works in the exact same way as the decimal\h system, its just that once we reach one,\h\h
we’ve already run out of digits, and\h so we increment the place to the left.\h\h
Because there’re only two digits in binary:\h 0 and 1, each place is worth 2x more than\h\h
the last. So if the first place is worth 1, then\h this place is worth 2, then 4, then 8 and so on.\h\h
So let’s say we want to figure out what this\h sequence: 1101 would be in decimal. Well,\h\h
we can write it out as 8x1 + 4x1 +\h 2x0 + 1 x 1. And that comes out to 13.
Alright, now what I’d like to do is design\h something that’s able to add 2 binary numbers\h\h
together. So let’s work through a quick example\h by hand, say we want to add these two together:\h\h
starting on the right here, 1 + 1 is is two, which\h in binary is 10. So I’ll write the zero down here,\h\h
and then carry the one over up here, because\h we’ll need to add it together with these other two\h\h
to figure out what goes in this spot.\h By the way, this part that we wrote down\h\h
here straight away I’ll refer to as the sum\h bit, and this one up here is the carry bit.\h\h
Anyway, let’s continue 1 + 1 is 2, plus the carry\h is gives us 3 in decimal, or 11 in binary. So\h\h
I’ll write one over here - that’s the sum bit, and\h carry the other one over to the left. Now we have\h\h
0 plus 1, plus the carry bit is 2 again,\h so I’ll put 0 down here, and 1 up here.\h\h
This’ll just give us 1, so I’ll write that down\h here. Then 0 plus 0 is just 0, and finally,\h\h
1 plus 0 is one. In case you care to know,\h what we’ve just calculated here is 35 + 7.
It’s a little daunting to try start thinking about\h how we can wire our logic gates together to do all\h\h
of this, so let’s start small with adding together\h just two single bits. For example, if we’re adding\h\h
a zero and a zero together, then naturally both\h the carry bit and the sum bit will be zero.\h
But, if the first bit is zero and the second is\h one, or the other way around, then the carry bit\h\h
will be zero and the sum bit will will be 1. Finally if both bits are 1,\h\h
then the carry will be 1, and the sum bit will\h be zero. So if we look at the carry column here,\h\h
it might look familiar, because it’s actually\h an exact match with the AND operation.\h\h
The sum column on the other hand doesn’t match\h exactly with anything we’ve already seen, but it’s\h\h
quite close to the OR gate we created earlier, it\h just has a 0 in this last spot instead of a 1. So,\h\h
let’s take that OR gate as a starting point,\h and we just need to turn the output to a zero\h\h
when both inputs are one. So I’m going to take a\h nand gate, and connect it up here, and this will\h\h
check if both inputs are one, and then invert the\h result, so that it’s outputting zero in that case.\h\h
We can then use an AND gate to test if either of\h the inputs, but not both of them, is one. Let’s\h\h
test this quickly. With both inputs off, or zero,\h the output is zero. With just a single input\h\h
set to one, the output is one, but crucially\h when both inputs are one, the output will be\h\h
zero again. This operation has a special name as\h well, it’s called an exclusive OR. XOR for short.
Okay, so I now have an empty chip with two inputs,\h which we want to add together, and two outputs:\h\h
the sum bit, and the carry bit. So, we can use\h our new xor gate to calculate the sum bit of\h\h
the two inputs, and then remember that if both\h inputs are 1, then the carry bit should be one,\h\h
and so as we saw, we can simply use an AND gate\h to test for that. So that’s everything we need\h\h
to add two bits together, but of course in some of\h the steps we actually had 3 bits we needed to add\h\h
together, because there was a carry bit from the\h previous step to deal with. And in fact we could\h\h
think of these other places as having zero in the\h carry spot, so really we’re always adding 3 bits\h\h
together. So, I’ll introduce a third input to the\h chip over here for the carry input, and we need to\h\h
add this to the sum of the first two bits which we\h calculated up here. So, we can simply use another\h\h
XOR gate, and I’ll wire that up to that carry\h input, and to the sum of the first two inputs.
We’ll then need a second AND gate as well,\h because if sum of the first two bits is 1,\h\h
AND the carry input is one, then we’ll\h need to carry 1 to the next step.\h\h
So if either of our two AND gates detect that\h we should be carrying one to the next step, then\h\h
we’ll want to output one to the carry\h output, which I’ll do using an OR gate.
Let’s check that this is working properly. So\h with all of the inputs off, or zero, both the\h\h
sum and carry output bits should be zero. Then,\h if any single input is 1, the sum should be 1, and\h\h
the carry should be zero. So far, so good. Next,\h if any two inputs are 1, then the sum bit should\h\h
be zero, and the carry should be 1. And finally,\h if all three inputs are 1, the sum should be 1,\h\h
and the carry should be 1. And it looks like its\h all working, so I’ll give it a name, and then what\h\h
I’d like to do is take this ADDER we’ve made, and\h construct a 4BIT ADDER, capable of taking these\h\h
two 4-bit numbers that we have here as our inputs,\h and calculating the 4bit sum as the output.\h\h
I’ve added little displays by the way to\h tell us what all these values are in decimal,\h
just so it’s a bit easier to\h tell if this thing is working.
We’ll need four adders to construct this,\h and I’ll wire each one up to the outputs.\h\h
Then there’s a carry input here, just in case\h we want to string two 4bit adders together to\h\h
make an 8bit adder, for example, so that can\h go into the carry input of the first adder,\h\h
and then its carry output goes into\h the carry input of the next one,\h\h
and so on down the chain. Finally I’ll\h need to connect up the two 4bit inputs.
Let’s test this out, so right now we have 0 +\h 0 = 0, which is a good start. Let me try 1 + 1,\h\h
I believe 2 is correct! 5 + 1 is 6, and 7 + 1 is\h 8. So, it looks like we can add numbers together,\h\h
which is pretty cool. Of course with just 4 bits,\h if we try do 15 + 1 for example, it will overflow\h\h
to zero because we don’t have enough bits to store\h 16, and the carry bit will light up over here.
If we want to extend this to handle subtraction,\h we’ll need a way to represent negative numbers\h\h
in binary. I always assumed that this last spot\h was used to indicate the ‘sign’ of the number.\h\h
So what we have here would be positive 7, and this\h\h
would be -7. But of course you’d expect that if\h we added 7 to negative 7, we’d end up with 0,\h\h
but that’s clearly not the case here. So one way\h we could try thinking about this, is what would we\h\h
have to add to 7, in order to get 0 as the result? Well in order to get a zero in the first spot,\h\h
this would need to be a one, because\h remember 1 + 1 gives us a sum bit of zero.\h\h
Of course we also now have to carry 1 to the\h next spot. So now we know that there should be\h\h
a zero here, so that we’ll again have 1+1 giving\h us zero for our sum bit. And a carry of 1. So\h\h
we can deduce that there should be a zero here\h as well, and we can continue like this, to end\h\h
up with all zeros for our 4 bits. There is a one\h that ends up over here, but since we’re working\h\h
with just four bits, that can be discarded.\h So we’ve figured out that -7 must be 1001\h
That might seem weird, but it actually makes\h some sense if we think of this last spot as the\h\h
-8 place, because then we could write this out as\h -8 x 1 + 4 x 0 + 2 x 0 + 1 x 1. Which gives us -7.\h\h
Let’s start at zero and see what\h it looks like now if we count up.\h\h
So as you can see seven is now the\h largest number we can have with 4 bits,\h\h
and then it flips over to the smallest number,\h -8. And from there we have -7, -6, -5, -4, -3, -2,\h\h
and finally all ones would be -1. So it’s a\h bit of a funky system, but it allows us to add\h\h
negative and positive numbers together without\h any fuss, so it’s totally worth the weirdness.
There’s actually a simple two-step\h procedure for making any positive\h\h
number negative. Take the number positive 6\h for example, 0110 in binary. The first step\h\h
is to invert all the bits, so where there’s a\h zero we write a 1, and vice versa, giving us 1001.\h\h
At this point if we were to add these two together\h we’d obviously get all ones. We want it to be\h\h
all zeros though. And we saw a few minutes ago\h that if we take this, and just add one to it,\h\h
we’ll end up with zero for the 4 bits we’re\h interested in. This tells us that clearly our\h\h
inverted number is just one too little to give\h us all zeros. So the second step, as you might\h\h
predict, is to take the inverted number, and\h add one to it. So in this case we’d take 1001\h\h
and add one, giving us 1010. And if we look back\h at the number wheel, that is indeed negative six.
So, using that 4bit adder we built, we can of\h course add these two 4bit numbers together, but\h\h
if this subtract signal over here is on, then I\h want to subtract the second number from the first,\h\h
which we can do by making the second number\h negative. And remember we do that by inverting\h\h
the bits, and then adding one. So to invert the\h bits, we need something that looks at the subtract\h\h
signal, and if that’s off, the input bit should\h be unchanged, but if the subtract signal is on,\h\h
then the bit should be inverted. This table\h actually matches the Exclusive OR we made earlier,\h\h
so we can just use 4 of those to invert these\h 4 bits only if the subtract signal is on.
The last step of negating a number was\h to add one, so we can just feed the\h\h
subtract signal into the carry input of the\h adder, and that’ll do that for us. Alright,\h\h
I’ll quickly go ahead and wire up the rest\h of the inputs, and then output the result.\h\h
I also have these 3 extra outputs, and these are\h just for flagging some stuff about the result.\h\h
This one over here for example tells us if the\h result was zero, and we can test for that like so.\h\h
This other output tells us if the result\h was negative, which is true if our\h\h
-8 bit is set to one. And finally there’s\h the carry, which I can just take from her.\h\h
So these flags just give us some information about\h the result, which’ll be useful to us later on.\h\h
Let’s test if this actually doing what we want, so\h I’ll try doing 3 + 4, and that’s 7 so we haven’t\h\h
broken addition at least. Now I’ll try turning\h on the subtract signal, so we’re now doing\h\h
3 + negative 4, which is the same thing as saying\h 3 minus 4, and the result is indeed negative 1,\h\h
so that’s good. Let me try negative 2 - 4, and\h that gives us negative 6. Let’s see if it can\h\h
handle subtracting a negative number, so I’ll try\h negative 2 minus negative 4. Even that seems to\h\h
work, we get positive 2. I want to test one last\h thing - adding two negative numbers together.\h\h
And once again, the maths checks out. So this\h is going to be our Arithmetic and logic unit.\h\h
Although to be honest it doesn’t actually do any\h logic, that would just be things like doing the\h\h
AND operation on the inputs and outputting\h that for example, but we can expand this\h\h
later if necessary. For now I’ll call it ALU for\h short, and package it up into a tiny little chip.
So that’s going to be all for this first episode,\h I hope you found it interesting. In the next one I\h\h
want to look at how memory works, I’m very curious\h to learn more about that. Until then, cheers!