# 12-bit homebrew computer?

I'm planning my first homebrew computer. I'd like to perform calculations with 8-bit numbers. My op codes will be 4-bit numbers.

I'll be building this on breadboards so I'd like to keep things as simple as possible. This is my first attempt at anything like this -- the purpose is to learn.

So... is there such a thing as a 12-bit architecture?

Example: oooo dddd dddd where o-bits are for op codes and d-bits are for data

This system would have 256 addressable registers, each 12 bits wide. The contents of each register would be a 1-nibble op code followed by 1 byte of data.

Am I missing something, or does this sound reasonable?

I'm trying to build something like Ben Eater's 8-bit computer.

My interest in increasing the register size is motivated by the desire to have more than 16 bytes of RAM. Ben's instructions are 1 byte long, with 4 bits of op code and 4 bits of data. Thus, he can only address 16 bytes of RAM. I figure I can do a 4/8 split and address 256 bytes of RAM, while still finding his tutorials similar enough to be useful.

• Commented Jul 20, 2020 at 1:45
• Whatever you do prove it in simulation before you touch hardware. Having registers contain opcodes is a bit atypical, which only increases the need to prove your ideas out before you invest days wiring up something that may not be a very good idea. Commented Jul 20, 2020 at 1:54
• Thanks for the replies. In the example projects I've seen, people load programs into RAM. Thus, the registers contain op codes, no? Maybe I'm misunderstanding the process. Commented Jul 20, 2020 at 2:11
• "homebrew computer" may refer to 2 things: a new CPU with a 12b architecture, or a new motherboard based on a 12b CPU. A "computer" is usually the latter. If the latter then no there likely isn't a 12b CPU available to build your MB. If the former, then what do you intend to use to build a CPU? NAND gates? PLC? FPGA? Do you intend to build a compiler to generate the machine code to run on this CPU? Also it may be inefficient to embed data and opcode in a single word. Some opcodes have no data and some have 2 data words. So separate data and opcodes. Commented Jul 20, 2020 at 2:32
• @Peter I'd start with writing a functional simulation in your favorite programming language to prove that your architectural design is viable for computation. Then move to a logic simulation of an HDL expression. Honestly today, no one but people with too much time on their hands build such things from discrete parts, the only plausible justification is an FPGA/ASIC core meeting a unique or educational need. But you can use the tools which would be used to prove that, and later build in low integration TTL if you really really want to do so. So C or python, then Verilog or VHDL. Commented Jul 20, 2020 at 2:48

The baseline PIC series is very simple, has 8-bit data path and 12-bit instructions. For example, the PIC12F509. The complete instruction set can be summarized on only one page:

You can find a Verilog implementation of this core on Opencores.org

To make it simpler, you could consider 4-bits. There were many 4-bit microcontrollers, many had 8-bit instruction widths, a few had 16, and some like the Epson S1C60L02 had 12-bit instructions.

This particular Epson processor was produced in cooperation with a Japanese manufacturer of sensors to create the (now ubiquitous) super-cheap LCD-display thermometers based on precision NTC sensors. To top it off, they could operate from a single button cell using an internal charge pump to double the voltage. Quite impressive for 1990's technology.

If you're not stuck on 12 bits, you could also consider the 'epoch-making' (to use the Japanese-English term) TMS1000 and i4004 processors from TI and Intel respectively.

The Digital Equipment Corp PDP-8 was 12 bits.

Was used, in my experience, to replace the 6_bay SCATE Stromberg Carlson Automatic Test Equipment machine that used paper tape to control the programmable voltages and the testing pulses and the expected output waveforms.

This sounds like an interesting project; you’re bravely facing a number of limitations. Firstly you have 8-bit data, which has been well trodden over the decades. Depending on your architecture you may choose an 8-bit address space or larger. I feel that the most significant limitation will be that you have allowed yourself only 16 opcodes, so choose then carefully. I built a system that wasn’t a million miles different while at University in the ‘80s, and programmed the microcode into EPROM. Debugging using a string of LEDs and a push button as a clock is quite straightforward, this is an entirely feasible project.

Yes, 12-bit architectures have existed in the past.

A caution to take in discussing architectures is that people refer to bit-width to mean different things. Bit width can refer to your memory data width, memory addressing bits, your instructions, your registers, and your ALU size. Opcodes and immediates together can be wider than your memory bus. Registers can be wider than the ALU (though never smaller). Your ALU/registers can be wider than your memory (or in rare cases, smaller, such as the FPGA 80186 design using a 32-bit bus). So just saying, "I have an x-bit CPU" really isn't saying much. Even 8-bit CPUs tend to have a 16-bit bus to access 64K of memory. The 8088 was a 16-bit CPU, with 20 address bits, and an 8-bit memory and I/O bus.

So you can use 12-bit opcodes but might only need 8-bits internally. This is doable but awkward given the choices in memory available today.

Now, your opcode would only go into the instruction register. The other registers would not need to be 12-bits. Your opcode would drive your control signals that drive the ALU. That would not be all that hard to make using 7400-series chips. So 4 bits go into your instruction register, 8 go into your immediate data register. For some instructions, those 8 bits would be ignored.

Your user register size would be what you need to do the job you have in mind. For immediate operations, you'd only need 8 bits. But if you want to have 16-bits, then you can use 2 operations to fill a user register. If you want 12-bit user registers, that is fine, but it will be awkward. You don't need 12-bit registers since there is no reason your code needs to access the opcodes. You would not use them as part of any numbers you calculate.

256 registers are quite a bit unless you are designing more of a microcontroller and the registers are being used in place of RAM. Then, in that case, 12-bits makes sense. And when you are not using the 8-bits as an immediate, then it could specify the register (and assume your accumulator is the other register). But if you are not running software out of the registers, then storing the opcodes in them makes little sense. You could have a cache with 12-bit memory, but it makes little sense to store the opcodes in your user registers unless that is where you are running the code. Generally, they are fed one at a time from external RAM into the Instruction and Data registers or directly into the control unit.

As for addressing RAM, that can be addressed from 2 registers. 8-bit CPUs tended to use 16-bit addressing, so that is how they could have 64k. Usually, you had 2 index registers, one to address the low bits and one to address the high bits. It is often helpful to have 2 pairs of index registers so you can specify source and destination in memory if you want to use block instructions. Or in a homebrew system such as the Gigatron, a 2nd set of index registers would have been helpful since it bit-bangs things that controllers would generally handle. It runs at 6.25 Mhz to produce 1/16 VGA. If you want to double the clock speed and keep that resolution, you'd likely need NOPs between the video instructions, unless you can use that time for other purposes, and you really can't since you don't have the time to save what is in the registers, put other things in the registers, perform a task, and put it back. But if it had 2 sets of index registers, then one could be used for the video and the other set could be used for doing other things.

And speaking of old CPUs and even the Gigatron, something that is used is a zero page. So if you need to address only the first 8 bits worth of memory, then you have instructions that only use an immediate or 1 index register. But if you need to use the other memory, then you'd use instructions that use 2 (or more) registers to address the memory.

So these are some things to consider as you create your design.

Absolutely you can do this, 4 bits gives 16 instructions and that is more than enough for a project like this. 256 registers is fine if you wish, saves on needing much ram (will burn a lot of sram to implement of course).

This is all very doable. And there are more processors out there than you have time to study. Create your instruction set (which does somewhat require you go study a number of different processors say, pdp8, pdp11, 6502, msp430, arm, arm thumb, mips, the older pic's shown above, etc). But that is to get a feel for the minimal set you want to have without getting into the extreme one or two instruction thing. load and store, push and pop (or just use load and store and add and subtract), register based add, sub, and, or, not, xor, mov (between registers). And some instructions for immediates (which is where you generally run out of instruction space, but you could for example have two opcodes one for load uppper half one for load lower half 6 bits of immediate leaving 2 bits to pick the register or 4+2 to pick the register. so maybe four registers that can be used to load immediates into the register then register to register move to move that value to any of the other 252.

This is all very doable, and even better you can code it all up in a software instruction set simulator, and or HDL and run that on a simulator, long before thinking about actual hardware. You will want an assembler, a compiler is a massive project if you are asking questions like these, so avoid that. An assembler is quite easy to code, for 16 instructions should take an hour give or take.