SPAM-1 - 8 Bit CPU

8 Bit CPU with simulator and toolchain and a hardware build to follow

Similar projects worth following
SPAM-1 : Simple Programmable And Massive - v1/v2
"Massive" in the sense that it's going to be built on breadboard.

8 Bit CPU using mostly HCT chips and fully simulated in verilog with realistic chip timings.

The current design is a heck of a lot more complex than the original POC but also a lot more capable. Unlike the POC it won't be relying on google sheets as the development effort of programming in that environment is too high, and also because I want to be able to use Icarus verilog and other such tools.


The prototype learning exercise was simulated in Logisim Evolution with an assembler written in Google Sheets - I've not seen this done before - is it a first? My intention was to make the tooling as accessible as possible and more visual.

However, once that initial effort and sim was completed I decided that this was too trivial to actually build as hardware. So I decided to bite off a lot more.

V2 objective

I got v1 working in the sim but then decided I wasn't going to build it in hardware as these very simple CPU's aren't that capable or complex and I wanted more of a challenge; something that would force me to learn more.

So this has changed out of all recognition.

Along the way I got distrated by a hardware build of a testing device for all the chip's Ive bought for this CPU project. The testing device project can be found in my project list. That was interesting and a throw back to my Uni days in the 80's.

Now, I'm firmly back on the CPU task and nearing the end of the design and sim phase....

UPDATE: After a few more months I've finally settled on the capabilities and design and have arrived at an approach that appeals to my  sense of symmetry. I've adopted some features of ARM; specifically conditional instructions and status flag control.

Check out the project logs !

V1 objective 

⭐️ I wanted to do things a little differently to some of the other efforts on the internet! 

I wanted the assembler and any other code I write to to be more readily accessible and instantly usable to others (like you) without installing python or perl or whatever first, so I've written the assembler in google sheets!I want to be able to run at least the typical demo programs like Fibonacci

  • I would like to extend it to play some kind of basic game (tbd)
  • It will have an assembly language and assembler for it
  • I might port C to it
  • I want to simulate it first
  • I want to build it physically, or a more likely a derivative

The Assembler is in Google Sheets ....

However, on completion of this phase of the project I made these observations (sorry about the font size)...

So I changed tack ... thus V2 above.

Graphics Interchange Format - 2.18 MB - 08/03/2019 at 19:59


  • 1 × Logism Evolution
  • 1 × Google Sheets

  • Triple Port Register Patterns

    John Lonergan3 days ago 0 comments

    Short video covering the register file pattersn I've used in the CPU.

    Extension of the previous video ...

  • 4x8 Register File video

    John Lonergan4 days ago 0 comments
  • Fried Chips Flavoured Register File

    John Lonergan6 days ago 0 comments

    Precursor to a video about SPAM-1's register file component.

    This video looks at the 74HCT670.

  • Feature Envy Video - Conditional Execution

    John Lonergan10/21/2020 at 18:21 0 comments

    CircuitVerse sim of the new control logic

    Bonus ! Heres a video on Instructrion Set Arch that I thought was really good (past of a series)

  • Register (not!) file timing

    John Lonergan10/14/2020 at 02:38 0 comments

    I wrote quite a long answer to a question over on Electronics Stack Exchange and decided to copy it here to avoid losing the info.

    See for context this ...

    Incidentally there are also these two related devices 

    - CD40108 - rare triple port register file

    - DM85s68 - dm85s68-16x4-synchronous-register-file

    My answer verbatim is was as follows ...

    I use a few 74HCT670 chips in my homebrew 8 bit CPU called SPAM-1

    See or more specifically see this verilog model of the CPU that I have created to simulate the CPU prior to hardware.

    I keep project logs here ..

    BTW see also this alternative to the 74670 ..

    So ....

    Concidentally I was actually finishing off the testing of the register file in hardware tonight and came across this post while browsing.

    In SPAM-1's case I want to "clock" data into the register file reliably and without reliance on short pulses who's width I'd have to worry about getting just right.

    By understanding the timings in my CPU design I was able to implement a register file based on the 74HCT670 that didn't rely on short pulses. I did this by putting a 74HCT574 in front of the data input and by relying on an understanding of the deliberate timing of signals in my CPU.

    So the setup I've used is as follows.

    An important feature of my CPUI is that the output of the register file feeds into the input of the ALU, and the output of the ALU feeds back into the register file. This presents a further problem for the use of the 74HCT670 because if the write address of the reg file is the same as the read address of the reg file then the reg file is in a "flow through" configuration and this will setup a situation where the updated output of the ALU updates the reg file which then causes the ALU to settle on a new value which then updates the regfile to a new value and so on. So it is essential for me that this loop cannot occur.

    To solve this I have put a 74HCT574 flipflop on the data lines in front of the register file. This prevents the cycle I referred to, and I will come back to discuss this flip flop a bit more in a minute.

    In my CPU the CPU increments the program counter on the rising edge of the clock, and executes the instruction on the low phase of the clock.

    Consider the high phase of the clock to be fetch/decode and the low phase of the clock to be execute.

    During the fetch/decode phase of the clock, directly after the PC increment the control lines begin to settle and the output of the ALU arrives at the 74HCT574 flipflop. In my case these control lines also include the /ReadEnable of the 74HCT670 regfile and the write address of the regfile. But I gate the /WriteEnable of the regfile with the clock so the /WE only goes low during the "execute" phase. The control lines settle completely by the end of the fetch/decode phase.

    During the execute phase of the clock I want the data to be latched reliably into the selected write address of the register file. So as the clock goes low and we enter the execute phase I trigger the 74HCT574 flipflop clock line to synchronously load the ALU result into that flip flop. I also enable the /WriteEnable of the regfile only during the execute phase so the new value of the flipflop then flows into the selected address in the regfile.

    Because the /WriteEnable is composed of a control line gated with the execute phase of the clock then I can be assured that it will not go low until the beginning...

    Read more »

  • Program Counter Video

    John Lonergan10/08/2020 at 08:23 0 comments

    Just published this video on the programme counter.

    The video includes details of the 74hct163 counter chip, the verilog simulation of the program counter and also using the verilog sim to debug the hardware.

  • Conditional Instructions

    John Lonergan10/03/2020 at 15:34 0 comments

    Have adopted an ARM-like approach by making all instructions conditional rather than just jumps and also used a spare bit to control whether a given op sets the status flags.

    This makes the whole desigh more symetrical and appealing to me.

    This was pretty easy to add once I realised that all I have to do was to hook up one of the unused enable pins on my "target" decoders  .Enable2_bar(_do_exec) 

    hct74138 targ_dev_08_demux(.Enable3(1'b1),        .Enable2_bar(_do_exec), .Enable1_bar(targ_dev[3]), .A(targ_dev[2:0]));
    hct74138 targ_dev_16_demux(.Enable3(targ_dev[3]), .Enable2_bar(_do_exec), .Enable1_bar(1'b0),        .A(targ_dev[2:0]));


    This relied on creating some simple decoding logic based on a 74151 multiplexer as shown below. But that work brought me to an understanding of the difference between "inertial" and "transport" delays in Verilog.. I was expecting some glitches due to the chip's published timings but they didn't show up in the simulation because I'd effectively used "inertial delays". I reworked the timings to let through all glitches by implementing "transport delays"; but that's not how real silicon works either because real silicon will not propagate short lived pulses. I'll probably write more on this.

    The additional control logic is simulated here..

  • Design Video

    John Lonergan09/25/2020 at 00:12 0 comments

    Part 1 of a sequence ...

  • Too many ROMs

    John Lonergan08/22/2020 at 14:43 0 comments

    Sitting in a pub in Brighton, away for weekend.

    I am deliberately using 6 ROMs for the program in an attempt to avoid any complicated decode logic. 48 bit instructions

    It's a horizontal decoding scheme. No bit overloading, just a bunch of wires and a few 74138/139 decode chips.

    However I'm not sure I can be bothered pulling 6 ROMs (flash) chips to change the program.

    Will consider whether to add a programming interface so I don't have to mess with individual chips, or maybe add 6 instruction registers and a single big room.


  • Destroyed my first chip

    John Lonergan08/08/2020 at 00:37 0 comments

    Forget static discharge.

    Instead, try running a high capacity lithium ion power bank through a register chip that's wired up incorrectly. 

    The breadboard practically melted and I burned a chip-shaped mark in my forefinger before I figured out what was up.


    Perhaps a current limited supply might be safer - I don't have one. 

    Would measuring the resistance from Vcc to Gnd before applying power have spotted the issue before things melted?  It might, but it would be a PITA having to keep making that measurment after each wiring change. 

View all 32 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