We were last seen with the OPC-3 - a one-page computer with 16 bit data, 16 bit addresses, and 16 valid opcodes, as a hastily-inflated version of OPC-1, our CPU for CPLD. It felt good to have 16 bit words - lots of room in the instructions, and fitting a full pointer into any register or location should be a relaxing change from 8 bit computing. And if it keeps the machine simple, so much more chance of doing something good in just 66 lines of source. But now we want to think bigger: up to 128 slices in an FPGA.
What to do with a 16 bit instruction word? Well, it will never be big enough for a full-size operand, so with simplicity in mind, our first take is to have every instruction word be followed by an operand word. We have room in the instruction for a 6 bit opcode field, two predicate bits, and two 4-bit fields for the registers: source and destination. A 16-entry register file should feel very roomy, and will be very compact in FPGA too (each LUT can be a logic gate or a 64x1 RAM!) We'll put the PC in register 15, and then predicates (on zero and carry) give us conditional branches. We'll have r0 be zero, and a dummy destination.
We decided on an 'effective value' idea to make use of our opcode - we always add the operand value to the source register before proceeding with the two-operand operation. It turns out this single addressing mode gives us some near equivalents to several conventional addressing modes, and it's simple to describe and to implement.
Although we have 6 bits for our operations, our first cut only has 8 opcodes: load, store, add, nand, each in two flavours - direct addressing and indirect addressing.
Here's the first OPC5 spec. Remarkably, all this fitted happily into 66 lines of verilog, and 66 lines of python for an emulator.
(What happened to OPC4? It's reserved, in case we want to flesh out OPC3, which was quick and dirty.)