138 lines
4.3 KiB
Systemverilog
138 lines
4.3 KiB
Systemverilog
`include "cpu_pkg.svh"
|
|
|
|
import cpu_pkg::*;
|
|
|
|
module cpu (
|
|
input logic clk_i,
|
|
input logic nreset_i,
|
|
|
|
output logic [15:0] address_o,
|
|
input logic [ 7:0] rdata_i,
|
|
output logic we_o,
|
|
output logic [ 7:0] wdata_o
|
|
);
|
|
|
|
state_t state;
|
|
|
|
logic alu_op_valid;
|
|
alu_op_t alu_op;
|
|
op_src_t op_src;
|
|
op_dest_t op_dest;
|
|
adr_src_t adr_src;
|
|
logic reg_write_alu;
|
|
|
|
logic [ 7:0] alu_operand;
|
|
|
|
logic [ 7:0] rega;
|
|
logic [ 7:0] regf;
|
|
|
|
logic [15:0] pc;
|
|
logic [15:0] sp;
|
|
logic [15:0] hl;
|
|
|
|
logic instr_valid;
|
|
logic instr_undef;
|
|
|
|
logic [ 7:0] operand8;
|
|
logic [15:0] operand16;
|
|
|
|
reg8_t reg8_wselect;
|
|
logic reg8_we;
|
|
logic [ 7:0] reg8_wdata;
|
|
reg16_t reg16_wselect;
|
|
logic reg16_we;
|
|
logic [15:0] reg16_wdata;
|
|
reg8_t reg8_rselect;
|
|
reg16_t reg16_rselect;
|
|
reg16_t reg16_rselect2;
|
|
logic [ 7:0] reg8_rdata;
|
|
logic [15:0] reg16_rdata;
|
|
logic [15:0] reg16_rdata2;
|
|
alu16_op_t alu16_op;
|
|
logic [ 7:0] alu_out8;
|
|
logic [15:0] alu_out16;
|
|
|
|
control control_inst (
|
|
.clk_i (clk_i),
|
|
.nreset_i (nreset_i),
|
|
.rdata_i (rdata_i),
|
|
.state_o (state),
|
|
.f_i (regf),
|
|
.pc_o (pc),
|
|
.sp_o (sp),
|
|
.alu_op_valid_o(alu_op_valid),
|
|
.alu_op_o (alu_op),
|
|
.reg_write_alu_o(reg_write_alu),
|
|
.op_src_o (op_src),
|
|
.op_dest_o (op_dest),
|
|
.instr_valid_o (instr_valid),
|
|
.instr_undef_o (instr_undef),
|
|
.operand8_o (operand8),
|
|
.operand16_o (operand16),
|
|
.reg8_dest_o (reg8_wselect),
|
|
.reg8_src_o (reg8_rselect),
|
|
.alu16_op_o (alu16_op),
|
|
.reg16_src_o (reg16_rselect),
|
|
.reg16_dest_o (reg16_wselect),
|
|
.memory_we_o (we_o),
|
|
.adr_src_o (adr_src)
|
|
);
|
|
|
|
alu alu_inst (
|
|
.clk_i (clk_i),
|
|
.nreset_i (nreset_i),
|
|
.alu_op_valid_i(alu_op_valid),
|
|
.alu_op_i (alu_op),
|
|
.operand_i (alu_operand),
|
|
.inx8_i (operand8[5:3]), // Used for bit/set/res
|
|
.a_o (rega),
|
|
.f_o (regf),
|
|
.alu16_op_i (alu16_op),
|
|
.inx16_i (reg16_rdata2),
|
|
.iny16_i (reg16_rdata),
|
|
.out8_o (alu_out8),
|
|
.out16_o (alu_out16)
|
|
);
|
|
|
|
registers registers_inst (
|
|
.clk_i (clk_i),
|
|
.nreset_i(nreset_i),
|
|
|
|
.reg8_wselect_i (reg8_wselect),
|
|
.reg8_we_i (reg8_we),
|
|
.reg8_wdata_i (reg8_wdata),
|
|
.reg16_wselect_i(reg16_wselect),
|
|
.reg16_we_i (reg16_we),
|
|
.reg16_wdata_i (reg16_wdata),
|
|
.reg8_rselect_i (reg8_rselect),
|
|
.reg8_rdata_o (reg8_rdata),
|
|
.reg16_rselect_i(reg16_rselect),
|
|
.reg16_rdata_o (reg16_rdata),
|
|
.reg16_rselect2_i(reg16_rselect2),
|
|
.reg16_rdata2_o (reg16_rdata2),
|
|
.hl_o (hl)
|
|
);
|
|
|
|
assign alu_operand = (op_src == OP_SRC_A) ? rega :
|
|
(op_src == OP_SRC_OPERAND8) ? operand8 :
|
|
(op_src == OP_SRC_REG8) ? reg8_rdata :
|
|
(op_src == OP_SRC_MEMORY) ? rdata_i :
|
|
'X;
|
|
|
|
assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8);
|
|
assign reg8_wdata = reg_write_alu ? alu_out8 : alu_operand;
|
|
assign reg16_we = instr_valid & (op_dest == OP_DEST_REG16);
|
|
assign reg16_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16;
|
|
assign reg16_rselect2 = reg16_wselect;
|
|
|
|
assign address_o = (adr_src == ADR_SRC_HL) ? hl :
|
|
(adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} :
|
|
(adr_src == ADR_SRC_REG16) ? reg16_rdata :
|
|
(adr_src == ADR_SRC_OPERAND8) ? {8'hFF, operand8} :
|
|
(adr_src == ADR_SRC_OPERAND16) ? operand16 :
|
|
pc;
|
|
assign wdata_o = (op_dest == OP_DEST_MEMORY) ? alu_operand :
|
|
rega; // ldi/ldd hl, a use the normal control paths for HL
|
|
|
|
endmodule : cpu
|