Hode Computer - Talk
* arch decisions
* processor only, use RasPi for memory and IO
* use BJTs, diodes, resistors, capacitors
no flower (germanium) transistors, too expensive
just dirt/sand-cheap silicon
* no MOSFETs or ICs
* not a toy - useable address space, interrupts
* byte addressable memory, no 12-bit or 18-bit nonsense
* other than that, dead simple to minimize transistor count
* 6800-like 8-bit still requires 16-bit adder
8 & 16-bit accumulators
two 16-bit index registers
16-bit program counter
complex instructions
4000+ transistors
* could do IBM-1130-like (accumulator) but add bytes
would need 16-bit accum register, PC register, couple index registers
* PDP-11 has 8 16-bit registers, one is PC
addressing modes complex, would need lots of states
* do Alpha/ARM-like 16-bit RISC with PDP-11-style registers
load/store for memory access (byte and word sized)
arithmetic on registers only
branches need condition code register
having PC be a regular register means don't need separate instructions for return, table jumps, etc
dead simple to implement
* needed registers
8 16-bit registers R0..R7, R7 is PC
could get by with 4 or 6 registers
5-bit processor status PS (interrupt enable IE + condition codes NZVC)
+------+-------------------+-----+-----+-----+-----+
| IE | . . . | N | Z | V | C |
+------+-------------------+-----+-----+-----+-----+
16-bit instruction register IR
state flipflops (turns out need 24)
* interrupts
* since just one interrupt request line,
save PC,PS in fixed memory locations FFFC,FFFE
start of interrupt service routine is 0002
no need for hardware stack pointer
* need return from interrupt instruction to restore PC,PS
* instructions, fixed 16-bit width for simplicity
loads/stores
arithmetics
branches
miscellaneous
read/write PSW (cond codes, interrupt enable)
return from interrupt
halt (or wait for interrupt)
IR[15:13] = major opcode
IR[12:10] = A register
IR[09:07] = D register
IR[06:04] = B register
IR[03:00] = minor opcode
+---.---.---+---.---.---+---.---.---+---.---.---+---.---.---.---+
| major | A-reg | D-reg | B-reg | minor |
+---.---.---+---.---.---+---.---.---+---.---.---+---.---.---.---+
13 10 7 4 0
loads/stores use A for address register, D for data register
B and minorop fields used for 7-bit signed offset
+---.---.---+---.---.---+---.---.---+---.---.---.---.---.---.---+
| major | A-reg | D-reg | byte offset |
+---.---.---+---.---.---+---.---.---+---.---.---.---.---.---.---+
13 10 7 0
arithmetics use A,B registers for ALU inputs
ALU output written to D register
minorop says which op to perform (ADD, SUB, AND, etc)
+---.---.---+---.---.---+---.---.---+---.---.---+---.---.---.---+
| 0 0 1 | A-reg | D-reg | B-reg | minor |
+---.---.---+---.---.---+---.---.---+---.---.---+---.---.---.---+
13 10 7 4 0
branches:
[12:10,00] = branch condition (non-zero)
[09:01] = signed word displacement
+---.---.---+---.---.---+---.---.---.---.---.---.---.---.---+---+
| 0 0 0 | cond | word offset | c |
+---.---.---+---.---.---+---.---.---.---.---.---.---.---.---+---+
13 10 1 0
miscellaneous:
[15:10,00] = zeroes
[02:01] = minorop says which misc instr
00 HALT sends B-reg to RasPi for halt reason
01 IRET doesn't use any other fields
10 WRPS uses B-reg to select register
11 RDPS uses D-reg to select register
+---.---.---.---.---.---+---.---.---+---.---.---+---.---.---.---+
| 0 0 0 0 0 0 | D-reg | B-reg | x | minor | 0 |
+---.---.---.---.---.---+---.---.---+---.---.---+---.---.---.---+
10 7 4 3 1 0
* transistor estimates
* registers: 6 x 16 x 8 = 800 + 20% for control = 1000
actual: 1200 (newer design 1080)
* alu: 20 x 16 = 320 (3 xors, and, or, multiplexor, decoding)
actual: 440 (newer design 380)
* ir: 5 x 16 = 80; psw: 6 x 5 = 30; raspi intf: 3 x 16 + 10 = 60
80 + 30 + 60 = 170 + 20% connection = 200
actual: 270
* seq: 24 x 6 = 144 + 100% decoders = 300
actual: 200
* total: 1000 + 300 + 200 + 300 = 1800
actual: 1200 + 440 + 270 + 200 = 2110
1 sq in per gate = 1800 sq in required
largest board can be made is 500mm x 500mm or 19.5in x 19.5in
18 x 18 with margins = 300 transistors per board = 6 boards
actually need 8 boards
* data & ctrl block diagrams
+-------------+
+------< <B |
| | REGISTERS D< <--+ . . . 4 x regboard
| +--< <A | |
| | a +-------------+ |
| | b |
| | u |
| | s |
| | +-------------+ |
| +--> >A | | d
b | | ALU D> >--+ b . . 2 x aluboard
b +------> >B | | u
u | +-------------+ | s
s | |
| . . . . . . . . . . . | &
| . . |
| . +-------------+ . | c
| . | | . | a
+------< <B PSW D< <--+ r
| . | | . | r
| . +-------------+ . | i
| . . | e
| . . | s
| . . |
| . +-------------+ . |
| . | | . |
+------< <B BCONS | . |
| . | | . |
| . +-------------+ . |
| . . |
| . . |
| . . |
| . +-------------+ . |
+------< <B | . |
. | RASPI MD< <--+
+--< <MQ | .
| . +-------------+ . . . . . rasboard
| . .
| . .
| . .
| . +-------------+ . +-------------+ . . . seqboard
| . | | . | |
+--> >D INSTREG Q> >------> >I SEQUENCER C> >------>
. | | ibus | | cbus
. +-------------+ . +-------------+
. . . . . . . . . . .
* busses & board contents
* abus & bbus, controls, ibus, dbus & carries
* primary input on left, primary output on right
* seq: input ibus, output controls
holds state flipflops, instruction decoding, control encoding
* ras: input dbus, output bbus
holds raspberry pi and interfacing, processor status word, instruction register
secondary output ibus
also drives clock, reset, intreq, intenab, branchtrue controls
rotated 90deg ccw
* alu: input abus & bbus, output dbus & carries
each board is an 8-bit alu
combinational logic only
jumpers determine which byte each board does
rotated 90deg cw
* reg: input dbus, output abus & ibus
each board holds 2 16-bit registers
jumpers determine which even/odd register pair the board is for
processor runs with minimum of one register board containing R6/R7
...but not terribly useful cuz arithmetic is register-to-register only
rotated 90deg ccw
* states
RESET.0 waits here as long as async RESET signal is asserted from RasPi
RESET.1 clocks here after RESET negated on next positive clock edge from RasPI
FETCH.1 sends PC to RasPi and asserts MEM_READ to start reading instruction
FETCH.2 receives instruction from RasPi and increments PC via the ALU
BCC.1 computes new PC via the ALU and decides whether or not to write PC by end of cycle
ARITH.1 does arithmetic on two registers via ALU and writes result to third at end of cycle and updates condition codes
LDA.1 adds offset to address register and writes result to data register at end of cycle
LOAD.1 adds offset to address register and sends to RasPi along with MEM_READ to start a read cycle
LOAD.2 receives data from RasPi and writes to data register at end of cycle
LOAD.3 if LD Rx,0(PC) this state increments PC over the immediate operand
STORE.1 adds offset to address register and sends to RasPi along with MEM_WRITE to start a write cycle
STORE.2 send data register to RasPi giving the data to be written
RDPS.1 gates PS through ALU and writes D register at end of cycle
WRPS.1 gates B register through ALU and writes to PS at end of cycle
HALT.1 gates B register through ALU on to RasPi and asserts HALT signal to RasPi
RasPi can stop clocking processor, processor continues with program when RasPi resumes clocking
IRET.1 send FFFC to RasPi along with MEM_READ to start reading saved PC from memory
IRET.2 receive saved PC value from RasPi and write to R7 (PC) at end of cycle
IRET.3 send FFFE to RasPi along with MEM_READ to start reading saved PS from memory
IRET.4 receive saved PS value from RasPi and write to PS at end of cycle
IREQ.1 send FFFE to RasPi along with MEM_WRITE to start writing saved PS to memory
IREQ.2 gate PS through ALU to RasPi to write to memory location FFFE
IREQ.3 send FFFC to RasPi along with MEM_WRITE to start writing saved PC to memory
IREQ.4 gate PC through ALU to RasPi to write to memory location FFFC ; clear PS<IE> bit
IREQ.5 send 0002 through ALU to write to R7 (PC) at end of cycle
* clocking
driven by RasPi GPIO pin CLK2 -> _CLK1 -> CLK0
mostly D flipflops clocked on leading edge of clock
IR latch open during FETCH2
RasPi takes sample just before raising clock
persists read data until halfway through next cycle
* raspi interface
Raspberry PI provides memory and IO via the GPIO connector.
+-------------------+ +--------+
| | | |
| Raspberry PI G | ---> clock,reset,intreq ---> | Hode |
| P | | CPU |
| I | <--- halt,memread,write,word <--- | |
| O | | |
| | <---- address[16]/data[16] ----> | |
| | | |
+-------------------+ +--------+
Signals from raspi to processor:
clock
reset
intreq
Signals from processor to raspi:
memory read
memory write
word vs byte
halted
+ 16-bit bi-directional address/data bus
* electrics
basic gate is and-or-invert
2N3904 5 cents ea
capacitors 5 cents ea
diodes/resistors 1 cent ea
2N3904 peak beta 100 at ic=10mA, tapers to 80 at 25mA
operate at 10-25mA for fanout 1-10
Rc = 680
Ra = 2.7K
Rb base resistor
4.7K ~300nS low-to-high, mininum beta 25 needed for fanout 10
1.0K <100nS low-to-high, minimum beta 60 needed for fanout 10
Originally built using 4.7K resistors for Rb. Processor ran at just under 70KHz (14.3uS).
Rebuilt lower ALU board with 1.0K resistors and added carry look-ahead.
Runs an hair above 84KHz (11.9uS) now, a 20% improvement.
dffs are 6 2- or 3-input nand gates
latches are 4 2-input nand gates
similar raspi level converters
* netgen
design written in simplified Verilog-like language
module, wire, assign
assign supports & | ~
built-in modules for connector, D-flipflop, latch, raspberry-pi
netgen java program compiles then simulates and generates
simulation scripts written in tcl (like qvartvs), simulates at gate level
generation creates kicad net and pcb files (looks like scheme) and a report
needs a map file for placement at gate and flipflop level
gate and flipflop internals are pre-routed
* raspictl
generates clock, reset, intreq signals
receives memread, memwrite, halt signals
operates bi-directional data bus
shadows processor state for verification
contains 64K byte array for memory
check for magic memory location (FFF0) access by processor for IO
used for synchronous syscalls
processor program generates an argument block somewhere in memory
...then writes its address to FFF0
RasPi then parses the argument block and performs corresponding IO
when IO is complete, RasPi resumes clocking the processor
processor program reads IO status from FFF0
currently does exit(), close(), gettimeofday(), open(), read(), write()
...also can assert/negate interrupt request line for testing
and simple println() call for debugging
can also generate random opcodes and operands for testing
* test programs
unit tests (one per board type) use paddles to operate boards
paddles are slow to write (200 Hz)
ras board needs gpio connected as well as paddles
running alutest on new alu board
integration test
generates random opcodes
minimum of seq, ras boards required
paddles required if no alu boards
any combo register boards