8-bit CPU: Putting it together
Looking at modules I have built so far, I realized that I have almost all I need for a complete computer. Long time ago I built Clock module and Program Counter. I've just updated Output module, There's ALU, 2 general-purpose registers, Flags register. Also I have RAM module and MAR register. I even have an Instruction Register. What's missing? Control Logic, of course!
Instead I have a Test Module that can toggle the control lines as required. It also can read and write the Bus, and get the value of Flags register.
One thing it could not do yet, was to read the contents of Instruction Register, Arduino (Uno/Nano) does not have enough pins for that. I've used 595 serial-in, parallel-out shift registers to expand outputs, but there are different type of shift registers available: parallel-in, serial-out. One of those could load 8 bits from IR at once and then shift them bit by bit into Arduino's MISO pin.
Luckily, I found an old 74HCT165 in my drawer. Not sure what project that was meant for, no matter that it's HCT, it should work.Adding PC and Output register to the existing build was simple enough, just some wires to connect. Turns out, I do not need Clock Module yet, as for now it's more convenient to use Arduino-provided clock. Also, I decided to put it in a box to make it easier to move (and protect from a cat). It starts to resemble a bowl of spaghetti, but since it is a temporary build, I'm not going to tidy it up much.
Now, if I upload machine code into RAM, reset PC and send proper control signals for fetch cycle, it starts to resemble the real thing. PC is counting, instructions are fetched. Contents of IR and Flags serves as the only input for decision-making in Control Logic, Test Module should emulate that.
At first I wrote some Python code to match the inputs to my microcode definitions and send appropriate control words. It worked, but was exceptionally slow. Round-trips over UART from Python to Arduino and back just took too much time.
Eventually I wrote a script that dumps microcode into C arrays and wrote similar logic to interpret the instructions on Arduino. That way it ran at acceptable pace, I even had to insert delays to slow it down a bit.
The CPU still is not autonomous, but we are slowly getting there. Now it really runs a program from memory, albeit using very convoluted "control logic".
Eventually I'll rebuild that to proper EEPROM based one, but there's more pressing issue: how to produce machine-code binaries? It may be fun to hand-assemble simple counter or Fibonacci sequence code, but I already have a Sieve of Eratosthenes implemented. Sure, I want to run that, but it's more than 100 instructions long. Hand-assembling that would be quite tedious.
Comments
Post a Comment