|
I stopped working on it when I got flustered with debugging my signed 16-bit floating point adder/subtractor.
I spent days going through logic tables to wade through the consequences of using signed numbers. It took me ages to convince myself I'd covered all the cases. I don't remember why, but I decided to re-order the operands such that the greater one was first. I had to then determine the sign of the output based on the signs of the inputs, knowing that, whether A + B or A - B, that A was greater, but may need to negate the result. I think this was because I was trying to not force a subtraction that actually resulted in a negative number, since the binary negative was not the same as a signed negative.
I never even got near the CPU-level logic. I was looking at how other people had clocked their minecraft CPUs and it was on the order of 4 seconds per clock tick. The trouble is that Minecraft only updates the game at 20 Hz. The graphics update and player-camera can move at much higher rates, but the changes made in the world are at 20 Hz. Furthermore, due to the cube-based nature of the game, any "compact" circuit has at most 4 I/O spots, so a 3-way AND gate is as big as you can go in a single game tick. Meaning that even optimizing a CLA (carry look ahead adder) design to optimize the ripple adder was a nightmare.
In the end, I decided that I learned what I intended to learn at the start, and I was getting really frustrated with the project.
What I wanted to know:
What happens in the first seconds of turning on a computer when somehow a current flowing through a wire and directing a switch can emerge into a calculator or a modern computer?
What I learned:
Meaning is where the designer decides it should be. The designer decided to give meaning to voltages. The designer decided to let no voltage mean a binary zero and some voltage to mean a binary one. That meaning is clearly a conceit. It is fabricated by the designer.
However, it is a clever conceit because it opens up the entire language of mathematics through binary numbers.
Using that conceit, we find that A XOR B gives the ones digit of A + B, and A AND B gives the carry digit of A + B, so long as A and B are one digit binary numbers. These gate functions existed outside of this binary conceit, but they become useful tools in a new light and context by the designer's choice.
So with that, the designer can extrapolate to an adder, and then a subtractor, multiplier and divider...
but wait. What just happened? adder of what?
Well, it doesn't actually add or multiply anything. It's just a machine that, when given a certain input, produces a certain output. Whatever meaning in the input and output is a conceit by humans. The designer has just been clever in how he's interpreting inputs to be numbers and outputting corresponding numbers, given a request for a certain mathematical operation - which is just another input, with no meaning in and of itself, and not even the binary numbers to lean on.
It's not that adding 1 + 0 = 1, it's that a certain kind of avalanche happens for each input, which leads to a specific output.
Whether its
no yes no [select avalanche type "add"] no yes no [avalanche] yes no no
or
010 + 010 -> 100
or
2 + 2 = 4
is merely a choice of how to display the inputs and output. There is no more meaning in the yes/no line than any other representation, except the readability to a human working with the machine.
Once we establish a clever abstraction which works well, we can stop considering it as individual pieces and consider a single thing.
So all those XOR and AND gates get lumped together into larger structures like half adders and full adders... which we then build to a clever working abstraction and when it works well, we step back again. We design integrated circuits whose specific internal gate structure isn't as important to us as the overall I/O logic of the chip. We make a bunch of those and put them together in new ways, and, again, when we get them working well, we step back and build ... etc.
This clevering up and stepping back took decades. The final product I use today bears the marks of all that prior cleverness embedded in the individual gates and structures from the smallest scales up to the whole computer.
By the time we get to a CPU, there's a whole underlying structure there of which we want to increase the functionality. The CPU doesn't rely on binary mathematics, but we still have this system of binary logic built up, and it's awesome, so we're going to run with what's right here. Again, the functionality of the CPU will drive us to create new conceits - imbuing meaning in 1s and 0s to fit our desired outcomes.
|