I've been teaching myself about CPU architecture for a while now and have successfully designed a couple myself. They were always based around microcode to drive the CPU's control lines.
The microcode is stored on one ROM chip and addressed by composing an address out of (1 = LSB):
- CPU flag states
Let's take my latest CPU as an example of how the address is constructed:
- Bank (3 bits) - There are 48 control lines in my CPU, so I need 6 bytes to store all control line states. The bank part of the address allows me to address 6 bytes in the microcode ROM.
- CPU flag states (3 bits) - I narrowed down my flags to zero, carry and compare. Need 3 bits to address all combinations
- Instruction (8 bits) - The instruction set requires over 127 op-code, so I choose to go with 8 bits.
- T-state (5 bits) - Some instructions take over 16 t-states to complete (complex ones like conditional CALL / RETURN) so with 5 bits I have enough room for up to 32 t-states
The final example microcode ROM address would look something like:
Now for my question:
In the above example, I seem to have reached the limit of what I can do with this approach. My microcode ROM address is 19 bits long and I have found one chip that supports it (
29C040) but it seems that I don't have a lot of options if I want a large address.
I'm thinking about my next CPU which will need more flags (negative, overflow, parity), and who knows, maybe even a few more control lines or an extra bit for T-states.
What would be a better approach to storing and addressing my microcode in that case?
The only thing I can think of right now is to:
- Add more ROM chips (would only free up 1 extra bit? per chip doesn't seem a good approach)
- Limit the instruction set (also, would only give me 1 - maybe 2 - extra bits)
- Limit the number of control lines, but that would allow for less control over the CPU...
I wonder how this is solved in professional, microcode-based CPUs and what I'm missing here.