Synchronous All-Purpose Minimal Instruction Reckoning Apparatus

Similar projects worth following
Synchronous All-Purpose Minimal Instruction Reckoning Apparatus

An attempt to improve my first homebuilt CPU that resulted in a new design.

This CPU will be slightly faster, more powerful, extensible and will be able to address a larger main memory than it's predecessor! I am using the wire-wrap technique to make electrical connections and one board is almost done.

Please read the logs below to learn about the progress :)

SAMIRA MK-II is a 8 bit RISC von-Neumann-type accumulator machine without microcode, which means it only has one register - the accumulator - to work with, the result of every calculation is automatically stored back into it. All instructions have a fixed length of two bytes, the first byte specifies the operation to perform, the second byte can either be data or an address. This keeps the decoder fairly simple and execution times consistent. The 4kB main memory is divided into 16 blocks of 256 bytes each, memory access (including branching) to blocks other than the current block (where code execution is happening) is possible but limited.

The modules of the CPU are:

CLK - master clock, can be stepped manually or runs on auto
CTRL - controls the state of the machine, running, halted or reset
SEQ - sequencer, controls the instruction cycle
DEC - decoder, generates control signals in the CPU
IR - instruction register, holds the current instruction
RAM - main memory, holds code and data
PC - program counter, holds current program position
OP - operand register, holds the current operand, either data or address
A - accumulator, the one and only main working register
ALU - arithmetic & logic unit, performs calculations and handles branches
Y - current block register, contains the currently active block address
IO - provides an extendable bus interface for additional devices

The ever repeating instruction cycle consists of these steps:

FI - fetch instruction, IR=M(PC)
INC - increment PC to next address, PC=PC+1
FO - fetch operand, OP=M(PC)
INC - increment PC again, PC=PC+1
EXE - command is decoded and executed if conditions are met, registers are modified

The following instructions can be executed:

NOP - no operation, does nothing but wait
LD - loads a byte from memory to A
STO - stores the content of A to memory
ALU - arithmetic or logic operation is applied on A
BRN - program counter is loaded, program flow is altered
IN - reads data from a peripheral device to A
OUT - writes data to a peripheral device from A
HLT - halts the main clock and stops execution of code

There are three addressing modes available:

Immediate - OP is directly used as data
Relative - OP contains address reference relative to the base of the block
Absolute - OP contains absolute adress reference
Inherent - OP is discarded

The ALU can add, subtract, shift left and right, apply bitwise AND and NOR.
The branch logic can act depending on the flags zero, carry and sign.

More details will follow!

  • Log05

    0xCAFEAFFE09/30/2017 at 13:16 0 comments

    I started working on the project once again but I was no longer satisfied with the design so I made some changes to it again. I decreased memory size to 4k, simplified adressing modes which further simplifies the decoder, added bitshift operations and maybe the biggest change: From now on it will be possible to execute all instructions conditionally, depending on flags Z, C or S! I deleted some of the logs that were now invalid! I'll need to rewire parts of the ALU board.

  • Log01

    0xCAFEAFFE05/17/2016 at 19:46 0 comments

    Wire-wrapping rocks! I'm progressing really fast, the first board (ALU) is almost done, I updated the picture in the gallery.
    I realized I have to improve a small part of the address-logic, but that won't be a large problem.
    Next log will be more extensive and will follow soon :)

  • Log00 - why? why not!

    0xCAFEAFFE05/12/2016 at 22:14 0 comments

    Alright, so what did I learn from the first version of S.A.M.I.R.A. and why do I build a second one?

    1) The ALU was alright, the MK-II will posess a marginally more powerful ALU, which will not only be able to add and subtract, but also use NAND and NOR gates to perform logic operations and bitmasks.

    2) The sequencer will be slightly faster and more efficient.

    3) The decoder will no longer be hardwired but implemented in a ROM lookup table.

    4) Branch logic will be improved. Branching conditions will be: Zero, Carry, Sign, Input. All of them can be used inverted.

    5) I need more memory. Version 1 is limited to 256 bytes (!) of main memory, this is due to the address bus beeing of the same width as the data bus, which simplified the design. If I ever want to have an operating system running on my machine, 256 bytes won't get me anywhere. This problem will be solved in MK-II, by splitting up a much larger memory (up 64k) into smaller blocks of 256 bytes. Access to and execution of content will only be possible within such a block, but switching between blocks will be enabled by a special instruction.

    6) The hardware design needs some serious fixing. Testing the design on breadboard will not be nessecary again because I gathered sufficient experience with digital logic and the design already works in Logisim and in my emulator. Also soldering all connections does not work very well. Neither the 'traditional' way (wires go down through the holes and are soldered to the IC on the bottom side of the board) nor my pseudo-wire-wrap-technique (thin wires directly soldered onto the pins of the ICs on the bottom side of the board)
    So what i will do: ICs on top, pin headers parallel to them, soldered together on the bottom side, but wire-wrapped on the top side. This will be easier, faster and cleaner. Pin headers are not perfect for wire-wrapping but alright. The whole system will be split onto seperate boards, which will be connected via one 'main bus board'. Extensions and peripherials can simply be added by plugging them in the same bus board.

    So eventually I WILL be able to run my own operating system (probably FORTH-like) and operate it through a serial terminal. Let's do this :)

View all 3 project logs

Enjoy this project?



mrpeterbell wrote 05/02/2020 at 12:49 point

SAMIRA is a Persian name for a girl.

  Are you sure? yes | no

esot.eric wrote 11/06/2016 at 22:09 point

Cool, never seen component-side wire-wrapping before. Looks great

Groovy background-image, too.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/06/2016 at 11:59 point

Log03 got duplicated :-)

Oh and if your instructions are fixed 2 bytes, it's a pain to see you spend 4 cycles fetching 2 bytes. Just increase PC by 2 and toggle the LSB ? :-)

Keep faith !

  Are you sure? yes | no

0xCAFEAFFE wrote 11/06/2016 at 13:45 point

Thank you for the hints! There is no way to increment the PC by 2 though, this machine does not have microcode, therefore the PC can not be manipulated by the ALU, in hardware it is simply a loadable binary counter! Execution speed never really was a priority, but I will consider decreasing the period of the fetch cycles!

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/06/2016 at 14:19 point

Your PC incrementer can remain physically the same, but the LSB will come from the FSM :-) (the counter's MSB will be unused)

Going from 5 to 4 steps per instruction, a simple 2-bits counter is enough, its LSB can go to the LSB of the instruction address. Or something like that.

Even simpler : having a 16-bits memory bus, or two 8 bits memory banks (odd&even), so they can be accessed at the same time. Normal data access will simply select the memory bank from the address' LSB.

  Are you sure? yes | no

0xCAFEAFFE wrote 09/30/2017 at 13:36 point

I just read your comment again and now I understand what you meant! Nice idea, maybe I'll actually implement it, thx! :)

  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