MC14500
This project is a bit-serial processor. At its core is a 1-bit processor capable of simple logic operations with shift registers attached to it to allow it to bit-serially process 8-bit words. It has access to the 64-bytes RAM in the Multiplexer, but instruction data must be provided from an external ROM. The processor is a Harvard Architecture with separate instruction and data buses.
Pinout
Pin # |
Name |
Type |
Summary |
---|---|---|---|
|
RSTD |
I |
Active low design reset |
|
I[7:0] |
I |
CPU Instruction Input |
|
PC[16:0] |
O |
Program Counter |
|
FLAG_O |
O |
High if current instruction is |
|
RR |
O |
Mirrors Result Register value |
|
SCLK |
O |
Serial Port clock signal |
|
SDO |
O |
Serial Port data output |
|
OUT1 |
O |
General-Purpose output port |
|
OUT2 |
O |
General-Purpose output port |
|
SDI |
I |
Serial Port data input |
|
CLK |
I |
Design clock input |
Please note that this design has a separate clock input at mprj_io[37]
.
1-bit Core
This design can be roughly separated into the 1-bit CPU in its core, and the shift registers and counters it uses to interface with memory. The CPU contains only three 1-bit registers.
The Result Register (RR
) is the “accumulator” for all 1-bit logic operations.
Input Enable (IEN
) and Output Enable (OEN
) are used for predication. If both are set, the CPU operates normally. If IEN
is clear, all instructions that consume Data will fetch a zero and not cause data to be shifted out of DIA
or DIB
.
If OEN
is clear, the instructions STO
and STOC
will have no effect and no data is shifted into any register.
The CPU has an instruction set of 16 instructions, meaning it uses 4-bit opcodes. These operations are as follows:
Opcode |
Instruction |
Operation |
---|---|---|
|
|
No change in RR, IEN or OEN, trigger memory read |
|
|
Load RR with Data |
|
|
Load RR with complemented Data |
|
|
Logic AND RR with Data |
|
|
Logic AND RR with complemented Data |
|
|
Logic OR RR with Data |
|
|
Logic OR RR with complemented Data |
|
|
Logic Exklusive NOT-OR with Data |
|
|
Store RR |
|
|
Store complemented RR |
|
|
Load IEN register with Data |
|
|
Load OEN register with Data |
|
|
Trigger Jump, PC is loaded from DR |
|
|
Clear MAR to 0 |
|
|
Skip next instruction if RR == 0 |
|
|
No change in RR, IEN or OEN, trigger memory write |
This opcode is taken from the least-significant 4 bits of each 8-bit instruction fed from the external ROM. The most-significant 4 bits index one of the internal machine registers. Whenever the CPU is told to load/operate on or store ‘Data’, this is refering to the CPU interacting with one of these internal registers, unless the address is 0
and the instruction reads Data, in which case a constant 1
is fetched.
Registers
The first of these machine registers is 8 bits wide starting at address 8h named the Scratch Register, and is the only bit-addressable machine register. By accessing addresses 8h - Fh, individual bits of this register can be read or written. It is mainly meant to store temporary data during processing of 8-bit bytes, but a few of the bits are wired to pins on the chip package. These bits are still readable and writable individually like the others, but their state will be mirrored onto chip pins as such:
Bit Address |
Pin mapping |
---|---|
|
None |
|
|
|
|
The pins OUT 1
and OUT 2
have dedicated registers at addresses 5h and 6h. These may only be written. The state of the input pin SDI
can be read at address 7h.
Additionally, the RR
is also output to a chip pin, and the FLAG_O
pin indicates if the current instruction is a NOPO
. These pins are meant for testing purposes or to monitor CPU activity.
There is also a 17-bit wide Program Counter register that points to the current instruction. It is output on the PC0
- PC16
pins and increments after each instruction has executed, unless the instruction is a JMP
.
The remaining registers are all shift registers to facilitate processing of 8-bit words. These are:
Mnemonic |
Bit Address |
Meaning |
---|---|---|
|
|
Destination Register for branches, write-only |
|
|
Memory Address Register to RAM, write-only |
|
|
Data Out Buffer to RAM, write-only |
|
|
Data In Buffer A from RAM, read-only |
|
|
Data In Buffer B from RAM, read-only |
All of these registers are 8 bits wide except DR
, which is 17 bits wide.
The Idea is that data from RAM is loaded into DIA
and DIB
where it can then by shited out and processed one bit at a time with the results shifted into DOB
as they are completed before being written back into RAM.
Therefore, these three registers plus MAR
shift least-significant bit first.
To actually load and store values from RAM, MAR
can be loaded with a memory address before execution of NOPO
or NOPF
triggers a value to be loaded or stored at the memory location pointed to by MAR
.
Note that because there are two input registers, NOPO
needs to be provided with an address argument to select a specific one and this address differs from the regular register address. 1
will select DIA
while 2
will select DIB
. Any other address will have no effect.
DR
facilitates branching. It is the only register which is loaded most-significant bit first and buffers a new value for the Program Counter. When the CPU hits a JMP
instruction, the value of DR
simply becomes the new Program Counter and the next instruction is fetched from this location.
JMP
is always unconditional, but can be combined with SKZ
to affect a conditional branch.
Programming
Writing programs for the MC14500 is accomplished with the help of a special assembler which assembles purely macro instructions. These macros give the outward appearance of a regular 8-bit instruction set and abstract away the bit-serial processing of data entirely.
It is the assembler’s job to translate these macro instructions into a series of CPU instructions operating bit-serially. This makes programming for the MC14500 relatively easy by not forcing the software developer to program in instructions operating on 1-bit data.