Close
0%
0%

4 Bit TTL CPU

A usable 4 bit TTL CPU

Similar projects worth following
I saw this really good looking 4k x 4 bit RAM chip that had to be put to good use.
The project is to design a usable 4 bit TTL CPU that uses the RAM chip.
Can a 4 bit CPU really be usable?
Here is an attempt.

A 4 Bit TTL CPU

Specifications:

  • 1 Mhz clock (could run up to 8 Mhz)
  • 4 bit data bus
  • 8 bit address bus

ALU:

  • ADD (also SHL)
  • DEC
  • OR/NOT
  • OR
  • AND
  • XNOR
  • MOVE
  • LAST (result)
  • SHR (not yet but being considered)

PC:

  • Set MSB (most significant nibble) for jump
  • Unconditional jump
  • Jump on not carry
  • Jump on not equal

Interface:

  • Front panel (i.e. data and address LEDs and switches)

AlanX

4Bit-FrontPanel.png

The Front Panel schematic

Portable Network Graphics (PNG) - 215.33 kB - 08/11/2016 at 11:43

Preview Download

4Bit-CPU-II-FrontPanel.png

The Front Panel PCB

Portable Network Graphics (PNG) - 87.81 kB - 08/11/2016 at 11:43

Preview Download

Portable Network Graphics (PNG) - 56.93 kB - 08/10/2016 at 12:55

Preview Download

4BITCPUOPCODE.JPG

The OpCode version (much better).

image/jpeg - 731.67 kB - 08/10/2016 at 12:54

Preview Download

4BitCPUOpCode.TSC

The OpCode version (much better).

- 323.88 kB - 08/10/2016 at 12:55

Download

4BITCPU.JPG

The Schematic for the 4 Bit CPU

image/jpeg - 570.49 kB - 08/06/2016 at 01:05

Preview Download

4BitCPU.TSC

The Tina file for the 4 Bit CPU

- 85.63 kB - 08/06/2016 at 01:05

Download

View all 7 files

  • Code Efficiency

    agp.cooper12/04/2016 at 09:02 13 comments

    Code Efficiency

    The Weird CPU is most likely to be the most inefficient CPU (built) other than first version of the 4 Bit CPU. The monitor program just fit into the 128 bytes of PROM. Each instruction takes two bytes. The monitor programs looks after the user interface (examine/modify/run) and a delay routine. All in 64 instructions very inefficient instructions.

    The 4 Bit CPU has 192 nibbles of PROM but each ALU instruction take 5 nibbles. The non-ALU instructions take 3 nibbles. So 192 nibbles is about 48 instructions but the instructions set more efficient (just) so I think it is just enough (I have done some pencil scratchings to convince myself of this).

    Although I have a working Front Panel I have elected to change the switch logic from inverting to non-inverting in order to save memory (PROM) by avoiding the need to invert the logic in software.

    What would be really nice is an immediate load op-code. Hard to rework the timing logic for a new two nibble op-code but there are several spare slots for a three nibble op-code. After playing with the logic schematic (i.e. more pencil scratchings), I think the neatest solution is to concurrently immediate load the MSN (Most Significant Nibble) for the jump op-codes and the immediate load the LSN (Least Significant Nibble) for the ALU. This should be quite usable as the MSN of a jump needs to be set regularly and just prior to any calculations used for the jump op-codes. At this time the ALU usually needs to be cleared. Win-win as they say.

    I think I can do this with one additional chip (swap out a 74LS138 for a 74LS157 and a 74LS10).

    I will post the update schematics when done.

    ---

    ALU Decoder Error

    After slowly stepping through the Tina-Ti simulation I found I have incorrectly decoded the 181 ALU. The decoder should be:

    Here is the updated schematic:

    Notes:

    1. The OR gate with the "x" and RC delay network is only required by Tina-Ti as the 74151 spice model is flawed (from Tina Pro V5.5).
    2. The input logic is now non-inverting (saves programming space).
    3. A 7485 comparator has bee added, OpCodes now include proper JNE, JGT, and JLT OpCodes.
    4. The SET MSN (used to be called SET MSB) for the jump command is now Load Immediate (LDI):
    • LSN (iused to be called LSB) sets the DataIn (A Reg of the ALU).
    • MSN sets the MSN of the jump address.
    • The LDI instruction makes a dummy read of the MSN:LSN address.

    The LDI OpCode significantly improve programming efficiency.

    Added a Test0 and Test1 (jump on pin high command).

    ---

    Here are the basic timing signals (not !DATA_OUT is and inverted !RD):

    Jump

    LDI

    Move

    The above signal are correct (the PC_CLK and !LOAD are the ones to check) but they don't test the operation of the OpCodes.

    ---

    Still have to step though all the OpCodes to satisfy myself they are working.

    Argh! After a few hours I realised that the Tina-TI model for the 74181 is not working.

    Argh!! I decided to digitise a gate level 74181 from scratch in TinaPro and export it as as a macro. I then imported the macro into TinaTI and it does not work! I think TinaTI has a limit to how deep it with transverse a spice network. I had a similar problem with modelling a biquad filter. So it is a TinaTI problem/limit rather than the model.

    Yes confirmed, it is TinaTI as the default 74181 works in TinaPro v5.5.

    ---

    The problem with Tina is that the old version I have (a paid for Tina Pro v5.5) is too unstable to be usable and the new versions are either crippled in function or crippling in price. I don't mind paying a few hundred dollars but not thousands. I checked out their forum and it does not seem to be very active. This does not bode well for the future for DesignSoft.

    ---

    I have decided to give LTSpice a try. I have installed it, watched a few videos and installed a TTL library and loaded a simple example. So all set to digitise the CPU schematic.

    Started digitising the CPU. It will take a few days as I get used to the LTSpice way of doing things. Using the 74HCT library but it is missing the 74HCT181 so I will...

    Read more »

  • Did not read the fine print!

    agp.cooper11/27/2016 at 06:35 2 comments

    Sometimes the Fine Print Hurts

    Sent off the updated CPU board for manufacture.

    I was playing around with the "jump logic" when I rediscovered that the "A=B" output from the 74LS181 actually means the F0-3 (i.e. F) output from the 74LS181 is all highs (=0xF) rather than "A=B". "A=B" is true only if you use "subtract mode". Now I don't use "subtract mode"! After the initial anguish I reasoned that after an XNOR then the if A=B then F=0xF. "A=B" does not depend on the mode control input (i.e. M). Check my schematic I seem to have not inverted the JEQ to JNE. Oh well!

    Jump on Not Carry (JNC) is okay (works with ADD).

    Arduino Emulator

    Wrote a simple 4 Bit CPU emulator to work with the Front Panel. This will allow me to test code:

    /*
      Front Panel Board Test
      
      Board Connections:
       A7   <-> D9  PortB1
       A6   <-> D8  PortB0
       A5   <-> D7  PortD7
       A4   <-> D6  PortD6
       A3   <-> D5  PortD5
       A2   <-> D4  PortD4
       A1   <-> D3  PortD3
       A0   <-> D2  PortD2
       !RD  <-> D10 PortB2
       !WR  <-> D11 PortB3
       Rst  <-> D12 PortB4 (active low)
       LED  <-> D13 PortB5
       D0   <-> A0  PortC0
       D1   <-> A1  PortC1
       D2   <-> A2  PortC2
       D3   <-> A3  PortC3
       !CLR <-> A4  PortC4
       CLR  <-> A5  PortC5
       
    Port mapping:
      Port D
        Pin D00000000
            D76543210
        Bit B76543210
        Fnx  AAAAAART
             543210xX
      Port B
        Pin D11111100
            D54321098
        Bit B76543210
        Fnx  XXLR!!  
             XXESWRAA
             XXDTRD76
      Port C
        Pin AX6543210
        Bit B76543210
        Fnx  XX !
             XXCC
             XXLLDDDD
             XXRR3210
    
    Addressing:
      IO:
        0xFF ADDR IO MSB
        0xFE ADDR IO LSB
        0xFD DATA IO
        0xFC IO unused
      RAM:
        0xC0-0xFC RAM 60 nibbles 
      ROM:
        0x00-0xBF ROM 192 nibbles
    
      Notes: Requires seperate power supply as on board power from Nano is not sufficient
    */
    
    #include <avr/pgmspace.h>
    const byte PROGMEM ROM[192]={
      0x07, 0x04, 0x02, 0x0b, 0x0f, // MOVE [0x24]=0x0      -> [0xfb]
      0x01, 0x0d, 0x0f, 0x0d, 0x0f, // XNOR [0xfd]=Data     -> [0xfd]
      0x07, 0x04, 0x02, 0x0b, 0x0f, // MOVE [0x24]=0x0      -> [0xfb]
      0x01, 0x0e, 0x0f, 0x0e, 0x0f, // XNOR [0xfe]=AddrLow  -> [0xfe]
      0x07, 0x04, 0x02, 0x0b, 0x0f, // MOVE [0x24]=0x0      -> [0xfb]
      0x01, 0x0f, 0x0f, 0x0f, 0x0f, // XNOR [0xff]=AddrHigh -> [0xff]
      0x0f, 0x05, 0x02,             // SET MSB [0x25]=0x0  
      0x0e, 0x06, 0x02,             // JMP LSB [0x26]=0x0
      0x00,                         // 0x0
      0x00, 0x00,                   // 0x00
      0x00,                 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    };
    
    byte RAM[60]={
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00
    };
    
    void resetState(void) {
      // Port D
      //      AAAAAATR
      //      543210xX
      DDRD &=B11111111;
      DDRD |=B11111100;
      PORTD&=B00000011;
      // Port B
      //      XXLR!!  
      //      XXESWRAA
      //      XXDTRD76
      DDRB &=B11101111;
      DDRB |=B00001111;
      PORTB&=B11111100;
      PORTB|=B00001100;
      // Port C
      //      XX !
      //      XXCC
      //      XXLLDDDD
      //...
    Read more »

  • New Boards Are Here

    agp.cooper11/25/2016 at 04:51 0 comments

    The New Boards Are Here!

    Unfortunately I don't have enough chips (i.e. 74LS173 and 74LS125) for the CPU so I have to order some (that will take another week).

    Assembled the front panel:

    Learnt my lesson and used sockets for all the ICs. I can test the new board while I am waiting for the remaining CPU chips to arrive.

    The only mistake I ave found so far is that I forgot to label the D0-3 databus on the right had side of the board.

    One Win and One Loss

    The Front Panel checks out. A good feeling! Noticed that I have written some rubbish to the PROM (must have been when I was debugging the PROM programmer).

    Three errors on the CPU board:

    • forgot to rewire the counter (or I used the wrong schematic as a base for the design update).
    • swapped the Jump On Not Carry and Jump On Not Equal signals, and
    • the footprint for the power plug was not linked in (i.e. an autorouter/footprint problem).

    So time to get another set of boards made.

    EasyEDA

    For my first set of boards I pay for airmail (the cheap option) and delivery was less than two weeks. For the second set of boards I paid the fast option and delivery was two days and I got SMS's to tell me it was coming. Still it takes about 5 days to manufacture.

    The only complaint is that the website has slowed down but this is probably Telstra rather than EasyEDA.

    Going the PCB route rather than the strip-board route has it's pluses and minuses:

    • PCB is quick to get going but any mistake is costly (a new board).
    • Strip-board for big projects is a real pain (very time consuming to design and build) but it is quick to fix mistakes.
    • Not using IC sockets for the PCB the first time was costly (none of the ICs were recoverable and it takes time to buy new ones).
    • Patching PCB boards (usually that means making a jumper board) except for the most minor fixes is a real pain and is probably a waste of time.

    There is probably merit during prototyping to split big boards into two or three smaller boards. At least it will make it easier and quicker to debug. After they are debugged then they can be recombined.

    Finally, some consideration for testing the boards should be built in. I brought out the clock signals on the second set of boards so that the Arduino could follow what the CPU was doing.

    Regards AlanX

  • Arduino Shield

    agp.cooper11/08/2016 at 13:18 0 comments

    Testing the 4 Bit CPU

    The CPU is too complex to test (debug) by measuring signals (on an oscilloscope).

    You need to test each board (yes there is only two boards) separately first.

    For that I use an Arduino.

    To minimise the problem with jumpers I have designed an Arduino shield using strip-board:

    Yes I know the pins ARef to D8 are offset 0.05", I intend to bend the header pins to fit.

    First I will test the front panel:

    • LEDs
    • Switches
    • RAM
    • PROM (all highs for a new PROM)

    Then I will write an emulator to test the monitor program.

    A Nano Shield

    I went for a Nano shield as it was a better fit:

    I make a mirror image in order to minimise track cutting mistakes.

    Here is the finished board with the front panel fitted:

    Now to write some test code.

    Shield Update

    As I was coding and I noted a mismatch and realised I had a wiring error.

    Here is the updated design for the shield:


    Front Panel Test Results

    • Swapped the CS_IO and CS_ROM when redrawing the schematic in EasyEDA. Fixable.
    • Need to slow down the read/write pulse from 1 us to 2 us?
    • The Data read and write (switches and LED) works.
    • The Addr LSB and Addr MSB read/wrte from the address bus rather than the data bus. Fatal!
    • The memory chip was bad. Replaced with spare. Now good.

    This board is ready for redesign in EasyEDA.

    Tomorrow I will test the CPU.

    To do this I have to slow down the CPU and get the Nano to emulate the Front Panel/ROM/RAM.

    CPU Tests

    I slowed the clock down to 10 Hz with a 100uF timing capacitor.

    Emulating a PROM/RAM with the Arduino is not too hard.

    Monitoring the CPU is a little more difficult.

    I have not exposed all the necessary clock signals:

    • OPC_CLK - yes
    • LSB_CLK - no
    • MSB_CLK - no
    • DATA_CLK - no
    • !WR - yes

    The CPU seems to have a glitch in the PC_CLK train (still) but not surprising given the dodgy fix last time. I have rework the design to fix properly.

    Still the timing circuit could do with a revision.

    Even so the ALU does appears to be working.

    So I have reworked the boards and sent them off to be made.

    This time I will be using IC sockets!

    AlanX

  • Assembly and Testing

    agp.cooper10/30/2016 at 05:34 0 comments

    Assembly and Testing

    I am done with my last project so time to do more work on this one.

    Assembled the main board.

    Need to use a 0.2" spacing for capacitors rather than 0.1" (even though I have a packet of 0.1" 100nF capacitors).

    Testing:

    • Powered up - voltage okay.
    • No clock?
    • Checked the reset line and it is locked low.
    • The reset switch part layout is rotated 90 degrees.
    • I will have to edit the part layout but can bend the pins to fit.
    • Clock a little slow and low duty.
    • Adjust the 220 ohm resistor down to 120 ohm.
    • Clock is good enough.
    • No timing signals, the 74LS161 is not working.
    • Check the schematic and I have miss-wired it (three pins pulled low instead of high).
    • Replace with another 74LS161 with the miss-wired pins lifted and a solder a wire from the pins to Vcc.
    • Timing signal present but a glitch on the PC_Clock.
    • Really bad design for the PC load logic, fix with a RC delay on one of the PC_CLK inputs.
    • No address output?
    • The program counter 74LS161s are not working.
    • Now the pin voltages are okay and the clock is present so strange!?
    • I have a spare so I breadboard it and it does not work properly!?
    • I think I have a set of defective chips.

    Oh well, go to another shop and buy some more!

    I thought it would be wise to test the chips before using them:

    • After a couple of hours of frustration I realised the 1 kHz signal from my oscilloscope cannot drive the clock input (properly) of the 74LS161.
    • So I thought I better check 74LS151 before cutting out the 74LS161s.
    • Strange the signal does not match the simulation even though I check the schematic carefully?
    • Checking the datasheet I find the 74LS151 model I have is wrong!
    • The model has the Y output going high on deselect while the data sheet has the Y (actually Z) going low.
    • So I need to use Z bar and invert the multiplexer inputs.
    • This is going to need a jumper board.

    Not the first time I have used an incorrect model.

    The other dud model was the 74LS132, it was just a 74LS00 rebadged

    Working (within test limits)

    I jumped the 74LS151 with a board that mimicked the Tina model.

    Still that 74LS161 does not work!

    Replaced the 74LS161 and now it works as far as I can test it:

    • Works for D0-4 equal 0b1111 (SET MSB - a 3 nimble opcode) and for 0b0111 (MOVE - a 5 nimble opcode).
    • It works in that the timing signals are correct and the A0-8 is working its way through the address space (as expected).

    Not a real test but that has to wait.

    Here is a picture of the boards:

    Next is to assemble and test the front panel.

    I will test the front panel with an Arduino.

    If the front panel works then I can use the Arduino to emulate the CPU.

    After that I will slow down the CPU clock and emulate ROM/RAM to test the CPU properly.

    Once I have everything working I will get the next version (fixed) of PCBs manufactured.

    A long way to go!


    The Front Panel

    The front panel is short two ICs and a few resistors.

    Here it is fitted to the CPU board:

    But it will not be staying connected.

    I will use an Arduino to test the front panel and to develop an emulator of the CPU.

    Assembly Completed

    Passes the power up test.

    Next is to emulate the CPU with an Arduino and test the front panel.

    AlanX

  • The boards have arrived

    agp.cooper09/02/2016 at 09:12 0 comments

    The boards have arrived

    The boards have arrived so now it is time to start assembling it.

    Well, not quite, I am busy at moment and I am going on holidays next week with my partner.

    But to get the ball rolling I should assemble the timing sub-system components.

    I have everything except for 74LS132 (I used the last one I had on another board recently).

    I have ordered some more, more than a week or so ago, but it usually takes about 3 weeks from Hong Kong (or was it Thailand?).

    So maybe before I go on holidays.

    The other option would be the Front Panel.

    At least I can hook it up to an Arduino and work on an emulator while I am away.

    That sounds like a plan to me!

    AlanX

  • Memory and ALU chips have arrived

    agp.cooper08/23/2016 at 03:27 5 comments

    hat sexy chip is here!

    You just have to admit that they don't make them like this anymore.

    So I am just waiting for the PCBs.

    AlanX

  • While I am waiting for my boards to be manufactured

    agp.cooper08/15/2016 at 08:49 0 comments

    Growing up the 4 Bit CPU

    The 4 Bit CPU was a test of the lower boundary of something that is usable at least in an educational sense. Something like the Educ-8 (https://en.wikipedia.org/wiki/EDUC-8).

    I mentioned this DIY non-microprocessor based computer because it started it all for me.

    Up until recently (when I had a big throw-out) I even had the book from the 1970s for it.

    An 8 bit Version

    I have updated the schematic for an 8 Bit version (I kept the 4 bit op-codes) but added a register to set the Carry In flag. An extra 8 chips (from 36 to 44).

    I am not going to start the PCB design until I have hardware debugged the 4 Bit CPU, but here is the schematic for those who like these things:


    Some Artwork for the 4 Bit CPU

    A colleague sent me an image to add to my CPU boards rather than the boring text font.

    I am was engineer (mining) so artistic flair is not a strong point (mining engineers dig holes and like to blow things up!). But I recognize the value.

    An Engineers Attempt at Art

    A little while back I was working on a DeltaCad macro to automatically "decorate" the blank areas of CNC cutouts (think of scrollwork patterns). I used the Celtic Knot as a pattern. Here is an example:

    The problem is to make the pattern conform to the cutout edges (paving problem?).

    Anyway this an engineers attempt at art.


    AlanX

  • 4 Bit CPU Update

    agp.cooper08/11/2016 at 12:11 0 comments

    CPU Schematic and PCB Updated

    • Updated the CPU schematic for some errors.
    • Updated the CPU PCB.
    • Completed the Front Panel Schematic and PCB.

    Here is the EasyEDA CPU schematic:

    Here is the EasyEDA CPU PCB:


    Now the Front Panel schematic (includes ROM/RAM and Input/Output):

    And finally the Front Panel PCB (with Op-Codes!):

    Now is that not sexy!

    Hardware Debugging

    The Weird CPU was built with Strip-Board and each board was stacked:

    Each board and the stack could tested using an Arduino:


    This time I am using manufactured PCBs so the plan is to incrementally assemble and test each sub-section. For example:

    • I can add the clock first - test that
    • add the remaining of the timing schematic - test that
    • add the Op-Code and Address Latches - test, etc.
    • Easy enough to get access to an empty IC socket for test probes.

    Doable in that I will be able to find hardware errors (and they are expected). So I do expect to have to re-manufacture the PCBs.

    So it is going to cost me a bucket of money? Not! Try $25 per board (you get five whether you want them or not) and $20 delivery per order. So these two board will cost about $70. But it does take a few weeks for delivery.

    So strong motivation to try and get it right the first time but no fear of failure.

    AlanX

  • Architecture Review

    agp.cooper08/07/2016 at 13:41 0 comments

    Architecture Review

    The 8 bit Weird CPU (WCPU) had an 8 bit data and address space, and used registers for instructions.

    An ADD sequence would be coded like this:

    1. Move Memory A to Register P
    2. Move Memory B to Register Q
    3. Move Register ADD to Memory C

    Behind the registers were two ADD chips.

    Three cycles of two bytes (6 bytes) are required for the ADD sequence.


    The 4 Bit CPU uses a 74LS181 ALU so the same task on the WPCU would be coded as:

    1. Move Memory A to Register ALU A
    2. Move Memory B to Register ALU B
    3. Move Memory C (the function constant) to Register ALU S (i.e. the select register)
    4. Move Register ALU F (the ALU results register) to Memory D

    Four cycles of two bytes (8 bytes) are required for this ADD sequence.


    Now you can see why I did not use the 74LS181 (ignoring the cost) for the WCPU.

    For reference the WCPU monitor was 96 bytes and the delay routine 18 bytes and a further 14 bytes were used for constants. The biggest headache was the lack of an XNOR that cost a total of an extra 32 bytes of memory.

    The 4 Bit CPU used the 74SL181 ALU and has a 12 bit address space. The extra address space was assumed to be required based on experience with WCPU and the expected less efficient memory utilisation.

    Each instruction cycle (i.e. fetch and deposit) will require 6 nimbles. The ADD instruction will therefore require 24 nimbles.

    (If the 4 Bit CPU used the 74SL181 ALU and had an 8 bit address space, the ADD instruction would need 16 nimbles. It is clear that 128 nimbles of memory would be insufficient for a front panel monitor program.)

    Although the 4 Bit CPU with a 12 Bit address space is sufficient and feasible, the prospect of coding such an inefficient CPU is not a pleasant thought!

    Time to consider Op Codes

    It is pretty clear that for the 4 Bit CPU, I need to consider Op Codes to improve instruction/memory efficiency.

    I look at two basic options:

    Option 1:

    • [OpCode][LSB Memory][MSB Memory]
    • Where the OpCode's most significant bit defined a memory fetch or a memory deposit.

    This option is well suited to CPUs with multiple registers.

    An ADD sequence would look like:

    • Load A
    • Load B
    • Save ADD

    A total of 9 nimbles. Note, I have dropped back to a 256 bit address space.

    Option 2:

    • [OpCode][LSB Fetch][MSB Fetch][LSB Deposit][MSB Deposit]
    • Where the OpCode's defines the ALU and jump Instructions

    This option is well suited to a single (i.e. accumulator) register CPU.

    An ADD sequence would look like:

    • Load A (and Save)
    • Add B to Last and Save

    Note that each instruction write to the accumulator and then reads back the result (even if not meaningful).

    For this the work the other operand for the ALU is the previous or Last result.

    A total of 10 nimbles. Note, I have dropped back to a 256 bit address space.


    Final version

    After a couple of days designing both options I have settled on a hybrid.

    For the ALU, a 5 nimble format that write back the ALU result:

    [OpCode] [Fetch LSB] [Fetch MSB] [Deposit MSB] [Deposit MSB]

    The ALU codes are:

    • 0000 PLUS
    • 0001 XNOR
    • 0010 LAST
    • 0011 AND
    • 0100 DEC
    • 0101 OR/NOT
    • 0110 OR
    • 0111 MOVE

    For Program Counter (PC) a 3 nimble format:

    [OpCode] [Fetch LSB] [Fetch MSB]

    The PC codes are:

    • 1000 NOP
    • 1001 NOP
    • 1010 NOP
    • 1011 NOP
    • 1100 JNE LSB
    • 1101 JNC LSB
    • 1110 JMP LSB
    • 1111 SET MSB

    You will note that the PC codes are all about jumps.

    The Schematics

    Here is the Timing schematic:

    And the Timing signals:

    The OpCode and Address Latches:

    The ALU:

    The Program Counter (PC):

    And finally the Front Panel (i.e. Memory and Data IO):

    An this is what the PCB looks like (excludes the Front Panel piggy-back board):

    The PCB is waiting on a final check before being sent off to be made. The Front Panel will be designed later.

    AlanX

View all 12 project logs

Enjoy this project?

Share      

Discussions

Starhawk wrote 11/12/2016 at 23:34 point

Just thought of a tool that might help you debug this thing. It's what I'd use instead of that Arduino test rig -- mind you, I lean towards older tools and techniques, both because of cost (the older tools are less desired now, and so are cheaper) and because I can understand them (lol). For example, my probably most treasured tool is actually an o-scope from the mid-1960s that a friend of mine gave me. Tektronix 422, and oh, the stories it could tell if it could talk ;)

The tool I was thinking of for you, though, is called a 'logic probe'. It's basically a signal-to-sound converter... it has power leads and a little pin thing you touch against a trace. If the trace is at logic high, it makes one tone; if at logic low, another tone. If it's a busy trace that's doing stuff (and therefore flapping around between high and low) you can hear it as the tones flap around correspondingly.

I once asked Quinn Dunki aka Blondihacks (if you haven't heard of her, she's *amazing* -- she's built, from scratch, a 6502-based 'home microcomputer' like you would've had in the 80s) on her blog to explain the tool to me, out of ignorance. Here -- http://quinndunki.com/blondihacks/?p=1850#comment-17263 -- is my comment and her extraordinarily friendly reply, along with a recommendation for a specific probe to buy -- I have that exact one now, and it's saved my tail on a couple of occasions (most notably in debugging my perpetually-misbehaving Osborne One). It's a little confusing to use, at first, but you get used to it pretty quickly.

Hope that helps :)

  Are you sure? yes | no

Starhawk wrote 11/10/2016 at 20:51 point

I tipped off Hackaday and they agreed with me -- this is one cool project ;)

http://hackaday.com/2016/11/10/1mhz-2-boards-4-bits-and-a-homebrew-cpu/

Congratulations on making it to the Front Page!

...I might actually have to build one of these...

  Are you sure? yes | no

agp.cooper wrote 11/11/2016 at 13:41 point

Hi,

Thanks for the plug.

The boards are available from EasyEDA (it is a public project).

But best to wait until I have debugged the boards.

I have been busy on other projects but I can put some time in now.

Regards AlanX

  Are you sure? yes | no

agp.cooper wrote 08/15/2016 at 12:11 point

Hi Rob,
Now up until recently I had an Intel databook that included the i4004 but I had a big throw out. The i4004 had more instructions and more registers. And yes I now do remember pouring over the datasheet 40 years ago.
A worthy project would be to clone it in discrete gates but perhaps that is for someone else. I think my skills would fall a bit short.

AlanX

  Are you sure? yes | no

Yann Guidon / YGDES wrote 08/15/2016 at 12:20 point

The i4004 has been implemented as discrete transistors, as well as the 6502 recently :-) 

  Are you sure? yes | no

Rob Ward wrote 08/15/2016 at 10:45 point

I have an original Intel4004 Manual from the mid seventies. Interesting stuff. Would it do most of what you are trying to achieve, ie retro & 4bit? Just building a better calculator was the target in those days.

  Are you sure? yes | no

agp.cooper wrote 08/12/2016 at 00:05 point

You may be right, I still have to buy one!
I used it In the drive to reduce chip count!
I am using the Motorola Databook from 1977 so it is genuine retro!
I have moved on to the 4 Bit CPU II and Op-Code CPU now (less chips and more efficient).
I sent off the boards last night.
AlanX

  Are you sure? yes | no

Yann Guidon / YGDES wrote 08/11/2016 at 14:34 point

I've never seen a 74x133 before, I had to look up that function :-D

https://en.wikipedia.org/wiki/List_of_7400_series_integrated_circuits

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

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