* Harvard architecture with 16-bit instruction width, 64 word prorgram memory. * Two instruction formats * 16 registers (although not all instructions can use all 16 for all purposes) * Program counter is an addressable register (R7) * Memory base register (R8) allows up to 1Kword of RAM * Subroutine link register (R15) has next instruction address automatically copied into it whenever program counter is explicitly modified * Any instruction can be made conditional * Autoincrementing address mode for memory store operations * Also designed an implementation of a 6-bit ALU using a pair of GAL16V8 chips
Designed in Digital (a more advanced alternative to Logis
I wasn't really sure what software to use to do the schematic, though. Historically, I've tended to use OrCAD (I have an ancient version of it, but it does the job for most things I want to do, still), but I decided I wanted to do this project with free software if I could.
So I played with both gEDA and Kicad. I like Kicad better, but I can't say I'm a fan of its PCB autorouting ... it can't seem to cope with the complexity of routing signals to the TQFP100 package of the CPLD I plan on putting the register banks in. It's possible I may need to rework the pin layout to help it: I've tried to order the pins logically, but that's ended up with the register selection inputs for bank 0 and 1 being on the same side of the chip in the same sequence ... but they need to be connected to each other and that means each line needs to cross the others, which is creating a bit of trouble. Perhaps if I put bank 1 with a mirrored order it might work better.
When designing my register file, I kept in mind that I'd want this to be implementable in (mostly) TTL. I wanted to keep programmable logic to a minimum. But I also wanted to have a useful, flexible architecture, which would be easiest to achieve by having a lot of registers. I also wanted to keep the instruction set as minimal as possible, which was helped greatly by having addressable instruction pointer and link registers ... but that, along with wanting to be able to manage an instruction per cycle in the normal case, meant I needed to be able to update the registers at least 3 times per cycle.
The design I came up with was this:
Separate out the registers into two distinct banks
Double clock the register banks by detecting both high and low transitions of the input clock
Each bank needs to be able to support two simultaneous reads and one simultaneous write.
The ideal choice for implementing the register banks was using the 74172 IC. This chip has 8 registers, so with two banks would give me 16 total registers. The registers are only 2 bits wide, which means 3 per bank. And with a 20MHz cycle time, it'd be fast enough to potentially run the processor at a total of 10MHz, which is as fast as I'd hope to be able to get the rest of the design to work in any case.
Unfortunately, my usual sources for obsolete ICs have turned up blank on this one, leaving only the very expensive legacy spare parts suppliers (who seem to typically want around £5 per chip for these... and needing 6 of them for the design, that's a lot more than I want to spend here).
The more common 74670 won't do the job, because while it supports simultaneous read and write, it only has a single read port. The only other option is the CD40108 or CD40208, but both of those are too slow for my ambitions (at 5V, access time = 300ns; I really don't want to have 15V hanging around, but even then I'd only get 100ns, plus setup and hold times of 40ns on the modification cycle, so probably I'd struggle to get 3MHz out of the whole system using this chip).
So, programmable logic is the only way forward for actually implementing this. Fortunately, I've found a supply of cheap CPLDs. Unfortunately, they're in TQFP100 packages, which is beyond the capabilities of my PCB production process (I usually use toner transfer, but don't reliably get thin enough traces for the pins on these packages), so I suspect I'm going to have to get some boards manufactured for this. I've also never soldered a component with that many pins in such a small area before (I usually try to avoid anything < 1.27mm pin spacing, so basically SOIC/SOT packages are my usual limit, but these are 0.5mm). But at least they're cheap.
I've put both banks into a single CPLD package. And there were spare pins, so I also put the address increment circuit into the same package. There are still a few pins left, and quite a few LEs, so I'm thinking about integrating more, too, although I'm not sure what exactly. The design files are up on github.
I decided to go ahead and move a few parts into the CPLD that could reduce the chip count substantially without needing many more pins on the CPLD: there are 3 muxes that are used to override register selections (for read port a in bank 0, allowing register 7 - the instruction pointer - to be selected, and port b in bank 1, allowing register 8 - the memory base address - to be selected) and the input to the write port for bank 0 (allowing the incremented instruction pointer address to override the usual instruction result bus). I moved these three muxes into the CPLD, which will save 3 entire ICs in the design, but only needed 3 pins on the CPLD. I still have some pins left, but not enough for any buses and there aren't any more easy wins, so will probably leave it at this. Logically, this...