svgb/rtl/cpu/decode.sv

157 lines
6.5 KiB
Systemverilog

`include "cpu_pkg.svh"
import cpu_pkg::*;
module decode (
input logic [7:0] instr0_i,
input logic [7:0] instr1_i,
input logic [7:0] instr2_i,
input state_t state_i,
output logic need_instr1_o,
output logic need_instr2_o,
output logic undef_o,
output logic sp_we_o,
output sp_src_t sp_src_o,
output logic alu_op_valid_o,
output alu_op_t alu_op_o,
output logic reg_write_alu_o,
output op_src_t op_src_o,
output op_dest_t op_dest_o,
output reg8_t reg8_dest_o,
output reg8_t reg8_src_o,
output alu16_op_t alu16_op_o,
output reg16_t reg16_dest_o,
output reg16_t reg16_src_o,
output cc_t cc_o,
output pc_src_t pc_src_o,
output adr_src_t adr_src_o,
output logic memory_we_o
);
logic [1:0] dec_x;
logic [2:0] dec_y;
logic [2:0] dec_z;
logic [1:0] dec_p;
logic dec_q;
logic is_cb;
logic is_ld_r_r;
logic is_ld_a_nn;
logic is_ld_r_nn;
logic is_ldh_c_a;
logic is_ld_rrrr_a;
logic is_ld_nnnn_a;
logic is_ld_rr_nnnn;
logic is_ld_sp_nnnn;
logic is_ldd_hl_a;
logic is_alu_a_r;
logic is_bit_n_r;
logic is_inc_a;
logic is_inc_r;
logic is_jr_cc_n;
reg8_t reg8_dest;
reg8_t reg8_src;
assign dec_x = instr0_i[7:6];
assign dec_y = instr0_i[5:3];
assign dec_z = instr0_i[2:0];
assign dec_p = instr0_i[5:4];
assign dec_q = instr0_i[3];
assign is_cb = (instr0_i == 8'hCB);
assign is_ld_r_r = (dec_x == 2'h1) & ((dec_z != 3'h6) | (dec_y != 3'h6));
assign is_ld_a_nn = is_ld_r_nn & (reg8_dest == REG8_A);
assign is_ld_r_nn = (dec_x == 2'h0) & (dec_z == 3'h6);
assign is_ld_rr_nnnn = (dec_x == 2'h0) & (dec_z == 3'h1) & ~dec_q & (dec_p != 2'h3);
assign is_ld_sp_nnnn = (dec_x == 2'h0) & (dec_z == 3'h1) & ~dec_q & (dec_p == 2'h3);
assign is_ldd_hl_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h3);
assign is_ld_rrrr_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p != 2'h3);
assign is_ld_nnnn_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h2);
assign is_ldh_c_a = instr0_i == 8'hE2;
assign is_alu_a_r = (dec_x == 3'h2);
assign is_bit_n_r = (is_cb & instr1_i[7:6] == 2'h1);
assign is_inc_a = is_inc_r & (reg8_dest == REG8_A);
assign is_inc_r = (dec_x == 2'h0) & (dec_z == 3'h4);
assign is_jr_cc_n = (dec_x == 2'h0) & (dec_z == 2'h0) & dec_y[2];
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
is_ldh_c_a ? REG8_C :
is_inc_r ? reg8_t'(dec_y) :
reg8_t'(dec_z);
assign reg8_dest = reg8_t'(dec_y);
assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb | is_jr_cc_n | is_ld_r_nn;
assign need_instr2_o = is_ld_sp_nnnn | is_ld_rr_nnnn;
assign undef_o = ~(is_ld_r_r | is_ld_sp_nnnn | is_ld_rr_nnnn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r | is_jr_cc_n | is_ld_r_nn | is_ldh_c_a | is_inc_r | is_ld_rrrr_a);
assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC);
assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_nn | is_inc_r;
assign alu_op_o = is_bit_n_r ? ALU_OP_BIT :
is_ld_a_nn ? ALU_OP_NOP :
is_inc_a ? ALU_OP_INC :
is_inc_r ? ALU_OP_INCR :
alu_op_t'({1'b0, dec_y});
assign reg_write_alu_o = is_inc_r;
assign op_dest_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY :
(is_ld_r_nn & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY :
(is_ld_r_r & reg8_dest == REG8_A) ? OP_DEST_A :
is_ld_r_r ? OP_DEST_REG8 :
is_ld_a_nn ? OP_DEST_A :
is_ld_r_nn ? OP_DEST_REG8 :
is_ldh_c_a ? OP_DEST_MEMORY :
is_ld_rr_nnnn ? OP_DEST_REG16 :
is_ldd_hl_a ? OP_DEST_REG16 :
is_inc_a ? OP_DEST_A :
is_inc_r ? OP_DEST_REG8 :
op_dest_t'('X);
assign op_src_o = (is_ld_r_r & reg8_src == REG8_A) ? OP_SRC_A :
(is_alu_a_r & reg8_src == REG8_A) ? OP_SRC_A :
(is_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 :
(is_ld_r_r & reg8_src == REG8_PHL) ? OP_SRC_MEMORY :
is_inc_r ? OP_SRC_REG8 :
is_ld_r_nn ? OP_SRC_OPERAND8 :
is_ldh_c_a ? OP_SRC_A :
is_ld_rr_nnnn ? OP_SRC_OPERAND16 :
is_ldd_hl_a ? OP_SRC_REG16 :
is_bit_n_r ? OP_SRC_REG8 :
op_src_t'('X);
assign reg8_dest_o = reg8_dest;
assign reg8_src_o = reg8_src;
assign reg16_src_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
assign reg16_dest_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 :
PC_SRC_SEQ;
assign adr_src_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? ADR_SRC_HL :
(is_ld_r_r & reg8_src == REG8_PHL) ? ADR_SRC_HL :
is_ldd_hl_a ? ADR_SRC_HL :
(is_ld_r_nn & reg8_dest == REG8_PHL) ? ADR_SRC_HL :
is_ldh_c_a ? ADR_SRC_REG8 :
is_ld_nnnn_a ? ADR_SRC_OPERAND16 :
is_ld_rrrr_a ? ADR_SRC_REG16:
ADR_SRC_PC;
assign cc_o = cc_t'(dec_y[1:0]);
assign memory_we_o = is_ldd_hl_a | is_ldh_c_a | is_ld_rrrr_a | (is_ld_r_nn & reg8_dest == REG8_PHL) | (is_ld_r_r & reg8_dest == REG8_PHL);
endmodule : decode