JACA 1 & 2 Homebrew CPU

JACA - Just Another CPU Again
Homebrew CPU, starting by a simple POC 4-bit CPU on circuit simulator soft. (done), then 8-bit (in progress)

Similar projects worth following
The ultimate goal is to make (physically build) from scratch a complete computer as simple as possible, but powerful enough to run old games such as Tetris, Pong, Arkanoid or Snakes on a LED matrix (probabily 16x16).

Edit: check it out for the latest version of project files on GitHub:

The ultimate goal is to make (physically build) from scratch a complete computer as simple as possible, but powerful enough to run old games such as Tetris, Pong, Arkanoid or Snakes on a LED matrix (probabily 16x16).

In order to do this (and have something working earlier) I decided to make first, as a POC, a very simple 4 bit CPU in a simulation software (Logisim 2.7.1).

This 4 bit CPU has the barely minimum to do some useful computing, in this case I chose a multiplication of two 4 bit numbers.
Hardware specifications:
-4 general registers of 4 bits (A to D)
-RAM memory of 16 words of 8 bits
-initially just 8 instructions, with 3 addressing modes (no instructions of memory access at this point) (*)
-fixed instruction size (8 bits, one cell of memory)

This last point I consider vital for the simplicity of the circuit, since I need only one access to the memory to get all the instruction, making the Fetch fase the simpler I could imagine.

There are only two steps cycles per instruction, Fetch and Execute. Two clock lines are used, one to properly set the inputs of the devices and other to trigger the clocks and commit the changes.

The ISA is heavilly influenced by that of MSX, which I used to program back in the early 90's. That was an 8 bit computer hugelly popular in my country (Brazil), despite almost unknown in the rest of the world.

It uses a Load/Store architecture, meant that all operations are done over the registers, the only instructions to access memory are Load/Store to or from a register. There is is no way to add two numbers in memory directly, for example. As all other design decisions that was for the sake of simplicity.

(*) Later in the project I could squeeze even more the ISA and insert two instructions to make memory access, but this is not necessary to the initial goal (multiply two registers).

Initial research and study on the subject was done late March 2017, I spent maybe two weeks choosing the simulation software (there are lots of options, even web based ones). Circuit design itself started one month ago, and, as of May is, I'd say 80% done. The pace seems very slow, but I could manage to effectively work on the project just 1-3 hours/week...

PS: the name JACA is a (bad) joke with the portuguese name of the jackfruit, common in Brazil.

  • 2 × 74LS181 4 bit ALU
  • 1 × 62256 32k x 8 bit SRAM
  • 4 × AT28C256 Memory ICs / EEPROMsEEPROM 32k X 8 bit
  • 13 × 74ALS874 8 bit register with async CLR and 3-state outputs
  • 10 × 74LS154 4 to 16 demux

View all 7 components

  • Update project status

    Andre Baptista10/03/2017 at 20:09 0 comments

    Last two weeks saw some progress although not the expected.

    In the Logisim realm, finally implemented the RET_ADDR register, which, unsurprisingly, stores the return address to be used in the CALL isntructions.

    In the breadboards realm, I managed to build the IR (Instruction register), and a (small) part of the registers control logic.

    In the "future steps" realm I studied and I am very optimistic about VGA output (maybe 256 x 240 pixels, 256 colors/pixel) and interfacing a regular PS/2 keyboard for input.

    That's all people. See you next time.

    Instruction register (IR) with 3 chips (each 8 bits) to hold a 24 bit instruction.

    IR completed.

    Registers logic very far from completed, with those ugly stickrs to help me remember what each wire is for.

  • A little step for a man.

    Andre Baptista09/18/2017 at 16:32 0 comments

    This sunday I finally could make a progress in the hardware part of the project.

    This is the ALU module working, the board below is for test the ALU isolated.

    Now showing the sum of 201 (11001001) and 41 (00101001) which is 242 (11110010):

    Some next modules will need code to be writen to EEPROMs, I will use an arduino to accomplish that.

    Thanks to follow and see you soon.

  • v.0.15.2

    Andre Baptista09/11/2017 at 12:04 0 comments

    Added a 8x8 LED matrix to the circuit in Logisim, already showing simple animations. I'm not sure if this part should be implemented in real hardware, or skip to a VGA output...

    The problem is that the LED matrix haven't any kind of memory, so I'm using a handful of registers to store actual display state. It will be a lot of IC's in real world, doesn't look much like an elegant solution. Maybe I could map screen memory in the RAM and use a fast clock to always refresh the display. We'll see.

    Some changes in OUT instruction were needed, all test programs were reassembled (painful and boring task), but all working fine right now.

    Next step is to implement an input device (keyboard or joystick) in Logisim, to make the first draft of a game, maybe a Tetris clone.

    PS. Now I have all parts necessary to make the CPU in breadboards, maybe next weekend will see big progress.

    Thanks for reading.

  • Weekend update

    Andre Baptista09/05/2017 at 02:42 0 comments

    v.0.14.0 Big changes.

    - Reorganized instructions. As Opcodes changed, all test programs must be reassembled (not finished yet).

    - Implemented some new ALU instructions such as XNOR, INC and DEC. Add new ALU instructions is pretty simple, just add new lines to Microcode ROM.

    -The main change: now there are two registers called H and  L, which will be used to addressing in Direct By Register instructions, containing the High and Low parts of address. These two fix registers replace the previous idea of use any pair of registers [RR3]. Also added one controlled buffer (called Regs Bridge) to separate the outputs of the registers into R1 (A, B, H and L) and R2 (C, D, E and F). This overcome the old limitation that the ALU operations had to use always A register as first input. Now it's much more flexible, R1 for first input (and output also) and R2 for second input.

    New control lines were added to the circuit, and Microcode had to be rewritten.

    Maybe I've forgotten something. Hope I didn't...

    Very busy (and fun) weekend.

    Edit: forgot to mention: all this work only in virtual world (Logisim). Real hardware is stuck as the extras 12 breadboards I've bought still didn't arrive...

  • Clock, Phases, and PC working

    Andre Baptista08/28/2017 at 20:00 0 comments

    Finally, as most of pieces arrive, I could dive into the breadboards and wires and ICs all weekend.

    Now we have the Clock, Reset, 4 Phases (Fetch 1 to 3, Execute) and 12-bit PC (Program Counter) fully operational.

    Lessons learned the hard way:

    -The clock generator 555 IC has very weak output. It barely can feed two TTL inputs. If I put a single 3mm round led (with a huge 4,7K resistor) to see the clock ticks, it makes all the circuit to behave erratically. That is why all projects out there uses an buffer/inverter right after the 555 output to feed all the circuit.

    -Baby steps, allways. The old and good XP (eXtreme Programming) mantra is especially true when dealing with (moody) hardware. For each single piece added, turn on the circuit and see if everything still runs fine.

    -TTL outputs are not suited to drive leds directly, but as i'm using big resistors (4,7k as mentioned above), the current is very small (between 0,3 and 0,8 mA, depending on the TTL output, which can vary bettween 5 and 2.7 V). Surprisingly the leds show a useful bright even with such tiny current, so I can use them without bother with transistors to drive the leds.

    I never felt so happy to see a bunch of leds blinking :)

    Unfortunally the 6 breadboards I ordered a long ago still didn't arrive. I will buy them on local market anyway.

  • Update after long time, real hardware.

    Andre Baptista08/06/2017 at 18:10 0 comments

    Hello, first log entry in a long time... Trying to keep the project up while solving personal issues.

    Finally I have something "real" to show:

    I'm yet to receive many parts (thanks to the brazillian mail), but I could make the clock, and the 74HCT4017 to make the 4 cycles steps (Fetch 1 to 3, the red leds, and Execute, the yellow one).

    It's a very small step, but I need to break the inertia.

    Working with real hardware has it's peculiarities, It's very important to follow one of the XP principles, baby steps...

    Between the lessons learned, never, NEVER keep inputs floting, the circuit behavior becomes imprevisible.

    Thank you for reading.

  • v.0.11.0 - Microcoded ROM

    Andre Baptista07/10/2017 at 20:56 0 comments

    Finally upgraded from the archaic IC's of microcodes with combinatorial logic to ROM, still in Logisim.

    In real hardware will be used 3 of the AT28C256 EEPROM in parallel. It's a huge waste of space, I know, but there aren't smaller chips, or the cost is almost the same.

    PS. Now there is a LCD output, and a test program to print an 'A' char. All ready to make a classic Hello World program!

  • Week (almost zero) progress

    Andre Baptista07/06/2017 at 13:19 0 comments

    This week seen very little progress, as I'm stuck in personal problems, like a minor car crash...

    That being said, let's move on.

    It's amazing how silly things you ignored/disdained for a long, long time suddenly shows up and you perceive how incredibly useful they are! It's pretty like a Eureka moment.
    Yes, I'm talking about you, Pull Up/Down resistors. These guys, in conjunction with 3-state buffers, are all you need to make bus-driven circuits.

  • Project decisions. The trade-off hell

    Andre Baptista06/27/2017 at 20:34 0 comments

    Regarding the problem faced on last log entry, I haven't decided yet, but I'm inclined to solve it as follows:

    Change the single Execute phase for a dual phase. It makes possible to use any of the registers as both ALU A and B in. All the registers will have its outputs connected together (bus), so only one can be read at a time. The first Execute step would load R1 value in a (new) input temporary register for the ALU A input. In the next step (Execute 2), the R2 value would be driven to ALU B input normally, and (almost) immediatelly the result would be available at ALU output, ready to be loaded in R1 input when CLK-B rises at middle of Execute step 2.

    This approach has the notable advantage of barely add hardware complexity (only one new register) while making the Instruction set code far more confortable by allowing all registers to act as both two inputs and the output of ALU.

    The main disadvantages is the speed penalty, 25% slower, but I think it's manageable, and one step entirely useless in all non ALU operations. That doesn't make me anyway happy, but...

    PS. Just added a list of parts. It's preliminar, and some quantities are very overestimated, as the demux.


  • Project decision regarding registers

    Andre Baptista06/26/2017 at 21:00 0 comments

    Almost done, but got stuck with register problems, which ones will be source and destiny of instructions.

    In case of ALU there are two sources. And to make things worse, the two inputs of the 74LS181 ALU haven't same powers, the A input has a lot more functions allowed.

    It's easy to permit all registers to work in all roles in a software simulator like Logisim, but when it comes to use real chips it becomes a nightmare due to the huge quantity of controlled 3-state buffers (74LS244) required to control the data flow.

View all 18 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates