Max's Cool Beans
Comment
KarlS
You are right ... rotate then mask off bits for left shift, etc.
Max the Magnificent
Instruction set for a 4-bit HRRG Steampunk Computer
Clive Maxfield
4/13/2011 8:36 PM EDT
Sad to relate, I haven’t gotten around to completing Part 4 of my Heath Robinson Rube Goldberg (HRRG) Steampunk Computer mini-series this week (Click Here to see Part 3), but this is because I’ve been pondering its instruction set…
Before we plunge into the fray with gusto and abandon, I should note that an executive decision has been made that the HRRG Steampunk computer will be a 4-bit machine; specifically, it will have a 4-bit (1-nybble) data bus and a 12-bit (3-nybble) address bus. [Remember that “Two nybbles (or ‘nibbles’) make a byte,” which goes to show that engineers do have a sense of humor … it’s just not very sophisticated.]
Why a 4-bit machine? Actually, there are two main reasons. The first is that I always wanted to construct, and play with, a 4-bit computer. The second is that I want the final machine to be educational and understandable to a wide range of folks, including younger guys and gals like high school students. A 4-bit machine is, in many ways, easier to wrap one’s brain around than a larger machine. Of course such a machine also poses some limitations, but that’s all part of the game.
Now, before we proceed, I think I should bring you up to speed with at least part of the “Master Plan” (for future reference we will call this “Plan A” so that no one gets confused). My co-conspirator on this project is my friend Joe Farr in England. Joe and I have been involved in a number of crazy schemes over the years. My specialty is coming up with wild and wacky ideas; Joe is a hardware and software guru who can build or code just about anything; so combined we make a crack team that’s ideally suited for something as weird and wonderful as the HRRG.
But, as usual, we digress… consider the image shown below. This is a screenshot of a software emulator Joe created to represent a physical machine he’s in the process of constructing (Click Here to see a larger, more detailed version of this image). Joe created this emulator in order to experiment with different architectures and instruction formats and suchlike.
This is, of course, a significantly more complex machine than the HRRG, but I think it will give you a better understanding of where we plan on taking all of this. The starting point will be to create a software emulator for our HRRG Steampunk Computer (hereon after to be known as “The Beast”). As soon as this emulator is up and running, we will make it (along with associated tools like an assembler and suchlike) freely available for anyone who wants to play with it.
As part of this, we will also define an external interface that will allow portions of the virtual machine to be swapped out with their physical counterparts in the real world. The idea is that anyone, from individuals to groups of high school students, will be able to build their own physical cabinets containing things like the system clock or a block of ROM or RAM. For example, you might decide to construct a cabinet containing as little as say one 4-bit word of memory. This could be implemented in any technology of your choosing, such as relays, vacuum tubes, juggling hamsters… You could then connect this cabinet to your computer and run it in conjunction with our virtual machine.
Personally I am very excited by all of this, but first we have to make some basic decisions. As I previously mentioned, Joe and I have agreed that The Beast will have a 4-bit data bus and a 12-bit address bus. So, our next step is to decide on the underlying architecture of the machine, and part of this is to specify its instruction set and addressing modes.
One important consideration is to ensure that the machine is defined in such a way as to make it as easy and intuitive to implement as possible. It would be more than possible to create something in the virtual emulation world that would be a pain in the rear end to implement in the real world, and we certainly don’t want that, do we?
So, we are currently bouncing ideas back and forth across the Internet like ping pong balls. Do we need a stack or can we get by without one? If we do decide to support a stack, then which (how many) stack-based instructions will we offer? Will we support a simple interrupt structure or not? Should we support the concept of an index register? If we use only a single 4-bit nybble to represent an instruction, this gives us only 16 possible instructions, so which instructions do we have to support and which can we live without?
As a simple example, consider the logical instructions AND, OR, XOR, and NOT. That’s four instructions, which is a quarter of the total number we can support. Do we need them all? Well, we could probably live without the NOT (which simply inverts all of the bits) because we can achieve the same thing by XOR-ing with all ones; for example, %0110 XOR %1111 = %1001 (where the ‘%’ character is used to indicate a binary value).
In fact, we can go one step further, because we can actually live without an XOR, whose operation can be replicated using AND and OR instructions. To be perfectly honest this was a new one on me – Joe told me about it yesterday. Consider %0101 XOR %0110 = %0011. So how could we replicate this using AND and OR instructions? Well, if we AND our original values we get %0101 AND %0110 = %0100. And if we OR our original values we get %0101 OR %0110 = %0111. Finally, if we subtract the result from our AND from the result from our OR, we get %0111 – %0100 = %0011, which is the same as the result from our original XOR… clever, huh?
In fact there are so many tradeoffs like this. Here’s another one – if you have only two instructions to devote to shift/rotate type instructions, is it better to have shift-left and shift-right, and to then use the results to emulate rotate instructions if required, or vice versa?
Of course we could overcome our self-imposed 16-instruction limitation by supporting multi-nybble instructions. Two nybbles (8 bits) would allow us to support 256 instructions; three nybbles (12-bits) would allow us to support 2,048 instructions, and so forth. But where’s the fun in that? Also, we want to abide by the KISS principle (“Keep It Simple, Stupid”), so we’ve stuck a stake in the ground and said: “One nybble for the instruction, plus extra nybbles for operands like constant values and addresses (always assuming that we decide to support constant values, of course).”
Joe and I are just at the stage of bouncing ideas back and forth via email at the time of this writing. Our original ideas were so different to each other’s that it really opened my eyes as to the various possibilities (I’m not happy that his ideas are better than mine, so I’m in the process of “tweaking” them while he’s not looking [grin]).
But the bottom line is that this would be a great time for you to chime in with your thoughts on this matter (you can add a comment to this blog, or you can email me directly at max@CliveMaxfield.com). At this early stage of the game, anything and everything can contribute to “the mix.”
When we’ve gathered all of the ideas and made some decisions, I will pen an article describing the way in which we swung back and forth on this and how we finally arrived at … well, whatever solution we finally arrive at (grin). Until then, have a good one!
Before we plunge into the fray with gusto and abandon, I should note that an executive decision has been made that the HRRG Steampunk computer will be a 4-bit machine; specifically, it will have a 4-bit (1-nybble) data bus and a 12-bit (3-nybble) address bus. [Remember that “Two nybbles (or ‘nibbles’) make a byte,” which goes to show that engineers do have a sense of humor … it’s just not very sophisticated.]
Why a 4-bit machine? Actually, there are two main reasons. The first is that I always wanted to construct, and play with, a 4-bit computer. The second is that I want the final machine to be educational and understandable to a wide range of folks, including younger guys and gals like high school students. A 4-bit machine is, in many ways, easier to wrap one’s brain around than a larger machine. Of course such a machine also poses some limitations, but that’s all part of the game.
Now, before we proceed, I think I should bring you up to speed with at least part of the “Master Plan” (for future reference we will call this “Plan A” so that no one gets confused). My co-conspirator on this project is my friend Joe Farr in England. Joe and I have been involved in a number of crazy schemes over the years. My specialty is coming up with wild and wacky ideas; Joe is a hardware and software guru who can build or code just about anything; so combined we make a crack team that’s ideally suited for something as weird and wonderful as the HRRG.
But, as usual, we digress… consider the image shown below. This is a screenshot of a software emulator Joe created to represent a physical machine he’s in the process of constructing (Click Here to see a larger, more detailed version of this image). Joe created this emulator in order to experiment with different architectures and instruction formats and suchlike.
This is, of course, a significantly more complex machine than the HRRG, but I think it will give you a better understanding of where we plan on taking all of this. The starting point will be to create a software emulator for our HRRG Steampunk Computer (hereon after to be known as “The Beast”). As soon as this emulator is up and running, we will make it (along with associated tools like an assembler and suchlike) freely available for anyone who wants to play with it.
As part of this, we will also define an external interface that will allow portions of the virtual machine to be swapped out with their physical counterparts in the real world. The idea is that anyone, from individuals to groups of high school students, will be able to build their own physical cabinets containing things like the system clock or a block of ROM or RAM. For example, you might decide to construct a cabinet containing as little as say one 4-bit word of memory. This could be implemented in any technology of your choosing, such as relays, vacuum tubes, juggling hamsters… You could then connect this cabinet to your computer and run it in conjunction with our virtual machine.
Personally I am very excited by all of this, but first we have to make some basic decisions. As I previously mentioned, Joe and I have agreed that The Beast will have a 4-bit data bus and a 12-bit address bus. So, our next step is to decide on the underlying architecture of the machine, and part of this is to specify its instruction set and addressing modes.
One important consideration is to ensure that the machine is defined in such a way as to make it as easy and intuitive to implement as possible. It would be more than possible to create something in the virtual emulation world that would be a pain in the rear end to implement in the real world, and we certainly don’t want that, do we?
So, we are currently bouncing ideas back and forth across the Internet like ping pong balls. Do we need a stack or can we get by without one? If we do decide to support a stack, then which (how many) stack-based instructions will we offer? Will we support a simple interrupt structure or not? Should we support the concept of an index register? If we use only a single 4-bit nybble to represent an instruction, this gives us only 16 possible instructions, so which instructions do we have to support and which can we live without?
As a simple example, consider the logical instructions AND, OR, XOR, and NOT. That’s four instructions, which is a quarter of the total number we can support. Do we need them all? Well, we could probably live without the NOT (which simply inverts all of the bits) because we can achieve the same thing by XOR-ing with all ones; for example, %0110 XOR %1111 = %1001 (where the ‘%’ character is used to indicate a binary value).
In fact, we can go one step further, because we can actually live without an XOR, whose operation can be replicated using AND and OR instructions. To be perfectly honest this was a new one on me – Joe told me about it yesterday. Consider %0101 XOR %0110 = %0011. So how could we replicate this using AND and OR instructions? Well, if we AND our original values we get %0101 AND %0110 = %0100. And if we OR our original values we get %0101 OR %0110 = %0111. Finally, if we subtract the result from our AND from the result from our OR, we get %0111 – %0100 = %0011, which is the same as the result from our original XOR… clever, huh?
In fact there are so many tradeoffs like this. Here’s another one – if you have only two instructions to devote to shift/rotate type instructions, is it better to have shift-left and shift-right, and to then use the results to emulate rotate instructions if required, or vice versa?
Of course we could overcome our self-imposed 16-instruction limitation by supporting multi-nybble instructions. Two nybbles (8 bits) would allow us to support 256 instructions; three nybbles (12-bits) would allow us to support 2,048 instructions, and so forth. But where’s the fun in that? Also, we want to abide by the KISS principle (“Keep It Simple, Stupid”), so we’ve stuck a stake in the ground and said: “One nybble for the instruction, plus extra nybbles for operands like constant values and addresses (always assuming that we decide to support constant values, of course).”
Joe and I are just at the stage of bouncing ideas back and forth via email at the time of this writing. Our original ideas were so different to each other’s that it really opened my eyes as to the various possibilities (I’m not happy that his ideas are better than mine, so I’m in the process of “tweaking” them while he’s not looking [grin]).
But the bottom line is that this would be a great time for you to chime in with your thoughts on this matter (you can add a comment to this blog, or you can email me directly at max@CliveMaxfield.com). At this early stage of the game, anything and everything can contribute to “the mix.”
When we’ve gathered all of the ideas and made some decisions, I will pen an article describing the way in which we swung back and forth on this and how we finally arrived at … well, whatever solution we finally arrive at (grin). Until then, have a good one!
Navigate to related information



Max the Magnificent
4/13/2011 8:48 PM EDT
I tell you, my head is currently spinning with ideas...
Sign in to Reply
DCSchmidt71
4/15/2011 2:37 PM EDT
Even though a nibble machine, consider using an 8-bit instruction op-code. Perhaps 14 4-bit instructions can embed a nibble operand, while the remaining 2 4-bit op-codes provide another 32 secondary op-codes. This can be scaled up with more primary op-codes, or down with fewer.
Sign in to Reply
Max the Magnificent
4/16/2011 4:38 PM EDT
The fun thing is to set limitations and then work around them -- if we had 8-bit opcodes we might just as well make an 8-bit machine...
Sign in to Reply
MindTech
4/15/2011 4:38 PM EDT
By excluding the XOR you can implement it using an AND, OR, and *SUB* instruction. Of course you could skip the SUB instruction if you had a 2s compliment (NEG) and an ADD. The NEG could be replaced with a 1s compliment (COM) and an ADD (1). But the 1s compliment instruction as already discussed can be replaced with the XOR.
So if you skip the XOR you need to implement at least 1 otherwise unnecessary instruction (SUB, NEG, or COM), as well as ADD which I assume you were going to include anyway.
Leave XOR in.
Sign in to Reply
Max the Magnificent
4/16/2011 4:40 PM EDT
I agree -- XOR is just too useful. One criteria for me is how many times you use an instruction -- I use XOR a lot. Joe says we don't need a CMP (compare) instruction, but I'm fighting for that one also :-)
Sign in to Reply
DPWARDEN
4/15/2011 9:29 PM EDT
Good mental exercise. I've never thought about 16 instructions--I would assume only 1 register (the accumulator) and two flags, carry and zero.
For load/store, I think you would need:
LOAD A,(addr) (load from memory)
LOAD (addr),A and (store to memory)
LOAD A, immediate. (load constant)
For math, I would suppose:
CC (clear carry),
ADDC A,(addr), (add w/carry)
SUBC (addr), (subtract w/borrow)
COM A (1's complement),
OR A, (addr),
AND A, (addr)
Shifts/rotates could be done with
ROTL A and
ROTR A;
(CC could make these shifts.)
Jumps need
JUMP NC, (addr) and
JUMP NZ, (addr);
...unconditional jumps can be handled by CC inst. I would also lobby for:
CALL (addr) and
RET.
That's 15 instructions. INC and DEC can be handled by storing 1 in memory and performing ADDC or SUBC.
Sign in to Reply
Max the Magnificent
4/16/2011 4:42 PM EDT
I started on the basis of just having an accumulator -- also not having an interrupt structure or a stack -- but Joe says that if this is supposed to be educational then we should have a primitive interrupt structure and a stack. I think you'll be surprised with what we've come up with ... more soon -- Max
Sign in to Reply
pomartel
4/16/2011 2:24 PM EDT
You can replace AND, OR and NOT with NAND (AND followed by NOT)or NOR (OR followed by NOT).
For instance,
M0 AND M1 is
LOAD A, M0
NAND A, M1
LOAD M2, A
NAND A, M2
; A has M0 AND M1
M0 XOR M1 is
LOAD A, M0
NAND A, M0
LOAD M2, A
LOAD A, M1
NAND A, M1
NAND A, M2
;A now has M0 OR M1
LOAD M2, A
LOAD A, M0
NAND A, M1
NAND A, M2
LOAD M2, A
NAND A, M2
; A has M0 XOR M1
Basically you can reduce the number of opcodes needed if you are willing to perform more operations. If you want to really have a minimal set of arithmetic/logic operations, you can build ADD up out of XOR (and AND) and so do all the arithmetic and logic ops with just NAND.
Sign in to Reply
Max the Magnificent
4/16/2011 4:44 PM EDT
This is another thing Joe and I are bouncing around. On the one hand we could make the CPU very minimalist and then use more instructions ... but this might not be so much fun (and not so intuitive) for beginners.
Or we can have a more sophisticated CPU that supports more interesting instructions.
Watch this space...
Sign in to Reply
clematis
4/16/2011 10:15 PM EDT
When your 4-bit processor is all done and debugged, why don't you send it over to Ken Chapman at Xilinx? He has already created a VHDL design of an 8-bit processor called the "Picoblaze". If you haven't seen/used the Picoblaze you should check it out - it's very cool. Perhaps your 4-bit design could become an even simpler "Femtoblaze".
Sign in to Reply
KarlS
4/19/2011 11:48 AM EDT
To really get down to basics:
And
Or
Left shift by 1
Right Shift by 1
Invert/Complement
Load
Store
Jump on true/false
Call
Return
Then you can add the hard way
And
Or
And (Or with ~And) for Xor
Left Shift the And
Repeat the above to propagate the Carries for a Ripple Carry Adder
Then when you get tired of hand coding the Least Instruction Set Computer (LISC) you will appreciate Subroutines and figure a way to Call the Add subroutine with parameters.
The Jump needs some work, but it would use flags like the old mainframes. Do a compare to get Gtr and Less. Conditional Jump on False that tests Gtr and Less for false would jump on Equal and Jump on True would jump if not equal.
Any logic function can be done with enough And, Or and Inverts .. why you can even build a computer.
Sign in to Reply
Max the Magnificent
4/19/2011 12:52 PM EDT
Ah, but is it better to do left / right sifts or left / right rotates :-)
we've been noodling furiously on this -- I will reveal all in my "How To" article tomorrow -- Max
Sign in to Reply
KarlS
4/20/2011 9:15 AM EDT
You are right ... rotate then mask off bits for left shift, etc.
Sign in to Reply