Friday, November 1, 2013

ASAP-3 - Almost Simple As Possible Computer 3

The ASAP-3 is a computer/microprocessor made of discrete TTL logic chips.  It is based upon the SAP-1 (and 2 & 3) computer as described in Digital Computer Electronics by Albert Malvino.  It is an 8-bit computer and uses 55 chips to carry out its function.

Picture album of the assembly of the circuit board.

Picture album of the schematic diagrams.

A .rar file containing the schematics, ROM binaries, source code for the calculator program and an explanation of the instruction set.

The schematic was made using  Proteus Design Suite 8.0.  A demonstration version can be downloaded from the website and can be used to view the schematic file and run a simulation of the hardware.


Video Demonstration

Calculator program with a LED output:

Calculator with a LCD output:

Running with a slow clock and probing the instruction register:


Design Goals

I have been fascinated by projects like Magic-1, Big Mess o' Wires 1, The Duo Series and MyCPU but wanted to build something on my own.  While the schematics are available for several homebrew computers I didn't have enough knowledge to take those and start building.  My research lead me to the SAP-1 design.  Playing around with digital circuit simulations I was able to start making something I actually could understand.  Eventually I decided on building a 4-function calculator with a keypad input and 7-segment output.  The design was simple enough so that it felt like it could be accomplished on my own while giving a tangible result that was more than just some flashing LEDs.

Simple ≠ least amount of chips.  The display could probably be made with a multiplexing type array which would take much less PCB space.  The software side would be more complicated, and my simulation doesn't have animation faster that about 20 fps.  However, with all I have learned about programming it would probably be doable now.  The keypad could be replaced by a PS/2 keyboard and some shift-registers, again shrinking the PCB footprint significantly.  And most damning, it has been shown you don't need a bunch of chips to do interesting things!

I ended up going with an architecture that emulates much of the 8085 instruction set so I could learn extensively from pre-existing code examples instead of translating over to a new instruction set.  The microcoded ROM gives the freedom to configure many different types of addressing modes and operations.  I ended up configuring over 100 instructions, but more types of instructions and addressing modes could be implemented simply by updating the microcode.

Not having much knowledge about programming, it turned out to be almost as complicated as the hardware.  Everything was written in machine code then manually entered into a binary file.  This made for a very time consuming and inefficient way of writing and updating the program.  Doing everything first with the simulation saved a significant amount of time.


Basic Architecture

  • W-bus: A single 8-bit data bus through which all data is transferred between each element of the computer.
  • Instruction Register: Stores the instruction currently being executed.
  • Controller/Sequencer:  A counter which keeps track of which micro-instruction to execute next (T-State).  It is a 5-bit counter so it can count up to 32.  The first 4 T-states are always the fetch cycle, which means each OpCode may contain up to 28 micro-instructions.
  • Microcode ROMs: Three Flash ROMs with an 8-bit output, which decode the instruction and T-State into the appropriate set of control signals.
  • Program Counter: A 16-bit register composed of four 4-bit synchronous counters, which can be preset for Jump and Call operations
  • Memory Address Register: A 16-bit register that sets the address of the memory
  • 32kB Program ROM: A 128kB flash ROM that occupies the lower half of the memory address space.  Using manual jumpers, 4 sets of programs can be stored and used.
  • 32kB RAM: A single static RAM chip.
  • Stack Pointer: An 8-bit register, the stack can grow to 256 entries, it is fixed at the very top memory page (FFF0-FFFFh).  Its main purpose is to automatically save the program counter when jumping to a subroutine.  After returning the address can be automatically reloaded.
  • Accumulator: A register for storing the result of all arithmetic and logic operation from the ALU.  This helps simplify the architecture and instruction set.  The stored byte can also be rotated or shifted.
  • B and C registers: Two general purpose storage registers for counting or saving data during an operation.  As a pair they can also indirectly address the memory.
  • Arithmetic Logic Unit: Two 4-bit 74LS181 chips.  It can Add, Subtract, AND, OR and XOR two 8-bit numbers or can Complement, Increment or Decrement a single 8-bit number.
  • Temporary Registers:  Two registers that store data for use within a single instruction.  They cannot be directly used or addressed by a program.
  • Flag Register: 4 flip-flops that keep track of the Sign, Zero and Carry bits and whether the keypad has been pressed.  The conditional Jump and Call instructions are affected by the status of the bits in this register.
  • Keypad Decoder: Two 8-line to 3-bit decoders that translates a single key press into a 4-bit number.  It also sets the keypressed flag, which the programmer can use for detecting when new data is present in the input register.
  • Input Register: Each press of the keypad clocks in the code for the keypress, which can then be loaded by the computer.
  • Output Register/LED display: An 10x8-bit shift register in which each individual register also drives a 7-segment LED display.  Clocking out one byte shifts the display by one character.


Bugs and Problems Encountered

The CPU speed is limited to 500kHz.  Somewhere between 500kHz and 1Mhz some instructions stop working, notably conditional calls and jumps.  At 2MHz and above it seems to stop working altogether.  I don't have a logic analyser so I can only speculate as to the exact cause.  I ended up bread-boarding some of the controller/sequencer and found (with my oscilloscope) that when changing between certain ranges of address, the outputs of the ROM will have a momentary glitch.  These glitches are enough to trigger the asynchronous set or clear inputs of flip-flops and registers.  So basically any input that is not synchronous with the CLK signal is vulnerable to being erroneously triggered (Like the /NOP signal).  Buffering each control word with another register that filters out these glitches may help but this complicates the design.

The tactile switches in the keyboard bounce significantly and don't always get decoded properly.  Pressing hard then releasing quickly minimizes the issue.  Also a significant software delay must be used before resetting the keypressed flag or the still bouncing switch will re-trigger it leading to a double input of the same character.

The switch that changes between an external and internal clock cannot be used while the computer is running. As it doesn't have any de-bounce circuitry, it will actually induce the bouncing into the clock signals.  If you switch to an external clock source while it is running some of the registers can latch up causing a crash.  Also, I should have wired the switches so the Auto/Manual switch overrides the Internal/External switch.  As built, while in external clock mode you cannot switch back to single step mode.

During simulation in Proteus Design Suite, I found that the carry bit from the 74LS181 model did not propagate correctly for certain operations.  This lead to weird results if subtracting two numbers and there was a carry between the upper and low nibbles.  It was fixed by emulating the function of a 74LS181 with a ROM acting as a look-up table for every possible combination of inputs.


Final Thoughts

Overall this was a very humbling experience.  I have spent the majority of my free time over the past year learning about digital electronics, CPU design and programming with machine code and the end result is a device that doesn't even have the functionality of a 99 cent pocket calculator.  And I definitely could not have accomplished this modest height without the extensive knowledge written by those who came before me.  It definitely makes me appreciate all the technology one has at their disposal today.

Saturday, May 4, 2013

SAP-1 Simple as Possible Computer with Discrete Component RAM

I have been asked a few times how to design a 16-byte RAM using standard TTL parts.  One way to do this is to use 8-bit registers to hold each byte.  A 74LS373 is an 8-bit latch type register with 3-state outputs, several chips can share the same input and output buses.  Two 74LS138 and two 74HCT238 3-bit to 8-line decoders are used for decoding the addresses.

Each decoder has two active low enable inputs and one active high enable input.  Internally they translate a 3-bit number to activate 1 out of 8 outputs.  The '138 has active low outputs, if the chip is not enabled then all outputs are high.  The '238 has active high outputs, if the chip is not enabled then all outputs are low.  The least significant 3 bits of the 4-bit address (from the MAR) connect to the select inputs.  The most significant bit connects to the (active low) enable of the first decoder and the (active high) enable of the second encoder.  So addresses 0 through 7 activate the lowest 8 lines and addresses 8 thought 15 activate the highest 8 lines.  Finally, either the WEram (write enable ram) or CE (chip enable) signals must go low for any of the control signals to activate.

These Input and Output signals go to each individual register chip.  To enter data, the address and data is set using the DIP switches (in Program mode) and the Write Memory button is pressed.  This sets the LE signal of the register high and the data is latched in to memory.  When reading data the controller/sequencer sends the CE signal to the memory decoder and whichever register is selected by the MAR outputs its data to the W-bus.

I have also made a second design that uses an additional 74LS245 bus transceiver.  This allows you, during simulation in ISIS, to view what data is actually stored in each byte of RAM.

Here is a file that contains the schematics for each design.

Thursday, March 28, 2013

ASAP-2 Almost Simple As Possible Computer - Version 2

Here is version 2 of my ASAP-2 Almost Simple As Possible Computer.  A few changes have been made to the circuit.

The conditional jumps will have either 6 or 9 T-states depending on whether the condition is true.  During a jump operation the selector will choose among the flags depending on the opcode (Jump if Positive microcode shown).  If the condition is false and jump is enabled, the output of U9 will be high and the sequence will simply increment the program counter to the next opcode.  If the condition is true and jump is enabled then U9 will go low.  The controller sequencer will then load the value 8 (D3 = 1, D2,D1,D0 = 0) on the positive going clock edge and the micro-instruction pointer will now be at the 9th instruction; this will carry out loading the program counter with the new value.

The I/O Ports are addressable by an 8-bit number, so up to 256 of either inputs or outputs can be supported by the I/O opcodes.  In this case minimal decoding is used and only 2 inputs and 2 outputs are placed.  During an operation the port selector buffer is loaded with the chosen I/O number.  This is decoded to pass along the enable signal to the correct port.  When active, either a low buffer enable or a positive going clock will be passed to the selected port.  The inputs are simply an 8-line 3-state buffer.  The outputs are 8-bit D-Type registers.

Dealing with the Carry Flag becomes quite complicated since a number of different opcodes affect the Carry Flag.  When rotating or shifting the accumulator, the previous MSB/LSB becomes the Carry Flag; but depending on the operation, the old Carry Flag may or may not be shifted in as the new MSB/LSB.  Some ALU operations use the current value of the Carry Flag, others need either a 1 or a 0 to get the correct result.  The two data selectors route the Carry Flag and the MSB/LSB of the accumulator to support Rotate Left/Right, Rotate-Through Carry Left/Right and Arithmetic Shift Left/Right.


Link to a RAR file of the schematics, ROM files and microcode.

Saturday, March 16, 2013

Wednesday, February 27, 2013

ASAP-2 Almost Simple As Possible Computer 2

Here is what I call the ASAP-2 Almost Simple As Possible Computer.  It is based on the SAP-2 as described in Digital Computer Electronics by Albert Malvino.  I made a few changes to the design: there is only one input register, the memory is split in to a 32kB ROM and 32kB RAM, the ALU supports a Carry flag, the OPcodes no longer follow the 8085 numbering and I have more than doubled the number of OPcodes.

The basic architecture of the circuit:

Having the ALU A input directly connected to the W-bus adds a lot of flexibility to the design.  I originally had a temporary register on both ALU inputs but this required another 3-state buffer on the ALU output.

The schematic was made using Proteus Design Suite version 8.0 SP1 and the demo version should be able to view and simulate the circuit.


I consider this to be a work in progress.  I plan to add some more decoding on the controller/sequencer to get the number of ROMs down to 4 (ROMs $ > 74HC138 $).  It was probably a mistake to change the I/O functions to 1 byte commands as this limits the ability to address and expand the I/O bus.  Also, adding some OPCodes that use the B/C registers as a memory address pointer would be useful.

Thursday, January 24, 2013

SAP-1 with a Microcoded ROM

Here is my attempt at designing a SAP-1 microprocessor with a micro-code ROM controller sequencer and a variable machine cycle.  The total number of ICs has decreased from 48 to 35.  My design deviates a bit from the block diagram shown at the end of chapter 10.  Looking at Digikey's catalogue, 16x4-bit or 16x8-bit ROMs are simply not available anymore.  I ended up using two 8Kx8-bit ROMs to give a 16-bit control word.  Obviously only a tiny fraction of the storage is used.  Also, the simulation program only has a few parallel access ROMs in its library anyway.  I took advantage of this wider address space to simplify the design.  Something like the AT28C64B (Digikey Part Page) can be used.  You will also need an EEPROM programmer; many inexpensive but adequate ones are available on eBay.

The OPCode half of the instruction register outputs directly to the address lines of the micro-code ROMs.  To simplify things, each instruction's microcode takes up a fixed block of 8-bytes, this allows for up to 8 micro-instructions for each routine.  Each instruction has 4-bits for the OPCode so there can be up to 16 OPCodes; this iteration of the SAP-1 has 8 instructions in its set.  Each machine cycle executes as follows:

  • T1: Load the memory address register from the program counter.
  • T2: Increment the program counter, load instruction from the RAM.
  • As soon as the instruction is loaded from RAM, the ROM address now points to the microcode for that instruction.
  • T3,T... Continue executing the instruction.
  • NOP: This resets the Controller/Sequencer counter back to zero and the machine cycle repeats.
 To save on manually entering a program each time the simulation is run, I have added an auto-loader circuit that will load into RAM a program saved in a ROM.  In the simulation, the ROMs are loaded from a linked binary file, which can be edited with a Hex editor to change the program.  Three 2:1 data selectors (think of them as a gang operated 4PDT switch) were added to easily switch between run/execute, manual programming and auto-programming.  Unfortunately the data input circuit is now much more convoluted.

The contents of memory once the auto-loader has completed.

And here the contents of the accumulator has been transferred to RAM by the store instruction.

The ROM allows for much more flexibility in creating and editing the instruction set.  The Jump, Store and Output memory instructions have been added to the original set.

The microcode for each instruction.  Thank-you to Kyle at 8-bit Spaghetti where I first saw this nice layout for the microcode.  He also has a build log of his own SAP-1 computer.

SAP-1 with Microcoded ROM

Link to a RAR file of the schematics, ROM binaries and microcode. 

Monday, January 21, 2013

SAP-1 Updated Design

Here is the updated design for the SAP-1 microprocessor.  I've made a number of changes that should allow someone to build this circuit using parts that are readily available from a place like Digikey.  To summarize:
  • All parts changed to 74HC high speed CMOS, no more worries about fanout limits and sinking vs. sourcing differences in current.  However the unused gates (not shown) will have to be properly terminated as per the usual issues with floating hi-impedance inputs.
  • Some newer parts have been used (4-bit counter, octal 3-state buffer) to simplify the design and reduces the chip count.
  • The 74LS189 RAM has been replaced with a 32kB CMOS Asynchronous Static RAM.  A part like the Cypress Semiconductor CY7C199CN can be used for the RAM (Digikey Part Page).
  • Since the RAM uses the same pins for input and output, another set of 3-state buffers is used to output or isolate the data switches from the W-bus.
  • To clean up the schematic the W-bus is only shown as a connection to a common bus.
  • A logic analyzer has been added to show how the control signals are sequenced.
This design still utilizes a hardwired controller sequencer.  Any changes to the microcode require a complete re-design of this circuit which is very cumbersome.  The next design will utilize a microcoded ROM to handle the control sequence, as outlined at the end of the chapter.

Here is the memory contents of a sample program entered into the SAP-1.  It can be found on page 146 of Digital Computer Electronics (Example 10-3).

SAP-1 Updated Design

Link to schematic file.
Link to PDF of schematic.

Sunday, January 20, 2013

SAP-1 Simple As Possible Computer

Here is an almost identical recreation of the SAP-1 Simple As Possible microprocessor, as published in Digital Computer Electronics by Albert Malvino and Jerald Brown.  While the book is out of print an "ebook" can be found fairly easily if you know where to look.

I used Labcenter Electronics' Proteus Design Suite to draw the schematic.  A demo version can be downloaded from under the download tab.  It can do everything except save or print, so the circuit can be simulated when opened (use the Import Legacy Design).

Unfortunately the original design uses 74LS189 16x4-bit RAM, which can only be found on eBay right now.  That means it would be difficult to actually build this circuit.  I am working on an updated design that uses 74HC chips and other commonly available parts.  For now you can try out the classic design and see how it works for yourself.

Link to Schematic File.
Link to PDF of Schematic.

SAP-1 Schematic