ZCpu/notes

135 lines
3.4 KiB
Text

---------------
-- Opcodes --
---------------
Argless
NOP
HLT
RST
Idfk
DBG
Memory ops
MOV
PUSH
POP
Branches
JMPA
JMP
JZ
ALU stuff
CMP
INC
DEC
------------------------
-- Addressing Modes --
------------------------
reg - Register
imm - Immediate
abs - Absolute
ida - Indirect absolute
idr - Indirect register
---- Examples ----
Assembly -- Mode -- Function
---------------------------------------------------------
mov A, 5 -- reg imm -- A <- 5
mov [$23], 5 -- ida imm -- mem[mem[23]] <- 5
mov $69, A -- abs imm -- mem[69] <- A
mov 420, [A] -- imm idr -- mem[ip + 1] <- mem[A]
add $13, $32 -- ida ida -- mem[13] <- mem[13] + mem[32]
inc A, 14 -- reg imm -- A <- A + 1 | Z <- (A == 14) # Cursed zero flag
---------------
-- Signals --
---------------
IR_W -- level -- D_BUS -> IR
LATCH_PC -- edge -- PC_MUX -> PC, PC_MUX is either PC++ or from branch logic, see SEL_PC_LOAD
SEL_PC_LOAD -- mux -- Selects between PC++ or branch logic, feeds PC register
PC_BUF -- level -- PC -> A_BUS
MAR_W -- level -- A_BUS -> MEM_A
MBR_W -- level -- MEM_D -> D_BUS or D_BUS -> MEM_D depending on MBR_W
MBR_BUF -- level -- MBR -> D_BUS
MEM_R -- level -- Put mem[MEM_A] on MEM_D
IN_SEL -- bus -- Selects register to write to
A_SEL -- bus -- Selects "A"(first operand) register
B_SEL -- bus -- Selects "B"(second operand) register
REG_WR -- edge -- regs[IN_SEL] <- REG_D_IN
REG_A_RD -- level -- A_OUT <- regs[A_SEL]
REG_B_RD -- level -- B_OUT <- regs[B_SEL]
-----------------
-- Sequences --
-----------------
---- Ring Clock ----
Clk | |#| |#| |#| |#| |#|...
PH_0 |###| | | | | | | | |...
PH_1 | | |###| | | | | | |...
PH_2 | | | | |###| | | | |...
PH_3 | | | | | | |###| | |...
PH_4 | | | | | | | | |###|...
PH_n | | | | | | | | | | |...
Clk is actually the inverse of the real "clock", on the rising edge the phase changes, then on the falling edge Clk goes high
*MOST* registers are fed by Clk and enabled by one of the phases
---- Template ----
Clk | |#| |#| |#| |#| |#|
Phase |PH0|PH1|PH2|PH3|PH4|
IR_W | | | | | | | | | | |
LATCH_PC | | | | | | | | | | |
SEL_PC_LOAD | | | | | | | | | | |
PC_BUF | | | | | | | | | | |
MAR_W | | | | | | | | | | |
MBR_W | | | | | | | | | | |
MBR_BUF | | | | | | | | | | |
MEM_R | | | | | | | | | | |
IN_SEL | | | | | | | | | | |
A_SEL | | | | | | | | | | |
B_SEL | | | | | | | | | | |
REG_WR | | | | | | | | | | |
REG_A_RD | | | | | | | | | | |
REG_B_RD | | | | | | | | | | |
---- Instruction Fetch ----
Clk | |#| |#|
Phase |PH0|PH1|
PC_BUF |###| | |
MAR_W |###| | |
LATCH_PC | | |###|
MEM_R | | |###|
MBR_W | | |###|
MBR_BUF | | |###|
IR_W | | |###|
--
In phase 0 we need to write PC to MAR via the A_BUS
In phase 1 we need to increment PC and write the data at mem[MAR] to both MBR and IR
Honestly since the opcode is just the opcode and nothing else we might be able to skip the MBR step here
--
Ph 0
----
PC -> A_BUS via PC_BUF(l)
A_BUS -> MAR via MAR_W(c)
Ph 1
----
PC + 1 -> PC via LATCH_PC(^) (SEL_PC_LOAD is 0)
MEM -> MEM_D via MEM_R(l)
MEM_D -> MBR via MBR_W(c)
MBR -> MEM_D via MBR_BUF(l)
MEM_D -> IR via IR_W(l)