Sunday, April 7, 2019

New Project: 7400 Logic Calculator

My newest project is a calculator using 7400-series logic chips. There are a lot of really neat computers built using these parts, and I would like to try building a relatively small one that fits into a calculator. My idea is to keep the design as minimal as possible, since even a simple computer of this type could get pretty big quickly. There are a few things I have been thinking of for a long time that should help me save space.

A few years ago, I got interested in building one of these computers using lookup tables on a flash or EEPROM chip to implement a simple ALU and got as far as putting a 4x4 bit look up on table on an EEPROM. Eventually, I gave up the idea since at least one other person had built essentially the same thing that I wanted to build, and I didn't want to totally reinvent the wheel. Recently, I got interested in the idea again when I saw Ben Eater's excellent series on building an 8-bit breadboard computer. It uses an EEPROM for microcode, which is what I had considered for other projects. Another neat project I looked at is the Gigatron, which is a different RISC-type design that I don't think uses microcode. So far, I have been able to get a fairly simple version of what I want to build going in the Atanua simulator:


After I got this going, I already started looking for ways to make the circuit smaller and fit into a calculator sized case. First, I have four registers, which would make programming a lot more convenient, but I would leave out to save space. Also, I have two microcode ROMs, like in Ben Eater's design, although I could survive with just one if I latch out some of the control codes from the program ROM.

The major consideration at the moment is what balance of registers will allow me to do everything I need to do in the smallest space possible. The first decision is what type of program counter to use. Each of the 74HC193s I'm using add an additional four bits of address space. Three of these chips would give me a 12 bit address space, which is four kilobytes. Since I want to use the same space for RAM and ROM this would probably mean 2k RAM and 2k ROM. The Tiny calculator project I have been working on is already up to almost 8k and uses a much more space efficient design, so I will definitely need all four counters to have 16 bits of address space. So, the first thing I know I will need is four of these chips for the program counter:


Each chip is DIP16, which means it has 8 pins on a side and the outline is 4 pins wide, so the chip itself takes up 32 holes on a regularly spaced grid like protoboard. Each of the 16 pins takes at least one more pin each for the wire that connects to it. This brings the total number of occupied holes to 48 and the overall count of all four counters to 192. This gives me a rough idea of the maximum number of chips I could fit on the board. This time I went with bigger 9x15cm boards since I think I will need every bit of space I can get. They are 33 by 54 holes, so I have 1782 holes per board and I hope to fit everything on two boards, which is 3564 holes. At most, I would be able to fit 74 DIP16 chips on the two boards, although a lot of chips are bigger than DIP16.

The program counter chips will drive the program ROM and need to be loadable from the address bus in order to enable jumps and load data from ROM. One fast but large design would be to add buffers to Z state the program counters since they don't have an OE pin, which would allow a second set of buffers to drive the ROM when needed. Since I am using 74HC574s for all my buffers, I won't need anything extra to Z state them. This setup would look like this:


This takes up at least 432 holes! This would be over 10% of my available space. Since the program counters need to be loadable, it's possible to use them to specify the address for loading data from ROM too. This would require saving the program counter address, using the counters to load data, then restoring the program counter address, which is a much slower process but saves two chips. Two 74HC574s save the 16 bit program counter address and output it on the data bus, when necessary, to load it back into the counters afterward:


To load a 16 bit address from memory to do indirect memory accesses, one byte of the address has to be buffered while the second byte is fetched. It can't be stored in the counters yet since they need to hold the address of the second byte of the 16 bit address. It also can't be stored in the accumulator since the accumulator needs to be able to hold a value that can be stored in RAM. One alternative would be to allocate a buffer just for holding the first byte of the address:


Now we have an accumulator, a program counter, and a way to access data indirectly, which should be enough to implement anything I need as long as I can use an ALU to manipulate addresses. Considering that I would need two extra 74HC245 chips to allow the program counter to be output to the data bus for subroutine jumps, this design uses four less DIP20 chips and is 240 holes smaller than the faster idea I had above. Since the accumulator and address buffer chip already take up two chips, a better alternative would be to replace them with 74HC670 chips, which have four 4 bit registers per chips. Two of them would give me four 8 bit registers which is enough room to store an accumulator, one byte of the address buffer, and two other registers for something else like a memory index. Unfortunately, this would add another buffer chip in order to be able to transfer data between the four registers. Replacing that buffer with two more 74HC670s would allow register to register transfers and give four more bytes which might be used for a 16 bit base pointer and index. Whether I go with two 74HC574s or four 74HC670s will depend on how much room I have to squeeze everything in.

No comments:

Post a Comment