Author Topic: Home build microcode design  (Read 13702 times)

0 Members and 1 Guest are viewing this topic.

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19509
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Home build microcode design
« Reply #25 on: August 10, 2017, 07:01:14 am »
And that's why I use bread-boards. It's not my first "duh" moment when I have had to totally scratch or take many steps backwards to make the step forward work.  And that's really my purpose with this - realize how things like pull up/down impacts, how to read the data-sheets correct so things work and how to diagnose shorts through ICs. Even though I'm not done, I've picked up a lot of things that I'm now first reading about - and I've learned the hard way what is clearly documented in old TTL books.

Ah, been there, done that :)

You'll learn a lot, including how to work out what you don't know and how to think of quick tests to see if your guesses are/aren't right.

You may know this, but don't forget ceramic decoupling capacitors on short leads for each IC, and the "ground bounce" when many outputs switch simultaneously.

Happy hacking!
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #26 on: August 10, 2017, 07:59:52 am »
First how you look at things can make a difference.

Z80
  Most times you see the Z80 instruction byte value listed in HEX. Take a look at it in octal.  For 8-bits an FFH becomes 377. For most part the instruction set is very logical. Note that Z80 uses some byte values as pre instruction selectors to get a combination of 8-bit instructions and 16-bit instructions.

PDP-11
  To see the logic of this instruction set you also need to use octal. DEC created a PDP-11 programming care that has full instruction set on it.
http://www.montagar.com/~patj/dec/pocket/pdp11_programmingcard_1975.pdf
Note how logical the instruction set is if you read the bits from left(MSB) to right. This logical design also helps in micro code and in hardware.
As I said all visible registers( R0-R7) are the same, it's microcode that puts special names on them.

74182
  Not a big deal you have none. You can do it in logic if needed.

What I read in your last post sounds like you are making it harder then needed.

If you do not care about speed, you can get simple.
Start with a normal fast ram chip as store of your registers. You can get rid of a lot of chips doing this at a cost of more microcode steps.
A register to register move would become Move ram register to temp register, Move temp register to ram register. Simple but more time and microcode steps.

Now add your 181's
To start add two 8 bit latches for 181 data inputs and one 8-bit latch for 181 output. Later you should see that you can remove one or more of these latches, but this is simple start. 
Now you need microcode to move a register to 181-A latch & microcode to move a register to 181-B latch.
Microcode to setup 181's 5 control bits.
Microcode to latch 181 output in 181-output latch.
Microcode to move 181-output latch to register.
This can be a used for a lot of instructions.

The microcode is acting like a C function.
You can have a C IF or CASE statement as microcode.
All this says that you have variable length microcode sections

You microcode storage is cheap these days, bigger is better.
You need a microcode PC to know what microcode step your at.
Don't use a counter! Use a chips like a 273. Power up clears the 273.
With the output of 273 going to microcode store you select a row of microcode.
By having two fields in microcode for next microcode address, you could use a 1 of 2 selector for what appears at 273's inputs for next clock. You now have an IF in microcode.
by using larger 1 of x you can get a case statement or more choices. One of the inputs could be a field in CPU's instruction.
Look at PDP-11's double operand instructions. bits 15-12
Bit 15 is word or byte, a IF at some point in microcode.
You have 3 bits you can use to jump to different spot in microcode in the process of instruction decode..
Microcode can work from left to right processing each field in instruction.
All the different PDP-11 resister modes is just a step through the 181 or other microcode steps.

With how cheap your microcode store these days, there is no good reason to have every row of microcode filled.
In place of added logic, you can store logic results in microcode.
Nothing says that all inputs to 273's needs to always come from field in microcode.
Nothing says that all addresses to microcode store chips have to be the same.

So far you have ram chip for registers and 3  temp latches.
For a 16-bit CPU address bus you add 2 more temp 8-bit latches.
For 8-bit data bus add 2 more 8-bit latches, in & out.
One or more 8-bit latches for Instruction decode.
One for flags register.
Nothing says that you could not use more space in ram chip to store temp results. You might need this for Multiply, Divide, floating point, ect.

With a larger microcode store you can do a lot more with little added logic.
Start with your store being 64-bits wide. Go even wider if it can remove added logic.
As for rows, with 2 273's you could have 65.536.
You want a bunch of cheap & fast chips for your microcode store.
You could use rom or ram.
Some or all ram would let you have an instruction that loads microcode store from CPU memory or some other place. All ram is just using a little rom to do initial load..
Remember that with huge possible microcode store you can strap some address inputs to make it smaller.
The extra address lines can be used to select different microcode rows as next row address.

You said two 181's, You can build any size CPU you want, you just need to microcode process 8-bits at a time.
Where the PDP-11 uses 1 bit in instruction to select byte or word(16-bit), one more bit lets you have four sizes. Or you can do like Z80 where only some instructions can be a different size and put size field in microcode.

For teaching, think very wide but simple. From memory the PDP-11 microcode made things harder by using some bits in microcode for many purposes. Simple logic is easer to understand.

I should also mention that for the PDP-11there was a board that you could plug in that would allow testing/checking the logic with just a volt meter. Was more then just single step of microcode.
Also note on programming card "Processor Register Addresses"

Hope this might help some.
 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #27 on: August 10, 2017, 05:14:03 pm »
Thanks - this is a lot - I'll pick a few things out right now and address those. I'm woefully behind on creating diagrams of my current design, but since it changes every time I look at it, it feels like "why bother" every time. Diagramming takes me a long time since I suck at it (it wasn't until very recently I realized I could use labels to make it look much nicer). Anyway, I've asked quite a few questions about this project on the Beginners forum, and I explained there that I'm very hesitant posting exactly what I'm doing because I want to dumb into issues as it's how I learn.

That said ...

First how you look at things can make a difference.

Z80
  Most times you see the Z80 instruction byte value listed in HEX. Take a look at it in octal.  For 8-bits an FFH becomes 377. For most part the instruction set is very logical. Note that Z80 uses some byte values as pre instruction selectors to get a combination of 8-bit instructions and 16-bit instructions.
I did a LOT of Z80 in the 80ies - it's very rusty. If you think it will be helpful I'll find some datasheets and study it.

Quote
PDP-11
  To see the logic of this instruction set you also need to use octal. DEC created a PDP-11 programming care that has full instruction set on it.
http://www.montagar.com/~patj/dec/pocket/pdp11_programmingcard_1975.pdf
I never had a chance to use an actual PDP11 so I'm not really aware of it's basic CPU design etc. Von Neuman was pretty much the type of CPU I studied and knew how to design on paper - and it's pretty much the design I'm going with for my own home build.

I have two busses - 16 bit address, 8 bit data. I am aiming for 5 registers, right now I just have 2 using 273's and a 245 as buffer. The buffer is REALLY important, as it allows me to put a LED array right on the input to the buffer to show the value in the register. Nice and easy :)  I use 555s for the clock and a few logic ICs for control. I have a PC which is basic counters, the 181 for ALU, a data<->address bus transfer buffer, an address register, an instruction register and YES I do use a counter for the microcode offset - more about that later.

My plan was not to use a flag register. But instead simply hook the Z and C flags (the only flags I have) directly to two bits on the microcode address line. So a JMPZ would be at one address, and JMP would be a binary exponential offset from that - no fancy logic needed. Now, I know that reduces the number of OPs I can create but I don't think 64 OP codes is a limit for me (or it's one I can live with).  If that's a bad idea I need to understand why - and right now I find out when I apply it to reality and it sometimes makes me go "hmmmm - that was a dumb idea" :)

I use a simple 2Kx8 EPROM for microcode, I have a RAM chip + a EPROM on the address line. I use MSB on the address line to select between the EPROM and the RAM (the RAM only has 15 address bits).

Quote
74182
  Not a big deal you have none. You can do it in logic if needed.

I understood that the 182 is just for carrybit optimization - something I'm not really aiming at. Are there other functions I need to be aware of?

Quote
What I read in your last post sounds like you are making it harder then needed.

If you do not care about speed, you can get simple.
Start with a normal fast ram chip as store of your registers. You can get rid of a lot of chips doing this at a cost of more microcode steps.
A register to register move would become Move ram register to temp register, Move temp register to ram register. Simple but more time and microcode steps.
To be honest, reading this seems to be more complex than what I have?  Every register is connected to the data bus through the buffer. I READ from the data line without using a buffer, but I control the read clock through an AND gate with the clock and my "enable" signal. I share the AND gate between the registers. Now that I want to reduce the number of lines, I am rethinking that but it's a very basic design for now. So transferring data is a matter of enabling output on one, and WRITE on another.  Only a few registers are connected to the ALU directly.
[/quote]

Quote
Now add your 181's
To start add two 8 bit latches for 181 data inputs and one 8-bit latch for 181 output. Later you should see that you can remove one or more of these latches, but this is simple start. 
Now you need microcode to move a register to 181-A latch & microcode to move a register to 181-B latch.
Microcode to setup 181's 5 control bits.
Microcode to latch 181 output in 181-output latch.
Microcode to move 181-output latch to register.
This can be a used for a lot of instructions.
Thanks! This I need to revist to fully grasp. I was NOT planning on using registers - maybe a set of logic gates to reduce the number of bits to 2 or 3 (I only need shift, add/sub, compare for now. I'm not sure if I need to enable AND, OR, NOT etc. but I may. Again, I may need to compromise as I reduce the number of signals.

Quote
The microcode is acting like a C function.
You can have a C IF or CASE statement as microcode.
All this says that you have variable length microcode sections
So how would you implement this? I already explained about how I were going to implement the conditional jump statement. Nothing in the microcode will understand what "JUMP" means let alone a condition? I'm still reading about this, so if there's a good source to understand how you would wire microcode to do these kind of conditions I would very much like to learn.

Quote
You microcode storage is cheap these days, bigger is better.
You need a microcode PC to know what microcode step your at.
Don't use a counter! Use a chips like a 273. Power up clears the 273.

Why?? That's pretty much what I have. A 4 bit counter where I reset when the 4th bit is set (so it's a 3 bit counter). Seems to work just as I want it to? My plan is to add the RESET of the counter to a microcode bit so I can terminate a set of microcode steps if I don't use all 8 positions.  That seemed to be an easy design. What I'm stuggling more with is how to advance the PC every time (seems like every OP will have one or two steps that are EXACTLY the same, so there should be a way to implement this without using the EPROM for every OP).  Note, the counter I use has a built in register too - but it's only used to LOAD a particular number into the counter, so I don't use it for anything.

Quote
So far you have ram chip for registers and 3  temp latches.
For a 16-bit CPU address bus you add 2 more temp 8-bit latches.
For 8-bit data bus add 2 more 8-bit latches, in & out.
One or more 8-bit latches for Instruction decode.
One for flags register.
Nothing says that you could not use more space in ram chip to store temp results. You might need this for Multiply, Divide, floating point, ect.
If I have to add a bunch of other stuff to those latches, all I really did was built two busses instead of 1? What's the advantage here - since I'll have to latch/buffer between each register for transfer/load regardless?

Quote
With a larger microcode store you can do a lot more with little added logic.
Start with your store being 64-bits wide. Go even wider if it can remove added logic.
I'll stick to 4 chips for now (32bit) :) All the chips I've found with 16 bit data out are all serial instead of parallel and I cannot see how I can use that without a microcontroller.

Quote
As for rows, with 2 273's you could have 65.536.

This is where I goofed up earlier this week. You're talking about the number of OP codes not microcode?  The OP code is a simple 8 bit value which I use as an address line into the microcode storage. I add a few more bits for offset but that's about it. I have 4 8 bit EPROMS giving me 32 output for the same address.  The OP code is stored in the instruction register which is a 273 (it gets it's value from the bus, where the "read memory" buffer puts the value of the address on the address line, which comes from the PC or the address register).

Given that, I am a bit confused about the above statement. Hopefully you can see how my terminology works here, and what I'm attempting to do, and with that hopefully you can phrase it in a way I understand the difference. Right now it's only got me more confused.

Quote
You want a bunch of cheap & fast chips for your microcode store.
You could use rom or ram.
Some or all ram would let you have an instruction that loads microcode store from CPU memory or some other place. All ram is just using a little rom to do initial load..
Remember that with huge possible microcode store you can strap some address inputs to make it smaller.
The extra address lines can be used to select different microcode rows as next row address.
So speed is again not important. Strangely enough though, the RAM I have is SLOWER reading than my EPROM is :) The ram is about 55-70ns - the EPROM is around 30 (from memory). That's plenty fast for my purpose here. But you're right, if I used DRAM and have 5ns I would copy to RAM on boot. Absolutely.

Quote
You said two 181's, You can build any size CPU you want, you just need to microcode process 8-bits at a time.
Where the PDP-11 uses 1 bit in instruction to select byte or word(16-bit), one more bit lets you have four sizes. Or you can do like Z80 where only some instructions can be a different size and put size field in microcode.
So I'm struggling with that. I've been wondering how to create OP codes to do 16 bit operations given I only have 8 bits on the BUS. Not sure how I would feed 16 bit data to the 8 bit ALU and find a way to move the carry over to the second operation. Probably need another set of latches :(

Quote
For teaching, think very wide but simple. From memory the PDP-11 microcode made things harder by using some bits in microcode for many purposes. Simple logic is easer to understand.

I should also mention that for the PDP-11there was a board that you could plug in that would allow testing/checking the logic with just a volt meter. Was more then just single step of microcode.
Also note on programming card "Processor Register Addresses"

Hope this might help some.

So I would have to pick up PDP11 myself first :) I once illustrated how a CPU worked using paper notes that people carried from person to person. Each person was a function, and the people that moved the papers around were the bus :)  But it was again a basic Von Neuman + a bit of Z80 that I used back then (80ies - a looong time ago).

Thanks alot . while I may not have fully grasped everything you tried to say, I'll read it again and see how I can apply it.
 

Offline edavid

  • Super Contributor
  • ***
  • Posts: 3382
  • Country: us
Re: Home build microcode design
« Reply #28 on: August 10, 2017, 06:23:33 pm »
So speed is again not important. Strangely enough though, the RAM I have is SLOWER reading than my EPROM is :) The ram is about 55-70ns - the EPROM is around 30 (from memory).

Are you sure?  What is the EPROM part number?
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #29 on: August 10, 2017, 09:08:18 pm »
You need to register (I'm not going to use the term 'latch') the status bits for subsequent jump on condition codes.  These need not be the next sequential instruction and won't be when intermediate results are being saved to registers.

You will also use the carry flag when doing multibyte arithmetic which is how it was always done on the 8 bit microcontrollers.

You might consider registering bit 3 of the ALU output to assist with the DAA (Decimal Adjust Accumulator) instruction if you decide to implement it.  It's handy if you want to do decimal arithmetic.

I don't know if registering the accumulator parity is worth worrying about.  The 8080 types had JPE and JPO instructions.  I have only seen them used once.  Ever...

There are 74181s all over eBay but there is no good reason to implement a 16 bit datapath unless you really want to.  A whole lot of computing was done with 8 bit processors.

 
The following users thanked this post: bitman

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #30 on: August 10, 2017, 09:09:47 pm »
Quote
I did a LOT of Z80 in the 80ies - it's very rusty. If you think it will be helpful I'll find some datasheets and study it.

Your rusty knowledge is most likely ok,  You would just need to look at the instruction set byte values in octal.
Four 8 x 8 tables will show the logic.

Think of a picture of a (real)Z80 acting like a Z80 by running a program.
The (real)Z80 is changing IO bits just like a real Z80 changes what is on it's pins.
You have IO for each pin of the real Z80.
You would have two 8-bit ports for address bus
One two direction port for data bus or one in and one out port.
A port for control bus.
and more.
So you have less then 40 pins total.

The program on the (real)Z80 is acting like microcode. Due to the ports used,
The (real)Z80 memory is separate from the other.
the microcode does not have to stop to maintain proper values on any pin.
A change could be made so that the (real)Z80 would be acting like a PDP-11 or other CPU.

64 bit add on a Z80, 64 is just a number could be larger or smaller, 8-bit steps makes it easer.
64-bits is 8 bytes, so think of three arrays of 8 bytes.
Z80 does add A= A + __
To add larger like 64-bits you need add X = A + B
Note that Z80 has two Add instructions.
one is ADD while the other is ADC {add with carry}
You do a ADD on least byte followed by 7 ADC. Each ACD is adding in the carry from lower byte.
so
ADD X(0) = A(0) , B(0) ; Lsb
ADC X(1) = A(1) , B(1)
ADC X(2) = A(2) , B(2)
ADC X(3) = A(3) , B(3)
ADC X(4) = A(4) , B(4)
ADC X(5) = A(5) , B(5)
ADC X(6) = A(6) , B(6)
ADC X(7) = A(7) , B(7)

If you look at the 181, you have some pins that connect to next 181.
So one 181 can act like many if you save a copy of value that goes between the chips and use this value as input for next step with 181.
ADC is just using stored output of connecting lines of 181 as input to connecting lines.

Quote
My plan was not to use a flag register.
It is common to have one instruction modifying flags and then do more instructions before checking if a flag was changed.

Quote
I use a simple 2Kx8 EPROM for microcode, I have a RAM chip + a EPROM on the address line. I use MSB on the address line to select between the EPROM and the RAM (the RAM only has 15 address bits).
Quick look at this sounds like a mess. It looks like you are trying to put microcode into CPU memory.
You said you wanted to start with a 32-bit wide microcode and are building an 8-bit CPU.
Microcode store = 4x  2Kx8 EPROM 
You could add some ram to Microcode store 4x ___ ram\

Instructions and data for CPU should be separate.
A PDP-11 is von Neumann architecture to the programmer & users.
The logic and microcode of CPU is more Harvard architecture.
Normal Harvard architecture  is instructions (microcode) separate from data.
Data inside CPU is all CPU registers, the 181's and other registers that make logic simpler.

Quote
I understood that the 182 is just for carrybit optimization - something I'm not really aiming at. Are there other functions I need to be aware of?
N0, Just a way of speeding up 181's

Quote
To be honest, reading this seems to be more complex than what I have?

A bus is easer and quicker to wire and can do more at the cost of time.
Last post I used a normal ram to contain all the CPU registers.
This limits you to a read or a write.

With a lot more chips you could have a 374 as a register.
You would have an input bus and an output bus.
OE controls what goes on output bus.
Ck controls when input bus is latched.
You now have Read-modify-write, faster but many more chips needed.

You could enable OE all the time and use two or more chips like 244 to get data to the two inputs of 181. Again many more chips needed but you can gain some speed.
You have two output buses and one input bus.

So a Move using ram needs one latch to hold data between read cycle and write cycle of ram.
Using the ALU(the 181's) needs two read cycles and one write cycle with ram. And two or three latches.

Simple is using more microcode steps with wider microcode.

I used three temp registers for 181 in last post. Each would have a bit in microcode for when to clock the input in to the latch.
The one on output of 181 would have a additional bit in microcode for when to enable output.

Quote
Only a few registers are connected to the ALU directly.
This greatly limits what can be done.

8-bits you normally think a max of 256 instructions.
Z80 Shows you can get more then 256 instruction with a little change.

With more instructions you lose some by needing to read more instruction bytes but can have a huge gain by not needing to use even more instructions to do same job.
Look at difference of using Z80's DJNZ vs doing same thing with normal instructions.
A lot of instructions are used to work around only having one accumulator on Z80
Much easer and quicker on PDP-11 where every register is an accumulator.
With the register modes on PDP-11 any register can be used as a stack pointer.
As I said the modes are created by microcode and some use of 181's for some modes.
Quote
Quote
The microcode is acting like a C function.
You can have a C IF or CASE statement as microcode.
All this says that you have variable length microcode sections
So how would you implement this? I already explained about how I were going to implement the conditional jump statement. Nothing in the microcode will understand what "JUMP" means let alone a condition? I'm still reading about this, so if there's a good source to understand how you would wire microcode to do these kind of conditions I would very much like to learn.
[/quote]

What is a conditional jump in assembly or IF in C
Do next PC address or other PC address based on condition.
Next address is a field in microcode.
Other address is a field in microcode.
Condition just selects which is used.

Quote
Why?? That's pretty much what I have. A 4 bit counter where I reset when the 4th bit is set (so it's a 3 bit counter). Seems to work just as I want it to?
At first it looks easy. But it is not very powerful and very limiting.

Next address field in microcode lets you have any amount of microcode for an instruction. Lets you have common sections of microcode.
The Z80 checks for interrupt and other things before next instruction, Common microcode.
Some Z80 instructions do (HL) and access memory. Again common microcode.

Quote
Quote
As for rows, with 2 273's you could have 65.536.
This is where I goofed up earlier this week. You're talking about the number of OP codes not microcode?
No this is microcode bit rows or microcode steps.

Draw your self a box. The pins of a Z80 are the connections from inside box to outside of box.
Outside of box the Z80 looks like a Von Neuman processor.
The Z80 chip is a black box.
You are building what is inside the black box.

If you look around there are other 8-bit microprocessors in a 40 pin chip.

If you keep the insides of black box general in logic, then the microcode makes it a Z80, 8080, 8085, 6502, 6800, 6809
By using two bytes for an instruction you could have the PDP-11 instruction set with a 8-bit outside data bus. The hardware is there, this is just a microcode change.
Add more bits to address bus, this is a small change in hardware and you can add later gen Z80's

General here is simple logic that is very flexible.
My ram chip for registers  gives you simple for a huge number of registers.

From a teaching point of view, simple can be easy to understand.
Simple also would let you show small changes needed to expand to a 16-bit data bus and then act like a PDP-11
Or change to different instruction set.

Look at what you are doing now.
Remove Added logic to simplify  and get same result in microcode steps.

Quote
So I would have to pick up PDP11 myself first :) I once illustrated how a CPU worked using paper notes that people carried from person to person. Each person was a function, and the people that moved the papers around were the bus :)  But it was again a basic Von Neuman + a bit of Z80 that I used back then (80ies - a looong time ago).

For simple what is on programming card is all you need to know about PDP-11 instructions.
To get closer to an actual PDP-11 then you would have to add more knowledge about PDP-11
For example the PDP-11 34 used the unibus to connect CPU to rest of computer.
An LSI-11 23 used the PDP-11 instruction set with the Qbus and CPU bus to rest of computer.
The PDP-11 45 used unibus for IO and a different bus for memory. Basic instruction set is the same, 45 added some instructions.

Now with little hardware change, DEC created a VAX. Most VAXes could still run PDP-11 programs.

IF you do not understand something, please ask.
 




 

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #31 on: August 10, 2017, 11:59:05 pm »
Unless there is some software use issue, it would seem to me that any of the 8080,8085 or Z80 chips would be a real project to do with discretes.  The project just seems too big!

That's why I like BLUE.  I have never built it but I have been thinking about it as an educational computer for decades (like '75 and onward).  BLUE is a 16 bit minicomputer with a very limited instruction set and a very sparse set of registers.  There is no stack pointer, all addressing is direct and there are no internal user registers.  A very basic, easy to understand machine.  And, yes, it could be microcoded although the project itself is simple enough to do with a couple of dozen TTL chips.

https://www.alibris.com/Computer-Architecture-Caxton-C-Foster/book/1255656

Here's a simulator for BLUE

http://brainwagon.org/2011/07/07/a-basic-simulator-for-caxton-fosters-blue-architecture/

A very supercharged FPGA implementation - expanded instruction set, assembler, all kinds of stuff:

https://opencores.org/project,blue

If BLUE is too small, the INDIGO computer in the next chapter is much more complete.

BLUE and INDIGO are simply the colors of the boxes...
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #32 on: August 12, 2017, 12:58:42 am »
Here's a neat device to make registers.  It will do 16 registers of 4 bits so 4 of them make a 16 register array of 16 bits.  Lots of registers1

http://ltodi.est.ips.pt/lab-dee-et/datasheets/TTL/74189.pdf
 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #33 on: August 12, 2017, 02:42:53 pm »
So speed is again not important. Strangely enough though, the RAM I have is SLOWER reading than my EPROM is :) The ram is about 55-70ns - the EPROM is around 30 (from memory).

Are you sure?  What is the EPROM part number?

Nope :(  It was from memory, and unfortunately that has been scewed by reading almost a hundred data sheets over the weeks. I double checked and it's 200ns - not 20.  The chip I settled on was xls28c16bp - I gave up on the EPROMs that need different voltages for read and write. Beyond my capabilities right now to deal with so this one was much easier for me to use.
 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #34 on: August 12, 2017, 03:35:30 pm »
@C - wow, thanks for a very lenghty post. I've been away from my office for a few days, so I have a lot to catch up on here.
Lots of great ideas (never thought of the input+output buss - that would greatly simplify the settings and IO lines I need). I'm still not sure how you do logic with microcode. I understand that it's implemented once you have an answer, by executing the next or the following OP code. It's how you TEST for things in micro-code. The only way I know how to do that is use the flag input as part of the address offset in microcode, so offset X gives you "false" and offset Y gives you true. One would go ONE microcode instruction down, the other would go two.

And while I understand that not having a fixed number of steps for each instruction, I don't get how you can find instructions unless you use an index based on the OP code. I really would like to share parts of the microcode between all instructions just as you explained, but I'm struggling with how to design that. And the simplicity of the counter and a PROM seems straight forward and easy to explain too - too "convoluted" and part of the whole idea falls apart here.

What I am realizing is that to make a full explanation I should include the Z80 and perhaps the PDP11 or similar systems to illustrate how things can be optimized and made better. So again, THANK YOU for giving me lots of materials/reasons for reading :)

I'm keeping this short as I catch up on a lot of things. If I have any questions I'll definitely post again.
 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #35 on: August 12, 2017, 03:37:25 pm »
Here's a neat device to make registers.  It will do 16 registers of 4 bits so 4 of them make a 16 register array of 16 bits.  Lots of registers1

http://ltodi.est.ips.pt/lab-dee-et/datasheets/TTL/74189.pdf

I have to ask - HOW? How is it easier if I need to shift values and read two addresses for each byte?
I get the impression that I'm missing something very fundamental here. To me, it's a lot more complex with fewer bits?
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #36 on: August 12, 2017, 03:52:18 pm »
Here's a neat device to make registers.  It will do 16 registers of 4 bits so 4 of them make a 16 register array of 16 bits.  Lots of registers1

http://ltodi.est.ips.pt/lab-dee-et/datasheets/TTL/74189.pdf

I have to ask - HOW? How is it easier if I need to shift values and read two addresses for each byte?
I get the impression that I'm missing something very fundamental here. To me, it's a lot more complex with fewer bits?

Or perhaps I am missing something...

With two of these tied together (address field is common to both), you have 16 registers of 8 bit width (4 bits from each device).  With four tied together (again, the address fields are common), you have 16 registers of 16 bit width.  But the cool thing might be the fact that you could control just 8 of the 16 bit width so you could easily have something like register pairs (B-C, D-E, H-L) as well as true 16 bit registers like PC and SP.  You also have the ability to use the pairs as 16 bit registers.

The fact that the output is open collector means the register bank will be easy to gate on and off a bus without a MUX.

They are not true dual port RAM (pity) so you can't read the outputs and load the inputs simultaneously.

I wasn't aware that the devices are getting scarce.  They are in stock at Jameco but unless I could get a handful, I'm not sure I would design them into anything.  They do make the registers a little more compact.  Four chips gives 16 each 16 bit registers.  That's a lot in a small amount of real estate.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #37 on: August 12, 2017, 04:10:32 pm »
Your microcode has a program counter (for lack of a better name) that is simply incremented as you traverse the linear instructions.  Your microcode also has a next address field which is jammed into the PC instead of incrementing.  Somewhere in your microcode, you look at a condition (carry bit, for example) and decide whether to increment the PC or jam a branch address.  More often than not, the next address field is redundant because you are executing sequential instructions.  There may be some conditions under which the field can be used for other things.  It only needs to be an address when the code is going to branch.  But be careful!  The downstream stuff needs to know when to ignore the bits from the address field.

You could implement a stack mechanism for microcode and this would allow you to call subroutines.  You might limit the call depth to just one level and this might be quite adequate.  It is highly unlikely that microcode will involve recursion.  I have had to do this very thing in my FPGA project because the main FSA has a lot of calls to memory read/write and that happens to take two cycles.  So, I save the return state in a register before branching to the memory code and when the memory operation is complete, the memory code branches to the return state.  It's simple but it eliminates a lot of extra states in the FSA.

If you do the microcode properly, the PC is already pointing to the next instruction.  So, if you want to call something, you use the next address field to load the PC while simultaneously saving the current PC in the return address register.  In this scheme, the subroutine always returns to the instruction following the CALL and this is usually what you want.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #38 on: August 12, 2017, 04:28:16 pm »
I don't know if I have already recommended this book but here goes:

"Microprocessor Design Using Verilog HDL" available from Circuit Cellar:

http://www.cc-webshop.com/Microprocessor-Design-Using-Verilog-HDL-CC-BK-9780963013354.htm

This book is all about the Z80 and although your project won't involve Verilog, the important parts of the book are the early chapters where the author describes the hardware layout and uses spreadsheets to decompose all of the instructions into process steps.  I could see where this could be quite handy as an approach to writing microcode.

« Last Edit: August 12, 2017, 04:53:32 pm by rstofer »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #39 on: August 12, 2017, 05:00:06 pm »

In rstofer post, He used more chips to get wider. That is one way.

Look at it a different way
That is a 64 bit register but you work with blocks of 4-bits.
You have to do 16 steps doing this where a 64-bit wide one would be one step.

You asked " how to do big math"
How about 64-bit to match above.
You take 16 181's and connect them for 64-bit.
If you capture the data between chips in the center and use two steps, you could use 8 chips.  For the second step you are using the captured data as input.
If  you keep splitting the 181 ALU you get to
Use ONE 181, a latch and 16 steps.

A lot less chips but also > 16 times slower.

What is the difference between a 74F189 and normal ram memory?
The 71F189 has data inputs & outputs. This lets you use one step.
The outputs give your READ, what is connected gives you MODIFY & inputs gives you WRITE.
To use normal ram that is two steps.

 



 
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #40 on: August 12, 2017, 06:15:09 pm »

In rstofer post, He used more chips to get wider. That is one way.

Look at it a different way
That is a 64 bit register but you work with blocks of 4-bits.
You have to do 16 steps doing this where a 64-bit wide one would be one step.

You asked " how to do big math"
How about 64-bit to match above.
You take 16 181's and connect them for 64-bit.
If you capture the data between chips in the center and use two steps, you could use 8 chips.  For the second step you are using the captured data as input.
If  you keep splitting the 181 ALU you get to
Use ONE 181, a latch and 16 steps.

A lot less chips but also > 16 times slower.

The Intel 4004 took this approach - 4 bits.  We could get down to 1 bit in the degenerate case.  It's been done!  In fact, early numerical control did serial arithmetic from a magnetostrictive delay line memory.  The 1960s Bendix Dynapath is an example.

There is always a speed/complexity tradeoff.

Quote
What is the difference between a 74F189 and normal ram memory?
The 71F189 has data inputs & outputs. This lets you use one step.
The outputs give your READ, what is connected gives you MODIFY & inputs gives you WRITE.
To use normal ram that is two steps.

Separate input and output lines are interesting but timing is everything.  I haven't designed with them so I don't know if it is a help or not.  In any event, it isn't true dual port RAM so it is still limited.  It isn't truly clocked either.  It is more like latched.  I haven't checked the timing to see if it comes close to being clocked.  Setup and hold times will matter, I suspect.

One thing that is annoying and may disqualify the part is the fact that the outputs are inverted.  That's a real PITA unless there is somewhere that inversion is being done anyway.  The 74F219 does not invert the outputs.  Maybe that's a better idea.  They appear to be more readily available.

Don't overlook having two parallel banks of registers.  This way you can add a register to another register by addressing the banks separately and we get away from having a pair of MUXes to select the operands on both sides of the ALU.  Whenever a register is written, both banks are updated simultaneously.

I haven't really thought through how the register chips would work.  The idea would be to lay out a datapath and then start writing pseudo microcode and see how it works out.  Maybe it doesn't work out at all.  Do we register the ALU output?  Do we write inverted data? It matters...

Doing nibble width operations on bytes or byte width operations on words requires more microcode and, worse, it gets in the way of the discussion.

In my view, the Z80 itself gets in the way of the discussion.  There are too many instructions, too many addressing modes and the byte/word stuff is a stumbling block.  That's why, for an educational tool, I would look at a far simpler CPU.  Complexity can come later.

Here's another thought:  If the CPU doesn't need 16 registers, load constants like +1 -1 and 0 into other registers so that something like INC and DEC can be implemented in the ALU without having to MUX in some other values.

You get these values in the registers by having the microcode force the ALU to create them.  Or maybe they come from the next address field.  There will no doubt be a MUX on the inputs to the register bank to select between the ALU and other possible sources.  No reason one of the MUX inputs can't be the next address field.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #41 on: August 12, 2017, 08:12:58 pm »
rstofer
I have done 1 bit & magnetostrictive delay line memory

First there was registers
then chips like 189
Z80 calls it a "Register Array"
Others call it a "Register File"

DM74LS670 3-STATE 4-by-4 Register File
http://eeshop.unl.edu/pdf/DM74LS670.pdf

Think all are getting hard to find, Today a little slower and you can use ram with Read-modify-Write cycles.
Faster is pay the dollars for 2 or more port memory.

If you want less logic you use more microcode and get smarter how it is used.
More serial processing in place of more logic parallel.

Think about the ALU, here an 181 was mentioned.
If all control bits are in microcode, a section of microcode can do anything the ALU is capable of doing.
On the PDP-11 all 8 visible registers could be used as input or output for ALU
If my memory is correct 16 to 1 mux where used not 8 to 1
The 8 extra inputs to mux allowed a simpler CPU logic and more capabilities for microcode.
Flags register
Address bus register
Data bus register
Control bus register
Instruction register
Microcode input register
Temp register
I think these were the other 8 inputs to mux

The microcode could do more then PDP-11 instruction set allowed.
Options to add instructions by adding more microcode.
There was an option in later generation PDP-11's to add a writable microcode so you could create special instructions.

Each microcode step was timed by a TTL delay line.
Fast logic paths in CPU were faster.
Memory cards closer to CPU were faster due to less bus delays. Nanosecond faster memory meant a faster computer.

 




 


 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #42 on: August 13, 2017, 12:47:12 am »
Lecture 6. Microarchitecture II - Carnegie Mellon - Computer Architecture 2015 - Onur Mutlu


This might help
 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #43 on: August 14, 2017, 10:08:03 pm »
Somewhere in your microcode, you look at a condition (carry bit, for example) and decide whether to increment the PC or jam a branch address. 
Right - that's the issue. HOW? I understand that OP codes are basically conditional based on the state of a flag which is set electronically by ALUs or simular circuits to indicate the state of one or more values in registers.  Since microcode is "no more" than simply turning on/off signals, the question is how does microcode READ and ACT on the values it reads. This is one of the topics that once I understood what was being done (not the "how") it helped tremendously as a programmer to make better and more optimized code.  C made sense, expressions etc. - so I get that part, now I'm at the part where I'm trying to deal with the "how" side of things.

The way I'm planning (in the last few weeks I've had but very few hours to think/look at this) is to let the flags control the offset of the microcode being executed. That way, when executing a JMZ instruction, there are two locations in the microcode - one that is executed when there's no Z flag, and another section when the Z flag is set.  Each section is statically defined, but the choice of what section to execute is done using the flag input. It means I will reduce my 8 bit OP codes with one per per flag, which is a LOT. I have two flags, so that reduces the number of OP codes to 64 in my case. I can make due with that, even though I may have to not implement features I thought about.

Quote
More often than not, the next address field is redundant because you are executing sequential instructions.  There may be some conditions under which the field can be used for other things.  It only needs to be an address when the code is going to branch.  But be careful!  The downstream stuff needs to know when to ignore the bits from the address field.\
Correct - the preamble to each OP is the same, so that repeats regardless of the OP being executed. And there definitely are aspects of the microcode that is shared but it would be one or two cycles tops - an internal jump would not be optimal. So I could of course use an indirect reference to a table of instructions, but I'm not sure I see the exact advantage here. If values are given as parameters to some OP codes it's going to be very hard code to do to use indirect pointers based on a base offset instead of just the current OP code. This is however something I've thought about but well, I think it would destroy the whole idea of what I'm doing to go that deep.

What I was thinking about doing was the "set PC to count", "load PC address content onto bus", "read OP from bus into instruction register". This needs to happen for EVERY instruction. If I can find a way to having that done independent of the actual content I have, it would make the design much cleaner.

Quote
You could implement a stack mechanism for microcode and this would allow you to call subroutines.  You might limit the call depth to just one level and this might be quite adequate.  It is highly unlikely that microcode will involve recursion.
I'm fascinated if this is how Microcode is done today. That to me is too complex for microcode but something you implement a bit higher in the stack. 

Quote
  I have had to do this very thing in my FPGA project because the main FSA has a lot of calls to memory read/write and that happens to take two cycles.  So, I save the return state in a register before branching to the memory code and when the memory operation is complete, the memory code branches to the return state.  It's simple but it eliminates a lot of extra states in the FSA.
You would need to load every register into memory - how do you ensure that ALL states are saved? The moment you change your memory register, you lost state?

Quote
If you do the microcode properly, the PC is already pointing to the next instruction.  So, if you want to call something, you use the next address field to load the PC while simultaneously saving the current PC in the return address register.  In this scheme, the subroutine always returns to the instruction following the CALL and this is usually what you want.
Correct - it would be GREAT if I can make it so the PC is always "ahead one" so the LAST thing every instruction needs to do is advance the PC by one. THAT I'm definitely struggling with right now.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #44 on: August 14, 2017, 10:57:15 pm »
My understanding is you want something you can teach.
For this simple is better. A very slow system would be fine and allow you to show how you can add to the basics to make it faster.

To do simple you need to use the ALU a lot for many things.
Think you are using 2 74181's
The 181 gives you four outputs that normally go to the next 74181. You need to latch these outputs.
You will use them as inputs to Control logic to change microcode path.
You will later feed these latched outputs in to LSB 181 so that you can do bigger number math. A 1 of 2 data selector would let you do this.

When you look at a Z80 chip, every pin on that chip is a gated input or the output of a Latch.

so microcode to get an instruction is like this in microcode.
1. Copy PC to Address register
2 set Control bus register to read from memory and turn on M1
3 check for wait input If true go to 3 else goto 4
4. copy memory data in register to IR register.
5. end memory cycle by seting control bus register..
You now have instruction in IR register.
6. enable some bits of IR register to modify part of next microcode address.
For Z80 thus is D6 & D7 so microcode does a four way jump.
You might jump to
100 in microcode for D6 & D7 = 00
200 in microcode  for D6 & D7 = 01
300 in microcode  for D6 & D7 = 10
400 in microcode  for D6 & D7 = 11

If you look in Z80 instruction set 01 is LD R,R

Here is where using a RAM chip for registers reduces logic a lot.
200 Enable IR D2-D0 to register ram, read mode
201 latch output of register ram
202 ensble IR D5-D3 to register ram. enable register ram output latch, Write mode
203 You have now completed the move between registers.

Watch the Video.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Home build microcode design
« Reply #45 on: August 14, 2017, 11:15:44 pm »
Look at Z80 instruction set
D7 & D6 = 10 is 8 bit arth & logic
300 Enable IR D2-D0 to register ram, read mode
read from register ram latch in second register ram output latch
Enable register A address to register ram, read mode
latch latch in first register ram output latch
Enable IR D5-D3 tp modify next microcode address

You now have inputs to ALU set and have different areas in microcode to set control input to ALU. As you will need ALU in many places in microcode, ALU Control is a field in microcode.

Jump to common area and write output of ALU to address of register A in register ram

In keeping it simple, use microcode to have ALU to add 1 to PC for next PC address.


 
« Last Edit: August 14, 2017, 11:19:12 pm by C »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #46 on: August 15, 2017, 06:14:42 am »
Somewhere in your microcode, you look at a condition (carry bit, for example) and decide whether to increment the PC or jam a branch address. 
Right - that's the issue. HOW? I understand that OP codes are basically conditional based on the state of a flag which is set electronically by ALUs or simular circuits to indicate the state of one or more values in registers.  Since microcode is "no more" than simply turning on/off signals, the question is how does microcode READ and ACT on the values it reads. This is one of the topics that once I understood what was being done (not the "how") it helped tremendously as a programmer to make better and more optimized code.  C made sense, expressions etc. - so I get that part, now I'm at the part where I'm trying to deal with the "how" side of things.

First of all, consider building the PC with a string of binary counters such that a simple increment doesn't take an adder.

Suppose there is a MUX with two inputs, the PC or the Next Address Field.  Suppose there is a bit in the microcode that combines with a particular flag (again, say carry) that tells the MUX which address to use for the next microcode instructions.  If the MUX is told to use the next address field, parallel load this into the PC. 

It is up to you whether you increment the PC at the end of an instruction sequence or just after the fetch.  I tend to do it after the fetch such that the PC points to the next instruction.  Then if I have to copy the value into a return address register for a CALL instruction, the return address is already correct.

Something like that...
Quote
Quote
You could implement a stack mechanism for microcode and this would allow you to call subroutines.  You might limit the call depth to just one level and this might be quite adequate.  It is highly unlikely that microcode will involve recursion.
I'm fascinated if this is how Microcode is done today. That to me is too complex for microcode but something you implement a bit higher in the stack. 

Quote
  I have had to do this very thing in my FPGA project because the main FSA has a lot of calls to memory read/write and that happens to take two cycles.  So, I save the return state in a register before branching to the memory code and when the memory operation is complete, the memory code branches to the return state.  It's simple but it eliminates a lot of extra states in the FSA.
You would need to load every register into memory - how do you ensure that ALL states are saved? The moment you change your memory register, you lost state?

I must have messed up the explanation, it just isn't that complex.  As you process certain instructions, you will find subsequences of microcode repeated throughout.  To reduce redundancy, or just guarantee that a subsequence is coded properly once instead of a dozen times, you create a subroutine.  It takes no parameters and probably doesn't return a value but is simply a sequence of microcode.  If you implement a CALL instruction in microcode, all you need to do is save the return address and branch to the called routine.  When it's time to return, jam the return address into the PC.

In my case, there were several places in the FSM where I needed to read or write memoty as part of processiing an instruction.  I decided to make these sequences subroutines because RAM the operations were two states and when using external SRAM, they were one state.

Just a one level stack so subroutines can't be nested.

As you start to code the various instructions, you may find the idea useful.  Or not...
« Last Edit: August 15, 2017, 07:23:11 am by rstofer »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #47 on: August 15, 2017, 08:03:55 am »
On the IBM 1130, instructions come in two formats:  Long and short.  A short instruction does not use an address in the following word so I'll skip those.  The Long Format instruction has a word following the instruction word (like LXI <addr> except the instruction is also 16 bits).  Then there are index registers to add to the address and these are not really registers, they are located at addresses 1..3 of RAM.  There is also indirect addressing, I'll skip that...

An instruction/operand fetch might go like this:

1) Fetch the word at the PC and increment the PC. Memory Read required
2) Decode a long instruction so fetch the address field at the PC and increment the PC.  Memory Read required
3) Notice that the address is to be indexed so fetch the index register from memory.  Memory Read required.
4) Add the index register to the previously fetched address field
5) Use this effective address to fetch the operand .  Another Memory Read required.

By the time you add in indirect addressing and short format addressing, operand fetch is quite a project!

To just fetch the operand (as shown above) takes 4 memory reads.  In the case where each read takes two cycles, I wind up with 4 extra states (4 are required as a minimum if I inline the code) or I can CALL a subroutine in appropriate places and use far fewer states.  Further, as the Memory Read changes over the life of the project (from BlockRAM to SRAM to PSDRAM), I only had to change the code in one place rather that at every subsequence requiring memory access.

In an FPGA, all states will need some kind of name.  Extra states means I need to invent more names.

In the case of an FSM, all I had to do was save the next state in a register (the return address register), and set the next state to the CALLed routine.  I had to leave the present state and go somewhere, it might as well be to the code that handles memory access.  It's the same transition cycle in any event.  When the called routine is complete, it just branches to the return address.  This is all part of the last state of the memory access code.  No extraneous states are used.


It costs nothing extra to call and return while saving a LOT of states.

These are all FSM operations and have little relationship to anything higher in the code stack.  The user doesn't know and doesn't need to know how instructions are decoded and executed.

For microcode, the CALL is just going to be a bit in the word storing the microcode PC (not the PC register) into a temporary register and jamming the address of the called function (the next address field) into the microcode PC.

At some point, the microcode looks an awful lot like a higher level of coding and the architecture looks a lot like a higher level view of a CPU because even the microcode has a program counter and a (somewhat limited) stack.

Earlier I mentioned testing a bit (carry) and causing the MUX to select the next address field or the PC as the address of the next microcode instruction.  I was talking about just 1 condition.  There can be many conditions that are tested (carry, zero, minus, plus, parity, etc as well as inverted tests like not carry, not zero, not minus, etc.) and the effect is the same.  You take a branch if the condition is met or you execute the next microcode instruction if the condition is not met (or vice versa).  So, your microcode word has to have bits to select the conditions (AND the condition with the test bit) and some external logic combines these conditions (big OR gate) to direct the MUX.  You need to consider the possibility that you will test multiple conditions in a single instruction.

Until you lay out the instructions and start writing pseudo microcode, it's hard to see what the architecture should look like.  Do you need a MUX for the microcode address?  Do you need a MUX in front of the parallel load feature of the microcode PC?  How many inputs will these MUXen require?  (I just invented MUXen.  I derived it from VAXen which are multiple VAX machines).  You can't know these things until you see exactly what is required to execute instructions in the shortest number of cycles.
« Last Edit: August 15, 2017, 01:00:10 pm by rstofer »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Home build microcode design
« Reply #48 on: August 15, 2017, 01:26:41 pm »
One other input to the microcode address MUX will be some permutation of the op code.  Let's say you have 256 opcodes and, on average, they take 8 states.  Build an address with leading zeros, the op code shifted left 3 bits and 3 trailing zeros.  Right after instruction fetch, you just use this value as the microcode next address.  You branch and simultaneously load the value into the microcode PC.  At some point, you need to increment the PC before the next microcode fetch.

If executing an instruction takes more than 8 states then there will be a branch to some overflow area where code is just tacked to the end.  OTOH, if you have a lot of space, maybe you allow 16 states per instruction.

There will be variations on this idea as you see how the instructions are encoded.  It's usually not random and similar instructions tend to have adjacent op codes.

Now your MUX for the microcode address has at least 4 inputs:  The PC, the next address field, the return address and this computed GOTO address.

Notice that the address is being used to cause a branch while simultaneously being loaded into the PC.  This saves a state.  Otherwise, you would have the MUX load the PC and then in the next cycle perform the actual branch.

You'll see how this works when you start laying out some of your instructions.

Over at opencores.org, they have the T80 project which is an FPGA implementation of the Z80.  There might be something interesting in the code.  I have used that core to run CP/M and Pacman.  It definitely works!

I could see some advantage to coding this thing at a very low level in C.  There would be a huge switch statement that emulated the microcode.  This might be my very first approach to the problem.  Get the CPU working in software.  Things like MUXen would be functions, their control would come from the pseudo microcode in the switch statement.  C is a lot faster than wire-wrap.

There are simh simulations for the Z80 but I don't know anything about them.

http://www.classiccmp.org/cpmarchives/cpm/mirrors/www.schorn.ch/cpm/intro.php

 

Offline bitmanTopic starter

  • Supporter
  • ****
  • Posts: 299
  • Country: us
  • Open Source Guy jabbing with Electronics
Re: Home build microcode design
« Reply #49 on: August 15, 2017, 07:00:36 pm »
Until you lay out the instructions and start writing pseudo microcode, it's hard to see what the architecture should look like.

I think the crocks is right here. My approach for my "design" is as simple as "have the microcode do exactly what you do when manually setting the switches". Which means, I haven't really felt I needed to plan out the microcode - I was going to assign each input to a bit, make a piece of code on a PC where those bits were represented by symbols, and simply setup the microcode as I wanted it there (ie. I would set the enable flags based on what I would do manually).  What I thought was my only challenge was to figure out how to so a simple conditional jump based on the two flags I have, and the "simple" solution I came up with seems to work on paper, however timing wise I'll have to try it out to be sure.  My "only" issue has been I have way more "enable" bits than I expected to have, so I am trying to reduce them with gates first, and THEN I'll assign them to microcode bits.

Thanks to you and the others here, I will do a bit (a lot!) more reading and reconsider things. I am still aiming for simple so what I would definitely want to avoid is very advanced microcode that is hard to explain the first time.  I had my 71 year old father here the other day and sat with him showing how it works (with no microcode). All the LEDs showing state and what was "where" really helped him understand basic concepts of stuff he wasn't aware of, and that's part of what I'm aiming at here. Secondly, I want to prove to myself I can do this basic stuff with electronics, and not pretend I would design any level of modern processors with pipelining and optimization - that's definitely NOT the level I'm at knowledge wise but I love to learn how it's done.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf