Two threads are better than one…

The EightThirtyTwo ISA – Part 10 – 2019-11-16

One of the main goals with a pipelined CPU is keeping the pipleline as full as possible at all times. The biggest obstacle to this goal is the existence of ‘hazards’ – situations where what’s about to happen at the beginning of the pipeline depends on an outcome that’s yet to be determined further down the line. This is a particular weakness of the EightThirtyTwo CPU: because we have only eight registers, and because many operations involve the tmp register, there’s a good chance that any given instruction will depend on the result of the previous one. One way around this is to use results forwarding where, for example, a result calculated in the ALU can be sent directly to the ALU’s inputs for the next instruction rather than being first written to and then read again from the register file.

I haven’t yet attempted to implement this for the EightThirtyTwo. Instead, I’ve attempted something far less sane for a lightweight CPU – dual-threading!

Continue reading

INTER-handling-RUPTS

The EightThirtyTwo ISA – Part 9 – 2019-10-28

Having managed to get the CPU working well enough to run a Hello World program, I’ve since persuaded it to run the LZ4 decompression program I posted a week or two back, too – and was pleasantly surprised to find it running happily at 133MHz on my DE2 board.

I’ve been pondering how best to handle interrupts on this CPU, and realised that I’ve painted myself into a bit of corner by using the tmp register as a link register when branching; this means that without adding some kind of temporary storage register or stack logic especially for the task, I can’t change the program flow externally – such as in response to an interrupt – without losing the contents of the tmp register.

Continue reading

Some real-life code…

The EightThirtyTwo ISA – Part 7 – 2019-09-26

Last time I said I would show some real-life code for this new ISA. I’ve already shown some very simple “Hello World” code, and I’m now in the slow, careful process of implementing a CPU to run this – and exploring the wonderful world of HDL simulation in the process! But in the meantime, by far the best way to get a feel for how well an instruction set works is to write some actual code for it, and see which issues and limitations you bump into.

Continue reading

Evolving the ISA…

The EightThirtyTwo ISA – Part 6 – 2019-09-15

In my baby-steps towards a working VBCC backend I now have something complete enough at least to send the text “Hello world!” to a UART. There’s a long way to go yet before it (a) works and (b) produces code that’s even remotely efficient, but it’s a start. In the process I’ve found and addressed some shortcomings in the ISA, and made a few tweaks to the instruction set and encoding.

Continue reading

Assembly language is all very well…

The EightThirtyTwo ISA – Part 5 – 2019-08-24

Before proceeding very much further with the EightThirtyTwo design I wanted to have some way of generating code for it from a higher-level language, just to get a better feel for which instructions are useful for compilers, which will be pretty much unused and where I might find any gaps that make the generated code unneccessarily clumsy. The most obvious route to this goal is to find a C compiler that can be easily retargetted to a new architecture. (Anyone who’s attempted this before is probably laughing now at my use of the word ‘easily’!)

Continue reading

How to avoid writing an assembler

The EightThirtyTwo ISA – Part 4 – 2019-08-14

In order to experiment properly with the instruction set I need some way of assembling and running programs. Luckily I wrote a ZPU simulator some time ago, and this is easily re-purposed for the EightThirtyTwo instruction set. The simulator is part of the EightThirtyTwo project on github.

In the longer term, to be useful this ISA will need a fully-functional toolchain, which means writing a backend for GCC – or perhaps LLVM, or maybe even lcc, vbcc, or some other C compiler. That’s going to be a rabbit hole in its own right, however, and for now we just want a quick and easy way of turning an assembly listing into a binary file of bytes ready for execution.

Continue reading

Nailing Down the Instruction Set

The EightThirtyTwo ISA – Part 3 – 2019-08-12

My initial plan for the EightThirtyTwo ISA was to define eight general purpose registers, and use the ninth “temp” register as an accumulator. Immediate values would be assigned here, as would the result of any arithmetic operations. The best way to test the concept is, of course, to write some actual code. So let’s see what simple looping looks like with this concept:

  li 99 // (needs two li instructions since 99 doesn't fit within a signed 6-bit value)
mr r0
.bottles_of_beer:
// take one down, pass it around
li 1
sub r0
mr r0
cond NEQ // Disable execution if we've reached zero
li .bottles_of_beer
mr r7 // if not, do another iteration
cond EX // return to normal execution

That’s not too bad – weighing in at 10 bytes – way better than MIPS, but 68K beats us easily thanks to its dbf instruction. Let’s try something more involved…

Continue reading

Choosing the Instruction Set

The EightThirtyTwo ISA – Part 2 – 2019-08-10

In part 1 I talked about why I wanted to design my own microprocessor, and how I’d settled upon an architecture using eight-bit instruction words and eight addressable thirty-two bit registers.

Because our instruction words won’t have room to encode two registers in them, each instruction will only take one operand – so we need a way of supplying a second operand to instructions such as add, xor, load immediate, etc. For this I’ve defined a ninth register, which I’ll call temp. This register isn’t addressable via the instruction word – it’s simply used implictly wherever it’s needed. One of the key decisions to make will be whether the result of arithmetic instructions will go the nominated register or the temp register.

It’s not entirely clear without giving the matter some thought (and ideally writing some test programs) exactly which instructions we need to implement, so initially I’ll list all the possible instructions that come to mind, and then figure out what’s mandatory, what’s optional, and what’s most beneficial in terms of keeping code size down, in the hope that we can hit our target of 25 instructions.

Continue reading