Complete rewrite from scratch, bootstrap WIP

Rewrite to use several bus multiplexers, resulting into a less messy
microarchitecture (hopefully). Some more room for cleanup though...

Supports every instruction from the bootstrap rom, more or less.
LY hacked at 0x90 to progress through vsync instantly.
No cartridge is present yet, so we will always fail checksum test and lock up.
This commit is contained in:
2023-10-01 23:00:56 +01:00
parent e713f8de87
commit fda176d3b5
23 changed files with 1425 additions and 956 deletions

View File

@@ -1,128 +1,144 @@
package cpu_pkg;
//
// 4 | ST0_ADDR -> ST1_DEC -> ST2_EXEC -> ST3_NOP
// 12 | '-> ST2_DEC -> ST3_DEC -> ST4_EXEC -> .... -> ST11_NOP
//
typedef enum {
ST0_ADDR,
ST1_DEC,
ST2_EXEC,
ST2_DEC,
ST3_DEC,
ST3_EXEC,
ST4_EXEC,
ST5_EXEC
} state_t;
typedef enum logic [2:0] {
REG8_B = 3'h00,
REG8_C = 3'h01,
REG8_D = 3'h02,
REG8_E = 3'h03,
REG8_H = 3'h04,
REG8_L = 3'h05,
REG8_PHL = 3'h06,
REG8_A = 3'h07
} reg8_t;
typedef enum logic [2:0] {
REG8_B = 3'h00,
REG8_C = 3'h01,
REG8_D = 3'h02,
REG8_E = 3'h03,
REG8_H = 3'h04,
REG8_L = 3'h05,
REG8_PHL = 3'h06,
REG8_A = 3'h07
} reg8_t;
typedef enum logic [1:0] {
REG16_BC = 2'h00,
REG16_DE = 2'h01,
REG16_HL = 2'h02,
REG16_SP_AF = 2'h03
} reg16_t;
typedef enum logic [1:0] {
REG16_BC = 2'h00,
REG16_DE = 2'h01,
REG16_HL = 2'h02,
REG16_SP_AF = 2'h03
} reg16_t;
typedef enum logic [1:0] {
CC_NZ = 2'h00,
CC_Z = 2'h01,
CC_NC = 2'h02,
CC_C = 2'h03
} cc_t;
typedef enum logic [1:0] {
CC_NZ = 2'h00,
CC_Z = 2'h01,
CC_NC = 2'h02,
CC_C = 2'h03
} cc_t;
typedef enum logic [2:0] {
ALU_OP_ADD = 3'h00,
ALU_OP_ADC = 3'h01,
ALU_OP_SUB = 3'h02,
ALU_OP_SBC = 3'h03,
ALU_OP_AND = 3'h04,
ALU_OP_XOR = 3'h05,
ALU_OP_OR = 3'h06,
ALU_OP_CP = 3'h07
} alu_op_t;
typedef enum logic [4:0] {
ALU_OP_ADD = 5'h00,
ALU_OP_ADC = 5'h01,
ALU_OP_SUB = 5'h02,
ALU_OP_SBC = 5'h03,
ALU_OP_AND = 5'h04,
ALU_OP_XOR = 5'h05,
ALU_OP_OR = 5'h06,
ALU_OP_CP = 5'h07,
ALU_OP_BIT = 5'h08,
ALU_OP_NOP = 5'h09, // Write operand to a
ALU_OP_NOPF = 5'h0a, // Write operand to f
ALU_OP_ROT = 5'h0b,
ALU_OP_INC = 5'h0c,
ALU_OP_INCR = 5'h0d // Increment register instead of a
} alu_op_t;
typedef enum logic [2:0] {
SHIFT_OP_RLC = 3'h00,
SHIFT_OP_RRC = 3'h01,
SHIFT_OP_RL = 3'h02,
SHIFT_OP_RR = 3'h03,
SHIFT_OP_SLA = 3'h04,
SHIFT_OP_SRA = 3'h05,
SHIFT_OP_SLL = 3'h06,
SHIFT_OP_SRL = 3'h07
} shift_op_t;
typedef enum logic [2:0] {
ROT_OP_RLC = 3'h00,
ROT_OP_RRC = 3'h01,
ROT_OP_RL = 3'h02,
ROT_OP_RR = 3'h03,
ROT_OP_SLA = 3'h04,
ROT_OP_SRA = 3'h05,
ROT_OP_SLL = 3'h06,
ROT_OP_SRL = 3'h07
} rot_op_t;
typedef struct packed {
logic b;
logic s;
logic r;
logic [2:0] operand;
} bsr_op_t;
typedef enum logic [1:0] {
ALU16_OP_ADD = 2'h00,
ALU16_INC = 2'h01,
ALU16_DEC = 2'h02
} alu16_op_t;
typedef struct packed {
logic inc;
logic dec;
logic dst_a;
} incdec_op_t;
typedef enum {
OP_SRC_A,
OP_SRC_F,
OP_SRC_REG8,
OP_SRC_OPERAND8,
OP_SRC_MEMORY,
OP_SRC_OPERAND16,
OP_SRC_REG16,
OP_SRC_PC_L,
OP_SRC_PC_H
} op_src_t;
typedef struct packed {
logic update_a;
logic update_f;
logic alu_op_valid;
alu_op_t alu_op;
logic shift_op_valid;
shift_op_t shift_op;
logic bsr_op_valid;
bsr_op_t bsr_op;
logic incdec_op_valid;
incdec_op_t incdec_op;
} alu_ctrl_t;
typedef enum {
OP_DEST_A,
OP_DEST_REG8,
OP_DEST_REG16,
OP_DEST_MEMORY
} op_dest_t;
typedef enum {
ADDR_SRC_PC,
ADDR_SRC_SP,
ADDR_SRC_REG16, // TODO reuse BUS_Q
ADDR_SRC_REG8, // TODO reuse BUS_Q
ADDR_SRC_OPERAND8,
ADDR_SRC_OPERAND16,
ADDR_SRC_BUS_P,
ADDR_SRC_BUS_Q
} addr_src_t;
typedef enum {
SP_SRC_OPERAND16,
SP_SRC_INC,
SP_SRC_DEC
} sp_src_t;
typedef enum {
BUS_SRC_A,
BUS_SRC_F,
BUS_SRC_REG8,
BUS_SRC_OPERAND8_H,
BUS_SRC_OPERAND8_L,
BUS_SRC_ALU,
BUS_SRC_MEM,
BUS_SRC_PC_H,
BUS_SRC_PC_L,
BUS_SRC_REG16_H,
BUS_SRC_REG16_L
} bus_src_t;
typedef enum {
ADR_SRC_PC,
ADR_SRC_HL,
ADR_SRC_SP,
ADR_SRC_SP_P1, // SP + 1 for pop
ADR_SRC_REG8, // extended with FF
ADR_SRC_REG16,
ADR_SRC_OPERAND8, // extended with FF
ADR_SRC_OPERAND16
} adr_src_t;
typedef enum {
BUS_DST_SP_H,
BUS_DST_SP_L,
BUS_DST_ALU,
BUS_DST_REG8,
BUS_DST_REG16_H,
BUS_DST_REG16_L,
BUS_DST_PC_H,
BUS_DST_PC_L,
BUS_DST_MEM
} bus_dst_t;
typedef enum {
PC_SRC_SEQ,
PC_SRC_OPERAND8,
PC_SRC_OPERAND16
} pc_src_t;
typedef struct packed {
bus_src_t src;
bus_dst_t dst;
logic wen;
} bus_ctrl_t;
endpackage
typedef enum {
BUS16_SRC_REG16,
BUS16_SRC_ALU16,
BUS16_SRC_SP
} bus16_src_t;
`define DEF_FF(register, next, we, rst_value) \
always_ff @(posedge clk_i or negedge nreset_i) begin \
if (~nreset_i) begin \
register <= (rst_value); \
end else if ((we)) begin \
register <= (next); \
end \
end
typedef enum {
BUS16_DST_REG16,
BUS16_DST_ALU16,
BUS16_DST_SP
} bus16_dst_t;
typedef struct packed {
bus16_src_t src;
bus16_dst_t dst;
logic wen;
} bus16_ctrl_t;
typedef enum {
PC_SRC_INC,
PC_SRC_OPERAND8,
PC_SRC_OPERAND16,
PC_SRC_BUS
} pc_src_t;
endpackage : cpu_pkg