--------------- -- 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)