mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-05-01 14:16:34 +00:00
add Commen Units
This commit is contained in:
63
common/CPU/z180/alu_log.v
Normal file
63
common/CPU/z180/alu_log.v
Normal file
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** alu logic module Rev 0.0 07/17/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module alu_log (logic_c, logic_hc, logic_out, alua_in, alub_in, aluop_reg, carry_bit);
|
||||
|
||||
input carry_bit; /* cpu carry flag */
|
||||
input [15:0] alua_in; /* alu a input */
|
||||
input [15:0] alub_in; /* alu b input */
|
||||
input [`AOP_IDX:0] aluop_reg; /* alu operation control */
|
||||
output logic_c; /* alu logic carry result */
|
||||
output logic_hc; /* alu logic half-carry result */
|
||||
output [15:0] logic_out; /* alu logic result */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
reg logic_c; /* logic carry output */
|
||||
reg logic_hc; /* logic half-carry output */
|
||||
reg [15:0] logic_out; /* logic output */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu logic function */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (aluop_reg or carry_bit) begin
|
||||
casex (aluop_reg)
|
||||
`AOP_CCF: logic_c = !carry_bit;
|
||||
`AOP_SCF: logic_c = 1'b1;
|
||||
default: logic_c = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or carry_bit) begin
|
||||
casex (aluop_reg)
|
||||
`AOP_BAND: logic_hc = 1'b1;
|
||||
`AOP_CCF: logic_hc = carry_bit;
|
||||
default: logic_hc = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or alua_in or alub_in) begin
|
||||
casex (aluop_reg)
|
||||
`AOP_BAND: logic_out = {8'h00, alua_in[7:0] & alub_in[7:0]};
|
||||
`AOP_BOR: logic_out = {8'h00, alua_in[7:0] | alub_in[7:0]};
|
||||
`AOP_BXOR: logic_out = {8'h00, alua_in[7:0] ^ alub_in[7:0]};
|
||||
`AOP_RLD1: logic_out = {8'h00, alub_in[3:0], alua_in[3:0]};
|
||||
`AOP_RLD2: logic_out = {8'h00, alua_in[7:4], alub_in[7:4]};
|
||||
`AOP_RRD1: logic_out = {8'h00, alua_in[3:0], alub_in[7:4]};
|
||||
`AOP_RRD2: logic_out = {8'h00, alua_in[7:4], alub_in[3:0]};
|
||||
`AOP_APAS: logic_out = alua_in;
|
||||
`AOP_PASS: logic_out = alub_in;
|
||||
default: logic_out = 16'h0000;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
135
common/CPU/z180/alu_math.v
Normal file
135
common/CPU/z180/alu_math.v
Normal file
@@ -0,0 +1,135 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** alu math module Rev 0.0 07/29/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module alu_math (adder_c, adder_hc, adder_out, adder_ov, alua_in, alub_in, aluop_reg,
|
||||
carry_bit, carry_daa, daa_op, word_op);
|
||||
|
||||
input carry_bit; /* carry flag */
|
||||
input carry_daa; /* carry for daa */
|
||||
input daa_op; /* daa operation */
|
||||
input word_op; /* word operation */
|
||||
input [15:0] alua_in; /* alu a input */
|
||||
input [15:0] alub_in; /* alu b input */
|
||||
input [`AOP_IDX:0] aluop_reg; /* alu operation control subset */
|
||||
output adder_c; /* alu math carry result */
|
||||
output adder_hc; /* alu math half-carry result */
|
||||
output adder_ov; /* alu math overflow result */
|
||||
output [15:0] adder_out; /* alu math result */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire adder_c; /* alu math carry out */
|
||||
wire adder_hc; /* alu math half-carry out */
|
||||
wire [15:8] bsign_ext; /* alu b sign extend */
|
||||
wire [15:0] adder_out; /* alu math out */
|
||||
|
||||
reg alu_cin; /* alu math carry in */
|
||||
reg adder_ov; /* alu math overflow out */
|
||||
reg [4:0] alu0_out; /* alu math nibble 0 */
|
||||
reg [4:0] alu1_out; /* alu math nibble 1 */
|
||||
reg [4:0] alu2_out; /* alu math nibble 2 */
|
||||
reg [4:0] alu3_out; /* alu math nibble 3 */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu math carry input, sign extend */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (aluop_reg or carry_bit) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_ADC,
|
||||
`AOP_BADC,
|
||||
`AOP_SBC,
|
||||
`AOP_BSBC: alu_cin = carry_bit;
|
||||
default: alu_cin = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign bsign_ext = {alub_in[7], alub_in[7], alub_in[7], alub_in[7],
|
||||
alub_in[7], alub_in[7], alub_in[7], alub_in[7]};
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu math function unit */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (aluop_reg or alua_in or alub_in or alu_cin) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_SUB,
|
||||
`AOP_BSUB,
|
||||
`AOP_SBC,
|
||||
`AOP_BSBC: alu0_out = alua_in[3:0] - alub_in[3:0] - alu_cin;
|
||||
default: alu0_out = alua_in[3:0] + alub_in[3:0] + alu_cin;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or alua_in or alub_in or alu0_out) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_SUB,
|
||||
`AOP_BSUB,
|
||||
`AOP_SBC,
|
||||
`AOP_BSBC: alu1_out = alua_in[7:4] - alub_in[7:4] - alu0_out[4];
|
||||
default: alu1_out = alua_in[7:4] + alub_in[7:4] + alu0_out[4];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or alua_in or alub_in or alu1_out or bsign_ext) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_ADS: alu2_out = alua_in[11:8] + bsign_ext[11:8] + alu1_out[4];
|
||||
`AOP_SUB,
|
||||
`AOP_BSUB,
|
||||
`AOP_SBC,
|
||||
`AOP_BSBC: alu2_out = alua_in[11:8] - alub_in[11:8] - alu1_out[4];
|
||||
default: alu2_out = alua_in[11:8] + alub_in[11:8] + alu1_out[4];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or alua_in or alub_in or alu2_out or bsign_ext) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_ADS: alu3_out = alua_in[15:12] + bsign_ext[15:12] + alu2_out[4];
|
||||
`AOP_SUB,
|
||||
`AOP_BSUB,
|
||||
`AOP_SBC,
|
||||
`AOP_BSBC: alu3_out = alua_in[15:12] - alub_in[15:12] - alu2_out[4];
|
||||
default: alu3_out = alua_in[15:12] + alub_in[15:12] + alu2_out[4];
|
||||
endcase
|
||||
end
|
||||
|
||||
assign adder_out = {alu3_out[3:0], alu2_out[3:0], alu1_out[3:0], alu0_out[3:0]};
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu math flag generation */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign adder_c = (word_op) ? alu3_out[4] :
|
||||
(daa_op) ? carry_daa : alu1_out[4];
|
||||
assign adder_hc = (word_op) ? alu2_out[4] : alu0_out[4];
|
||||
|
||||
always @ (aluop_reg or alua_in or alub_in or alu3_out or alu1_out or bsign_ext) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_ADC,
|
||||
`AOP_ADD: adder_ov = (!alu3_out[3] && alua_in[15] && alub_in[15]) ||
|
||||
( alu3_out[3] && !alua_in[15] && !alub_in[15]);
|
||||
`AOP_BADC,
|
||||
`AOP_BADD,
|
||||
`AOP_BDEC: adder_ov = (!alu1_out[3] && alua_in[7] && alub_in[7]) ||
|
||||
( alu1_out[3] && !alua_in[7] && !alub_in[7]);
|
||||
`AOP_SBC,
|
||||
`AOP_SUB: adder_ov = (!alu3_out[3] && alua_in[15] && !alub_in[15]) ||
|
||||
( alu3_out[3] && !alua_in[15] && alub_in[15]);
|
||||
`AOP_BSBC,
|
||||
`AOP_BSUB: adder_ov = (!alu1_out[3] && alua_in[7] && !alub_in[7]) ||
|
||||
( alu1_out[3] && !alua_in[7] && alub_in[7]);
|
||||
default: adder_ov = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
66
common/CPU/z180/alu_shft.v
Normal file
66
common/CPU/z180/alu_shft.v
Normal file
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** alu shifter module Rev 0.0 06/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module alu_shft (shft_c, shft_out, alub_in, aluop_reg, carry_bit);
|
||||
|
||||
input carry_bit; /* carry flag input */
|
||||
input [7:0] alub_in; /* alu b input */
|
||||
input [`AOP_IDX:0] aluop_reg; /* alu operation control subset */
|
||||
output shft_c; /* alu shifter carry output */
|
||||
output [7:0] shft_out; /* alu shifter output */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
reg shft_c; /* shifter carry output */
|
||||
reg [7:0] shft_out; /* shifter output */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu shifter function */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (aluop_reg or alub_in) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_RL,
|
||||
`AOP_RLA: shft_c = alub_in[7];
|
||||
`AOP_RLC,
|
||||
`AOP_RLCA: shft_c = alub_in[7];
|
||||
`AOP_RR,
|
||||
`AOP_RRA: shft_c = alub_in[0];
|
||||
`AOP_RRC,
|
||||
`AOP_RRCA: shft_c = alub_in[0];
|
||||
`AOP_SLL,
|
||||
`AOP_SLA: shft_c = alub_in[7];
|
||||
`AOP_SRA: shft_c = alub_in[0];
|
||||
`AOP_SRL: shft_c = alub_in[0];
|
||||
default: shft_c = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_reg or alub_in or carry_bit) begin
|
||||
casex (aluop_reg) //synopsys parallel_case
|
||||
`AOP_RL,
|
||||
`AOP_RLA: shft_out = {alub_in[6:0], carry_bit};
|
||||
`AOP_RLC,
|
||||
`AOP_RLCA: shft_out = {alub_in[6:0], alub_in[7]};
|
||||
`AOP_RR,
|
||||
`AOP_RRA: shft_out = {carry_bit, alub_in[7:1]};
|
||||
`AOP_RRC,
|
||||
`AOP_RRCA: shft_out = {alub_in[0], alub_in[7:1]};
|
||||
`AOP_SLA: shft_out = {alub_in[6:0], 1'b0};
|
||||
`AOP_SLL: shft_out = {alub_in[6:0], 1'b1};
|
||||
`AOP_SRA: shft_out = {alub_in[7], alub_in[7:1]};
|
||||
`AOP_SRL: shft_out = {1'b0, alub_in[7:1]};
|
||||
default: shft_out = 8'h00;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
105
common/CPU/z180/aluamux.v
Normal file
105
common/CPU/z180/aluamux.v
Normal file
@@ -0,0 +1,105 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** alu a input multiplexer module Rev 0.0 06/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module aluamux (adda_in, alua_in, alua_reg, aa_reg_out, bit_mask, daa_out, hl_reg_out,
|
||||
ii_reg, int_addr, ix_reg, iy_reg, pc_reg, rr_reg, rst_addr, tmp_reg);
|
||||
|
||||
input [7:0] aa_reg_out; /* a register output */
|
||||
input [7:0] bit_mask; /* bit mask for bit operations */
|
||||
input [7:0] daa_out; /* daa constant */
|
||||
input [7:0] ii_reg; /* i register output */
|
||||
input [7:0] rr_reg; /* r register output */
|
||||
input [7:0] rst_addr; /* restart address */
|
||||
input [15:0] hl_reg_out; /* hl register output */
|
||||
input [15:0] int_addr; /* interrupt address */
|
||||
input [15:0] ix_reg; /* ix register output */
|
||||
input [15:0] iy_reg; /* iy register output */
|
||||
input [15:0] pc_reg; /* pc register output */
|
||||
input [15:0] tmp_reg; /* tmp register output */
|
||||
input [`ALUA_IDX:0] alua_reg; /* pipelined alu input a mux control */
|
||||
output [15:0] adda_in; /* address alu a input bus */
|
||||
output [15:0] alua_in; /* alu a input bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
reg [15:0] alua_in;
|
||||
reg [15:0] alua_in_0, alua_in_1, alua_in_2, alua_in_3, alua_in_4, alua_in_5;
|
||||
reg [15:0] alua_in_6, alua_in_7, alua_in_8, alua_in_9, alua_in_10, alua_in_11;
|
||||
reg [15:0] alua_in_12, alua_in_13, alua_in_14;
|
||||
|
||||
wire [15:0] adda_in;
|
||||
wire [15:0] adda_in_0, adda_in_1, adda_in_2, adda_in_4, adda_in_5, adda_in_12;
|
||||
wire [15:0] adda_in_14;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu input a select */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (alua_reg or aa_reg_out or bit_mask or daa_out or ii_reg or int_addr or
|
||||
hl_reg_out or ix_reg or iy_reg or pc_reg or rr_reg or rst_addr) begin
|
||||
alua_in_0 = 16'h0;
|
||||
alua_in_1 = 16'h0;
|
||||
alua_in_2 = 16'h0;
|
||||
alua_in_3 = 16'h0;
|
||||
alua_in_4 = 16'h0;
|
||||
alua_in_5 = 16'h0;
|
||||
alua_in_6 = 16'h0;
|
||||
alua_in_7 = 16'h0;
|
||||
alua_in_8 = 16'h0;
|
||||
alua_in_9 = 16'h0;
|
||||
alua_in_10 = 16'h0;
|
||||
alua_in_11 = 16'h0;
|
||||
alua_in_12 = 16'h0;
|
||||
alua_in_13 = 16'h0;
|
||||
alua_in_14 = 16'h0;
|
||||
if (alua_reg[`AA_ONE]) alua_in_0 = 16'h0001;
|
||||
if (alua_reg[`AA_M1]) alua_in_1 = 16'hffff;
|
||||
if (alua_reg[`AA_M2]) alua_in_2 = 16'hfffe;
|
||||
if (alua_reg[`AA_HL]) alua_in_3 = hl_reg_out;
|
||||
if (alua_reg[`AA_IX]) alua_in_4 = ix_reg;
|
||||
if (alua_reg[`AA_IY]) alua_in_5 = iy_reg;
|
||||
if (alua_reg[`AA_PC]) alua_in_6 = pc_reg;
|
||||
if (alua_reg[`AA_AA]) alua_in_7 = {8'h00, aa_reg_out};
|
||||
if (alua_reg[`AA_BIT]) alua_in_8 = {8'h00, bit_mask};
|
||||
if (alua_reg[`AA_DAA]) alua_in_9 = {8'h00, daa_out};
|
||||
if (alua_reg[`AA_II]) alua_in_10 = {8'h00, ii_reg};
|
||||
if (alua_reg[`AA_RR]) alua_in_11 = {8'h00, rr_reg};
|
||||
if (alua_reg[`AA_INT]) alua_in_12 = int_addr;
|
||||
if (alua_reg[`AA_TMP]) alua_in_13 = tmp_reg;
|
||||
if (alua_reg[`AA_RST]) alua_in_14 = {8'h00, rst_addr};
|
||||
end
|
||||
|
||||
always @ (alua_in_0 or alua_in_1 or alua_in_2 or alua_in_3 or alua_in_4 or
|
||||
alua_in_5 or alua_in_6 or alua_in_7 or alua_in_8 or alua_in_9 or
|
||||
alua_in_10 or alua_in_11 or alua_in_12 or alua_in_13 or alua_in_14) begin
|
||||
alua_in = alua_in_0 | alua_in_1 | alua_in_2 | alua_in_3 | alua_in_4 |
|
||||
alua_in_5 | alua_in_6 | alua_in_7 | alua_in_8 | alua_in_9 |
|
||||
alua_in_10 | alua_in_11 | alua_in_12 | alua_in_13 | alua_in_14;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* address alu input a select */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign adda_in_0 = (alua_reg[`AA_ONE]) ? 16'h0001 : 16'h0000;
|
||||
assign adda_in_1 = (alua_reg[`AA_M1]) ? 16'hffff : 16'h0000;
|
||||
assign adda_in_2 = (alua_reg[`AA_M2]) ? 16'hfffe : 16'h0000;
|
||||
assign adda_in_4 = (alua_reg[`AA_IX]) ? ix_reg : 16'h0000;
|
||||
assign adda_in_5 = (alua_reg[`AA_IY]) ? iy_reg : 16'h0000;
|
||||
assign adda_in_12 = (alua_reg[`AA_INT]) ? int_addr : 16'h0000;
|
||||
assign adda_in_14 = (alua_reg[`AA_RST]) ? {8'h00, rst_addr} : 16'h0000;
|
||||
|
||||
assign adda_in = adda_in_0 | adda_in_1 | adda_in_2 | adda_in_4 | adda_in_5 |
|
||||
adda_in_12 | adda_in_14;
|
||||
|
||||
endmodule
|
||||
99
common/CPU/z180/alubmux.v
Normal file
99
common/CPU/z180/alubmux.v
Normal file
@@ -0,0 +1,99 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** alu b input multiplexer module Rev 0.0 07/24/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module alubmux (addb_in, alub_in, alub_reg, af_reg_out, bc_reg_out, de_reg_out, din0_reg,
|
||||
din1_reg, hl_reg_out, ix_reg, iy_reg, pc_reg, sp_reg, tmp_reg);
|
||||
|
||||
input [7:0] din0_reg; /* data input 0 register */
|
||||
input [7:0] din1_reg; /* data input 1 register */
|
||||
input [15:0] af_reg_out; /* af register output */
|
||||
input [15:0] bc_reg_out; /* bc register output */
|
||||
input [15:0] de_reg_out; /* de register output */
|
||||
input [15:0] hl_reg_out; /* hl register output */
|
||||
input [15:0] ix_reg; /* ix register output */
|
||||
input [15:0] iy_reg; /* iy register output */
|
||||
input [15:0] pc_reg; /* pc register output */
|
||||
input [15:0] sp_reg; /* sp register output */
|
||||
input [15:0] tmp_reg; /* temporary register output */
|
||||
input [`ALUB_IDX:0] alub_reg; /* pipelined alu input b mux control */
|
||||
output [15:0] addb_in; /* address alu b input bus */
|
||||
output [15:0] alub_in; /* alu b input bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire [15:0] alub_in;
|
||||
reg [15:0] alub_mux;
|
||||
reg [15:0] alub_mux_1, alub_mux_2, alub_mux_3, alub_mux_4, alub_mux_5;
|
||||
reg [15:0] alub_mux_6, alub_mux_7, alub_mux_8, alub_mux_9, alub_mux_10, alub_mux_11;
|
||||
|
||||
wire [15:0] addb_in;
|
||||
wire [15:0] addb_mux_2, addb_mux_3, addb_mux_4, addb_mux_5, addb_mux_6, addb_mux_7;
|
||||
wire [15:0] addb_mux_8, addb_mux_9, addb_mux_10, addb_mux_12;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu input b select */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (alub_reg or af_reg_out or bc_reg_out or de_reg_out or hl_reg_out or ix_reg or
|
||||
iy_reg or sp_reg or din1_reg or din0_reg or tmp_reg or pc_reg) begin
|
||||
alub_mux_1 = 32'h0;
|
||||
alub_mux_2 = 32'h0;
|
||||
alub_mux_3 = 32'h0;
|
||||
alub_mux_4 = 32'h0;
|
||||
alub_mux_5 = 32'h0;
|
||||
alub_mux_6 = 32'h0;
|
||||
alub_mux_7 = 32'h0;
|
||||
alub_mux_8 = 32'h0;
|
||||
alub_mux_9 = 32'h0;
|
||||
alub_mux_10 = 32'h0;
|
||||
alub_mux_11 = 32'h0;
|
||||
if (alub_reg[`AB_AF]) alub_mux_1 = af_reg_out;
|
||||
if (alub_reg[`AB_BC]) alub_mux_2 = bc_reg_out;
|
||||
if (alub_reg[`AB_DE]) alub_mux_3 = de_reg_out;
|
||||
if (alub_reg[`AB_HL]) alub_mux_4 = hl_reg_out;
|
||||
if (alub_reg[`AB_IX]) alub_mux_5 = ix_reg;
|
||||
if (alub_reg[`AB_IY]) alub_mux_6 = iy_reg;
|
||||
if (alub_reg[`AB_SP]) alub_mux_7 = sp_reg;
|
||||
if (alub_reg[`AB_DIN]) alub_mux_8 = {din1_reg, din0_reg};
|
||||
if (alub_reg[`AB_IO]) alub_mux_9 = {af_reg_out[15:8], din0_reg};
|
||||
if (alub_reg[`AB_TMP]) alub_mux_10 = tmp_reg;
|
||||
if (alub_reg[`AB_PC]) alub_mux_11 = pc_reg;
|
||||
end
|
||||
|
||||
always @ (alub_mux_1 or alub_mux_2 or alub_mux_3 or alub_mux_4 or alub_mux_5 or
|
||||
alub_mux_6 or alub_mux_7 or alub_mux_8 or alub_mux_9 or alub_mux_10 or
|
||||
alub_mux_11) begin
|
||||
alub_mux = alub_mux_1 | alub_mux_2 | alub_mux_3 | alub_mux_4 | alub_mux_5 |
|
||||
alub_mux_6 | alub_mux_7 | alub_mux_8 | alub_mux_9 | alub_mux_10 | alub_mux_11;
|
||||
end
|
||||
|
||||
assign alub_in = (alub_reg[`AB_SHR]) ? {alub_mux[15:8], alub_mux[15:8]} : alub_mux;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* address alu input b select */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign addb_mux_2 = (alub_reg[`AB_BC]) ? bc_reg_out : 16'h0;
|
||||
assign addb_mux_3 = (alub_reg[`AB_DE]) ? de_reg_out : 16'h0;
|
||||
assign addb_mux_4 = (alub_reg[`AB_HL]) ? hl_reg_out : 16'h0;
|
||||
assign addb_mux_5 = (alub_reg[`AB_IX]) ? ix_reg : 16'h0;
|
||||
assign addb_mux_6 = (alub_reg[`AB_IY]) ? iy_reg : 16'h0;
|
||||
assign addb_mux_7 = (alub_reg[`AB_SP]) ? sp_reg : 16'h0;
|
||||
assign addb_mux_8 = (alub_reg[`AB_DIN]) ? {din1_reg, din0_reg} : 16'h0;
|
||||
assign addb_mux_9 = (alub_reg[`AB_IO]) ? {af_reg_out[15:8], din0_reg} : 16'h0;
|
||||
assign addb_mux_10 = (alub_reg[`AB_TMP]) ? tmp_reg : 16'h0;
|
||||
assign addb_mux_12 = (alub_reg[`AB_ADR]) ? pc_reg : 16'h0;
|
||||
|
||||
assign addb_in = addb_mux_2 | addb_mux_3 | addb_mux_4 | addb_mux_5 | addb_mux_6 |
|
||||
addb_mux_7 | addb_mux_8 |addb_mux_9 | addb_mux_10 | addb_mux_12;
|
||||
|
||||
endmodule
|
||||
92
common/CPU/z180/aluout.v
Normal file
92
common/CPU/z180/aluout.v
Normal file
@@ -0,0 +1,92 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** alu function unit combiner module Rev 0.0 06/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module aluout (cry_nxt, data_bus, hcar_nxt, one_nxt, par_nxt, sign_nxt, zero_nxt, adder_c,
|
||||
adder_hc, adder_out, hi_byte, logic_c, logic_hc, logic_out, shft_c, shft_out,
|
||||
mult_out,
|
||||
unit_sel, word_op);
|
||||
|
||||
input adder_c; /* math carry result */
|
||||
input adder_hc; /* math half-carry result */
|
||||
input hi_byte; /* shift left byte control */
|
||||
input logic_c; /* logic carry result */
|
||||
input logic_hc; /* logic half-carry result */
|
||||
input shft_c; /* shift carry result */
|
||||
input word_op; /* word operation */
|
||||
input [1:0] unit_sel; /* alu function unit select */
|
||||
input [7:0] shft_out; /* shift unit result */
|
||||
input [15:0] adder_out; /* math unit result */
|
||||
input [15:0] logic_out; /* logic unit result */
|
||||
input [15:0] mult_out; /* multiplier unit result */
|
||||
output cry_nxt; /* carry flag next */
|
||||
output hcar_nxt; /* half-carry flag next */
|
||||
output one_nxt; /* one flag next */
|
||||
output par_nxt; /* parity flag next */
|
||||
output sign_nxt; /* sign flag next */
|
||||
output zero_nxt; /* zero flag next */
|
||||
output [15:0] data_bus; /* datapath data bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire one_nxt, par_nxt, sign_nxt, zero_nxt;
|
||||
wire [15:0] data_bus;
|
||||
|
||||
reg cry_nxt, hcar_nxt;
|
||||
reg [15:0] alu_result;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu function unit combination */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (unit_sel or adder_out or logic_out or shft_out or mult_out) begin
|
||||
casex (unit_sel)
|
||||
2'b01: alu_result = adder_out;
|
||||
2'b10: alu_result = {8'h00, shft_out};
|
||||
2'b11: alu_result = mult_out;
|
||||
default: alu_result = logic_out;
|
||||
endcase
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu flag outputs */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (unit_sel or adder_c or logic_c or shft_c) begin
|
||||
casex (unit_sel)
|
||||
2'b01: cry_nxt = adder_c;
|
||||
2'b1x: cry_nxt = shft_c;
|
||||
default: cry_nxt = logic_c;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (unit_sel or adder_hc or logic_hc) begin
|
||||
casex (unit_sel)
|
||||
2'b01: hcar_nxt = adder_hc;
|
||||
2'b1x: hcar_nxt = 1'b0;
|
||||
default: hcar_nxt = logic_hc;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign one_nxt = ~|alu_result[7:1] && alu_result[0];
|
||||
assign par_nxt = ~^alu_result[7:0];
|
||||
assign sign_nxt = (word_op) ? alu_result[15] : alu_result[7];
|
||||
assign zero_nxt = (word_op) ? ~|alu_result[15:0] : ~|alu_result[7:0];
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu output left shift */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign data_bus = (hi_byte) ? {alu_result[7:0], alu_result[7:0]} : alu_result[15:0];
|
||||
|
||||
endmodule
|
||||
5227
common/CPU/z180/control.v
Normal file
5227
common/CPU/z180/control.v
Normal file
File diff suppressed because it is too large
Load Diff
691
common/CPU/z180/datapath.v
Normal file
691
common/CPU/z180/datapath.v
Normal file
@@ -0,0 +1,691 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** data path module Rev 0.0 05/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module datapath (addr_reg_in, carry_bit, dmar_reg, dout_io_reg, dout_mem_reg, inst_reg,
|
||||
intr_reg, page_reg, par_bit, sign_bit, tflg_reg, vector_int, xhlt_reg,
|
||||
zero_bit, add_sel, alua_sel, alub_sel, aluop_sel, clearb, clkc, cflg_en,
|
||||
data_in, di_ctl, dma_req, do_ctl, ex_af_pls, ex_bank_pls, ex_dehl_inst,
|
||||
hflg_ctl, ief_ctl, imd_ctl, int_req, ivec_rd, ld_ctrl, ld_inst, ld_page,
|
||||
nflg_ctl, nmi_req, page_sel, pc_sel, pflg_ctl, resetb, sflg_en, tflg_ctl,
|
||||
wait_st, wr_addr, zflg_en, rreg_en);
|
||||
|
||||
input cflg_en; /* carry flag control */
|
||||
input clearb; /* master (testing) reset */
|
||||
input clkc; /* main cpu clock */
|
||||
input dma_req; /* dma request */
|
||||
input ex_af_pls; /* exchange af,af' */
|
||||
input ex_bank_pls; /* exchange register bank */
|
||||
input ex_dehl_inst; /* exchange de,hl */
|
||||
input int_req; /* interrupt request */
|
||||
input ivec_rd; /* interrupt vector enable */
|
||||
input ld_ctrl; /* load control register */
|
||||
input ld_inst; /* load instruction register */
|
||||
input ld_page; /* load page register */
|
||||
input nmi_req; /* nmi request */
|
||||
input resetb; /* internal (user) reset */
|
||||
input rreg_en; /* update R register */
|
||||
input sflg_en; /* sign flag control */
|
||||
input wait_st; /* wait state identifier */
|
||||
input zflg_en; /* zero flag control */
|
||||
input [3:0] page_sel; /* instruction decode "page" control */
|
||||
input [7:0] data_in; /* read data bus */
|
||||
input [`ADCTL_IDX:0] add_sel; /* address output mux control */
|
||||
input [`ALUA_IDX:0] alua_sel; /* alu input a mux control */
|
||||
input [`ALUB_IDX:0] alub_sel; /* alu input b mux control */
|
||||
input [`ALUOP_IDX:0] aluop_sel; /* alu operation control */
|
||||
input [`DI_IDX:0] di_ctl; /* data input control */
|
||||
input [`DO_IDX:0] do_ctl; /* data output control */
|
||||
input [`HFLG_IDX:0] hflg_ctl; /* half-carry flag control */
|
||||
input [`IEF_IDX:0] ief_ctl; /* interrupt enable control */
|
||||
input [`IMD_IDX:0] imd_ctl; /* interrupt mode control */
|
||||
input [`NFLG_IDX:0] nflg_ctl; /* negate flag control */
|
||||
input [`PCCTL_IDX:0] pc_sel; /* program counter source control */
|
||||
input [`PFLG_IDX:0] pflg_ctl; /* parity/overflow flag control */
|
||||
input [`TFLG_IDX:0] tflg_ctl; /* temp flag control */
|
||||
input [`WREG_IDX:0] wr_addr; /* register write address bus */
|
||||
output carry_bit; /* carry flag */
|
||||
output dmar_reg; /* latched dma request */
|
||||
output intr_reg; /* latched interrupt request */
|
||||
output par_bit; /* parity flag */
|
||||
output sign_bit; /* sign flag */
|
||||
output tflg_reg; /* temporary flag */
|
||||
output vector_int; /* int vector enable */
|
||||
output xhlt_reg; /* halt exit */
|
||||
output zero_bit; /* zero flag */
|
||||
output [3:0] page_reg; /* instruction decode "page" */
|
||||
output [7:0] inst_reg; /* instruction register */
|
||||
output [7:0] dout_io_reg; /* i/o write data bus */
|
||||
output [7:0] dout_mem_reg; /* memory write data bus */
|
||||
output [15:0] addr_reg_in; /* processor address bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire adder_c; /* math carry */
|
||||
wire adder_hc; /* math half-carry */
|
||||
wire adder_ov; /* math overflow result */
|
||||
wire alu_carry; /* final carry */
|
||||
wire alu_hcar; /* final half-carry */
|
||||
wire alu_neg; /* final negate */
|
||||
wire alu_one; /* final one */
|
||||
wire alu_sign; /* final sign */
|
||||
wire alu_zero; /* final zero */
|
||||
wire bit7, bit6, bit5, bit4; /* bit decode */
|
||||
wire bit3, bit2, bit1, bit0;
|
||||
wire carry_bit; /* carry flag */
|
||||
wire carry_daa; /* daa carry */
|
||||
wire cry_nxt; /* combined carry */
|
||||
wire daa_l1, daa_l2, daa_l3, daa_l4; /* decimal adjust */
|
||||
wire daa_l5, daa_h1, daa_h2, daa_h3;
|
||||
wire daa_h4, daa_h5, daa_h6, daa_h7;
|
||||
wire daa1, daa2, daa3, daa4, daa5;
|
||||
wire daa6, daa7;
|
||||
wire hcar_nxt; /* combined half-carry */
|
||||
wire hi_byte; /* replicate data byte */
|
||||
wire ld_m_aa, ld_m_ff, ld_m_bb, ld_m_cc; /* register loads */
|
||||
wire ld_m_dd, ld_m_ee, ld_m_hh, ld_m_ll;
|
||||
wire ld_a_aa, ld_a_ff, ld_a_bb, ld_a_cc;
|
||||
wire ld_a_dd, ld_a_ee, ld_a_hh, ld_a_ll;
|
||||
wire ld_sp;
|
||||
wire ld_ixh, ld_ixl, ld_iyh, ld_iyl;
|
||||
wire ld_ii, ld_rr, ld_tmp;
|
||||
wire ld_dout_io, ld_dout_mem; /* load data out */
|
||||
wire ld_flag; /* load flags */
|
||||
wire ld_regf; /* load register file */
|
||||
wire ld_tflg; /* load temp flag */
|
||||
wire logic_c; /* logic carry */
|
||||
wire logic_hc; /* logic half-carry */
|
||||
wire one_nxt; /* combined one */
|
||||
wire par_bit; /* parity flag */
|
||||
wire par_nxt; /* combined parity */
|
||||
wire shft_c; /* shift carry */
|
||||
wire sign_bit; /* sign flag */
|
||||
wire sign_nxt; /* combined sign */
|
||||
wire vector_int; /* int vector enable */
|
||||
wire zero_bit; /* zero flag */
|
||||
wire zero_nxt; /* combined zero */
|
||||
wire [7:0] bit_mask; /* mask for bit inst */
|
||||
wire [7:0] daa_out; /* daa result */
|
||||
wire [7:0] ff_reg_in; /* register input */
|
||||
wire [7:0] aa_reg_out, ff_reg_out; /* register outputs */
|
||||
wire [7:0] new_flags; /* new flag byte */
|
||||
wire [7:0] rst_addr; /* restart address */
|
||||
wire [7:0] shft_out; /* shift result */
|
||||
wire [15:8] bsign_ext; /* address alu b sign extend */
|
||||
wire [15:0] adda_in, addb_in; /* address alu inputs */
|
||||
wire [15:0] adder_out; /* math result */
|
||||
wire [15:0] addr_alu8, addr_alu, addr_hl, addr_pc, addr_sp; /* address mux terms */
|
||||
wire [15:0] addr_reg_in; /* address register input */
|
||||
wire [15:0] alua_in, alub_in; /* alu inputs */
|
||||
wire [15:0] data_bus; /* alu output */
|
||||
wire [15:0] de_reg_in; /* register inputs */
|
||||
wire [15:0] af_reg_out, bc_reg_out; /* register outputs */
|
||||
wire [15:0] de_reg_out, hl_reg_out;
|
||||
wire [15:0] logic_out; /* logic result */
|
||||
|
||||
reg alt_af_reg, alt_bnk_reg; /* main/alt select */
|
||||
reg alu_ovflo; /* final ov */
|
||||
reg daa_sel, daa_op; /* daa operation */
|
||||
reg decr_sel, decr_op; /* decrement operation */
|
||||
reg dmar_reg; /* latched dma request */
|
||||
reg ex_dehl_reg; /* special exchange */
|
||||
reg ief1_reg; /* int enable flag 1 */
|
||||
reg ief2_reg; /* int enable flag 2 */
|
||||
reg imd1_reg; /* int mode 1 */
|
||||
reg imd2_reg; /* int mode 2 */
|
||||
reg intr_reg; /* latched int req */
|
||||
reg ld_dmar, ld_intr; /* sample int/dma */
|
||||
reg ld_pc; /* load pc */
|
||||
reg nmi_hld; /* nmi edge tracker */
|
||||
reg nmi_reg; /* latched nmi req */
|
||||
reg tflg_nxt, tflg_reg; /* temp flag */
|
||||
reg valid_dma; /* valid dma request */
|
||||
reg valid_int, valid_nmi, valid_xhlt; /* valid int request */
|
||||
reg word_sel, word_op; /* 16-bit operation */
|
||||
reg xhlt_reg; /* halt exit */
|
||||
reg [3:0] page_reg /* synthesis syn_preserve=1 */;
|
||||
reg [7:0] inst_reg; /* instruction register */
|
||||
reg [7:0] m_aa_reg, m_ff_reg, m_bb_reg, m_cc_reg; /* individual registers */
|
||||
reg [7:0] m_dd_reg, m_ee_reg, m_hh_reg, m_ll_reg;
|
||||
reg [7:0] a_aa_reg, a_ff_reg, a_bb_reg, a_cc_reg;
|
||||
reg [7:0] a_dd_reg, a_ee_reg, a_hh_reg, a_ll_reg;
|
||||
reg [7:0] ii_reg, rr_reg;
|
||||
reg [7:0] din0_reg, din1_reg; /* data input registers */
|
||||
reg [7:0] dout_io_reg, dout_mem_reg; /* data output registers */
|
||||
reg [15:0] adda_out; /* address alu out */
|
||||
reg [15:0] int_addr; /* interrupt address */
|
||||
reg [15:0] ix_reg, iy_reg; /* index registers */
|
||||
reg [15:0] pc_reg; /* program counter */
|
||||
reg [15:0] sp_reg; /* stack pointer */
|
||||
reg [15:0] tmp_reg; /* temporary register */
|
||||
reg [`ADCTL_IDX:0] addsel_reg /* synthesis syn_preserve=1 */;
|
||||
reg [`ALUA_IDX:0] alua_reg /* synthesis syn_preserve=1 */;
|
||||
reg [`ALUB_IDX:0] alub_reg /* synthesis syn_preserve=1 */;
|
||||
reg [`ALUOP_IDX:0] aluop_reg /* synthesis syn_preserve=1 */;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* input synchronization */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
nmi_hld <= 1'b0;
|
||||
valid_dma <= 1'b0;
|
||||
valid_int <= 1'b0;
|
||||
valid_nmi <= 1'b0;
|
||||
valid_xhlt <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
nmi_hld <= (nmi_req && !valid_nmi) || (!(ivec_rd && nmi_reg) && nmi_hld);
|
||||
valid_dma <= dma_req;
|
||||
valid_int <= nmi_req || nmi_hld || ((&ief_ctl[1:0] || ief1_reg) && int_req);
|
||||
valid_nmi <= nmi_req || nmi_hld;
|
||||
valid_xhlt <= !dma_req && (nmi_req || nmi_hld || (ief1_reg && int_req));
|
||||
end
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt mode and enables */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
ief1_reg <= 1'b0;
|
||||
ief2_reg <= 1'b0;
|
||||
imd1_reg <= 1'b0;
|
||||
imd2_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (|ief_ctl[2:1]) ief1_reg <= (ief_ctl[1]) ? ief_ctl[0] : (ief_ctl[0] && ief2_reg);
|
||||
if (|ief_ctl[2:1]) ief2_reg <= (ief_ctl[1]) ? ief_ctl[0] :
|
||||
(ief_ctl[0]) ? ief2_reg : (nmi_reg && ief1_reg);
|
||||
if (|imd_ctl) imd1_reg <= imd_ctl[1] && !imd_ctl[0];
|
||||
if (|imd_ctl) imd2_reg <= &imd_ctl;
|
||||
end
|
||||
end
|
||||
|
||||
assign vector_int = imd2_reg && !nmi_reg;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt pending */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (pc_sel or wait_st) begin
|
||||
case (pc_sel)
|
||||
`PC_DMA, /* dma xfer dma sample */
|
||||
`PC_INT: ld_dmar = 1'b1; /* block inst dma sample */
|
||||
`PC_NILD: ld_dmar = !wait_st; /* inst end dma sample */
|
||||
default: ld_dmar = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (pc_sel or wait_st) begin
|
||||
case (pc_sel)
|
||||
`PC_INT: ld_intr = 1'b1; /* block inst int sample */
|
||||
`PC_NILD: ld_intr = !wait_st; /* inst end int sample */
|
||||
default: ld_intr = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
dmar_reg <= 1'b0;
|
||||
intr_reg <= 1'b0;
|
||||
nmi_reg <= 1'b0;
|
||||
xhlt_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (ld_dmar) dmar_reg <= valid_dma;
|
||||
if (ld_intr) intr_reg <= !valid_dma && (valid_nmi || (ief1_reg && valid_int));
|
||||
if (ld_intr) nmi_reg <= !valid_dma && valid_nmi;
|
||||
if (ld_intr) xhlt_reg <= !valid_dma && valid_xhlt;
|
||||
end
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* register control */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (pc_sel or dmar_reg or intr_reg or valid_dma or valid_int or wait_st) begin
|
||||
case (pc_sel)
|
||||
`PC_LD: ld_pc = !wait_st; /* load PC unconditionally */
|
||||
`PC_NILD: ld_pc = !((ief1_reg && valid_int) || valid_nmi || valid_dma) && !wait_st;
|
||||
`PC_NILD2: ld_pc = !(intr_reg || dmar_reg) && !wait_st; /* if no latched int */
|
||||
default: ld_pc = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
alt_af_reg <= 1'b0;
|
||||
alt_bnk_reg <= 1'b0;
|
||||
ex_dehl_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
alt_af_reg <= ex_af_pls ^ alt_af_reg;
|
||||
alt_bnk_reg <= ex_bank_pls ^ alt_bnk_reg;
|
||||
ex_dehl_reg <= ex_dehl_inst && ld_ctrl;
|
||||
end
|
||||
end
|
||||
|
||||
assign ld_flag = (sflg_en || zflg_en || |hflg_ctl || |pflg_ctl || |nflg_ctl ||
|
||||
cflg_en) && !wait_st;
|
||||
assign ld_regf = wr_addr[`WR_REG] && !wait_st;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* cpu register interface */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign ff_reg_in = (ld_flag) ? new_flags : data_bus[7:0];
|
||||
assign de_reg_in = (ex_dehl_reg) ? hl_reg_out : data_bus;
|
||||
|
||||
assign ld_m_aa = ld_regf && wr_addr[`WR_AA] && !alt_af_reg;
|
||||
assign ld_m_ff = ((ld_regf && wr_addr[`WR_FF]) || ld_flag) && !alt_af_reg;
|
||||
assign ld_m_bb = ld_regf && wr_addr[`WR_BB] && !alt_bnk_reg;
|
||||
assign ld_m_cc = ld_regf && wr_addr[`WR_CC] && !alt_bnk_reg;
|
||||
assign ld_m_dd = ld_regf && wr_addr[`WR_DD] && !alt_bnk_reg;
|
||||
assign ld_m_ee = ld_regf && wr_addr[`WR_EE] && !alt_bnk_reg;
|
||||
assign ld_m_hh = ld_regf && wr_addr[`WR_HH] && !alt_bnk_reg;
|
||||
assign ld_m_ll = ld_regf && wr_addr[`WR_LL] && !alt_bnk_reg;
|
||||
assign ld_a_aa = ld_regf && wr_addr[`WR_AA] && alt_af_reg;
|
||||
assign ld_a_ff = ((ld_regf && wr_addr[`WR_FF]) || ld_flag) && alt_af_reg;
|
||||
assign ld_a_bb = ld_regf && wr_addr[`WR_BB] && alt_bnk_reg;
|
||||
assign ld_a_cc = ld_regf && wr_addr[`WR_CC] && alt_bnk_reg;
|
||||
assign ld_a_dd = ld_regf && wr_addr[`WR_DD] && alt_bnk_reg;
|
||||
assign ld_a_ee = ld_regf && wr_addr[`WR_EE] && alt_bnk_reg;
|
||||
assign ld_a_hh = ld_regf && wr_addr[`WR_HH] && alt_bnk_reg;
|
||||
assign ld_a_ll = ld_regf && wr_addr[`WR_LL] && alt_bnk_reg;
|
||||
assign ld_sp = ld_regf && wr_addr[`WR_SP];
|
||||
assign ld_ixh = ld_regf && wr_addr[`WR_IXH];
|
||||
assign ld_ixl = ld_regf && wr_addr[`WR_IXL];
|
||||
assign ld_iyh = ld_regf && wr_addr[`WR_IYH];
|
||||
assign ld_iyl = ld_regf && wr_addr[`WR_IYL];
|
||||
assign ld_ii = ld_regf && wr_addr[`WR_II];
|
||||
assign ld_rr = ld_regf && wr_addr[`WR_RR];
|
||||
assign ld_tmp = ld_regf && wr_addr[`WR_TMP];
|
||||
|
||||
assign af_reg_out = (alt_af_reg) ? {a_aa_reg, a_ff_reg} : {m_aa_reg, m_ff_reg};
|
||||
assign bc_reg_out = (alt_bnk_reg) ? {a_bb_reg, a_cc_reg} : {m_bb_reg, m_cc_reg};
|
||||
assign de_reg_out = (alt_bnk_reg) ? {a_dd_reg, a_ee_reg} : {m_dd_reg, m_ee_reg};
|
||||
assign hl_reg_out = (alt_bnk_reg) ? {a_hh_reg, a_ll_reg} : {m_hh_reg, m_ll_reg};
|
||||
assign aa_reg_out = af_reg_out[15:8];
|
||||
assign ff_reg_out = af_reg_out[7:0];
|
||||
assign carry_bit = af_reg_out[0];
|
||||
assign par_bit = af_reg_out[2];
|
||||
assign sign_bit = af_reg_out[7];
|
||||
assign zero_bit = af_reg_out[6];
|
||||
assign hi_byte = (wr_addr[`WR_AA] && !wr_addr[`WR_FF]) ||
|
||||
(wr_addr[`WR_BB] && !wr_addr[`WR_CC]) ||
|
||||
(wr_addr[`WR_DD] && !wr_addr[`WR_EE]) ||
|
||||
(wr_addr[`WR_HH] && !wr_addr[`WR_LL]) ||
|
||||
(wr_addr[`WR_IXH]&& !wr_addr[`WR_IXL]) ||
|
||||
(wr_addr[`WR_IYH]&& !wr_addr[`WR_IYL]) ||
|
||||
wr_addr[`WR_II] || wr_addr[`WR_RR];
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* cpu registers */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge clkc or negedge clearb) begin
|
||||
if (!clearb) begin
|
||||
m_aa_reg <= 8'h00;
|
||||
m_ff_reg <= 8'h00;
|
||||
m_bb_reg <= 8'h00;
|
||||
m_cc_reg <= 8'h00;
|
||||
m_dd_reg <= 8'h00;
|
||||
m_ee_reg <= 8'h00;
|
||||
m_hh_reg <= 8'h00;
|
||||
m_ll_reg <= 8'h00;
|
||||
a_aa_reg <= 8'h00;
|
||||
a_ff_reg <= 8'h00;
|
||||
a_bb_reg <= 8'h00;
|
||||
a_cc_reg <= 8'h00;
|
||||
a_dd_reg <= 8'h00;
|
||||
a_ee_reg <= 8'h00;
|
||||
a_hh_reg <= 8'h00;
|
||||
a_ll_reg <= 8'h00;
|
||||
ix_reg <= 16'h0000;
|
||||
iy_reg <= 16'h0000;
|
||||
end
|
||||
else begin
|
||||
if (ld_m_aa) m_aa_reg <= data_bus[15:8];
|
||||
if (ld_m_ff) m_ff_reg <= ff_reg_in;
|
||||
if (ld_m_bb) m_bb_reg <= data_bus[15:8];
|
||||
if (ld_m_cc) m_cc_reg <= data_bus[7:0];
|
||||
if (ld_m_dd) m_dd_reg <= de_reg_in[15:8];
|
||||
if (ld_m_ee) m_ee_reg <= de_reg_in[7:0];
|
||||
if (ld_m_hh) m_hh_reg <= data_bus[15:8];
|
||||
if (ld_m_ll) m_ll_reg <= data_bus[7:0];
|
||||
if (ld_a_aa) a_aa_reg <= data_bus[15:8];
|
||||
if (ld_a_ff) a_ff_reg <= ff_reg_in;
|
||||
if (ld_a_bb) a_bb_reg <= data_bus[15:8];
|
||||
if (ld_a_cc) a_cc_reg <= data_bus[7:0];
|
||||
if (ld_a_dd) a_dd_reg <= de_reg_in[15:8];
|
||||
if (ld_a_ee) a_ee_reg <= de_reg_in[7:0];
|
||||
if (ld_a_hh) a_hh_reg <= data_bus[15:8];
|
||||
if (ld_a_ll) a_ll_reg <= data_bus[7:0];
|
||||
if (ld_ixh) ix_reg[15:8] <= data_bus[15:8];
|
||||
if (ld_ixl) ix_reg[7:0] <= data_bus[7:0];
|
||||
if (ld_iyh) iy_reg[15:8] <= data_bus[15:8];
|
||||
if (ld_iyl) iy_reg[7:0] <= data_bus[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
ii_reg <= 8'h00;
|
||||
pc_reg <= 16'h0000;
|
||||
rr_reg <= 8'h00;
|
||||
sp_reg <= 16'h0000;
|
||||
tmp_reg <= 16'h0000;
|
||||
end
|
||||
else begin
|
||||
if (ld_ii) ii_reg <= data_bus[15:8];
|
||||
if (ld_pc) pc_reg <= data_bus;
|
||||
if (ld_rr)
|
||||
rr_reg <= data_bus[15:8];
|
||||
`ifdef RREG_EMU
|
||||
else
|
||||
rr_reg[6:0] <= rr_reg[6:0] + {6'h0, rreg_en && !dmar_reg && !wait_st};
|
||||
`endif
|
||||
if (ld_sp) sp_reg <= data_bus;
|
||||
if (ld_tmp) tmp_reg <= (ivec_rd) ? {ii_reg, data_in} : data_bus;
|
||||
end
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* temporary flag */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign ld_tflg = |tflg_ctl && !wait_st;
|
||||
|
||||
always @ (tflg_ctl or alu_one or alu_zero or ff_reg_out) begin
|
||||
casex (tflg_ctl)
|
||||
`TFLG_1: tflg_nxt = alu_one; /* blk set if done (next xfr) */
|
||||
`TFLG_Z: tflg_nxt = alu_zero; /* blk set if done (this xfr) */
|
||||
`TFLG_B: tflg_nxt = alu_zero || !ff_reg_out[2]; /* blk cp set if done or match */
|
||||
default: tflg_nxt = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) tflg_reg <= 1'b0;
|
||||
else if (ld_tflg) tflg_reg <= tflg_nxt;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* data input and data output registers */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign ld_dout_io = do_ctl[1] && !wait_st;
|
||||
assign ld_dout_mem = do_ctl[2] && !wait_st;
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
din0_reg <= 8'h00;
|
||||
din1_reg <= 8'h00;
|
||||
dout_io_reg <= 8'h00;
|
||||
dout_mem_reg <= 8'h00;
|
||||
end
|
||||
else begin
|
||||
if (di_ctl[0]) din0_reg <= data_in;
|
||||
if (di_ctl[1]) din1_reg <= data_in;
|
||||
if (ld_dout_io) dout_io_reg <= data_bus[7:0];
|
||||
if (ld_dout_mem) dout_mem_reg <= (do_ctl[0]) ? data_bus[15:8] : data_bus[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* instruction and page registers */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) inst_reg <= 8'h00;
|
||||
else if (ld_inst) inst_reg <= data_in;
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) page_reg <= 4'b0000;
|
||||
else if (ld_page && ld_ctrl) page_reg <= page_sel;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu control pipeline registers */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (aluop_sel) begin
|
||||
case (aluop_sel) //synopsys parallel_case
|
||||
`ALUOP_DAA: daa_sel = 1'b1;
|
||||
default: daa_sel = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_sel) begin
|
||||
case (aluop_sel) //synopsys parallel_case
|
||||
`ALUOP_BDEC: decr_sel = 1'b1;
|
||||
default: decr_sel = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (aluop_sel) begin
|
||||
case (aluop_sel) //synopsys parallel_case
|
||||
`ALUOP_ADC,
|
||||
`ALUOP_ADD,
|
||||
`ALUOP_PASS,
|
||||
`ALUOP_SBC,
|
||||
`ALUOP_SUB: word_sel = 1'b1;
|
||||
default: word_sel = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
addsel_reg <= `ADD_RSTVAL;
|
||||
alua_reg <= `ALUA_RSTVAL;
|
||||
alub_reg <= `ALUB_RSTVAL;
|
||||
aluop_reg <= `ALUOP_RSTVAL;
|
||||
daa_op <= 1'b0;
|
||||
decr_op <= 1'b0;
|
||||
word_op <= 1'b0;
|
||||
end
|
||||
else if (ld_ctrl) begin
|
||||
addsel_reg <= add_sel;
|
||||
alua_reg <= alua_sel;
|
||||
alub_reg <= alub_sel;
|
||||
aluop_reg <= aluop_sel;
|
||||
daa_op <= daa_sel;
|
||||
decr_op <= decr_sel;
|
||||
word_op <= word_sel;
|
||||
end
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* bit manipulation constant generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign bit7 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b111);
|
||||
assign bit6 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b110);
|
||||
assign bit5 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b101);
|
||||
assign bit4 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b100);
|
||||
assign bit3 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b011);
|
||||
assign bit2 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b010);
|
||||
assign bit1 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b001);
|
||||
assign bit0 = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b000);
|
||||
assign bit_mask = {bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0};
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* decimal adjust accumulator constant generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign daa_l1 = !ff_reg_out[1] && !ff_reg_out[4] &&
|
||||
(!aa_reg_out[3] || (aa_reg_out[3] && !aa_reg_out[2] && !aa_reg_out[1]));
|
||||
assign daa_l2 = !ff_reg_out[1] && !ff_reg_out[4] &&
|
||||
(aa_reg_out[3] && (aa_reg_out[2] || aa_reg_out[1]));
|
||||
assign daa_l3 = !ff_reg_out[1] && ff_reg_out[4] && (!aa_reg_out[3] && !aa_reg_out[2]);
|
||||
assign daa_l4 = ff_reg_out[1] && !ff_reg_out[4] &&
|
||||
(!aa_reg_out[3] || (aa_reg_out[3] && !aa_reg_out[2] && !aa_reg_out[1]));
|
||||
assign daa_l5 = ff_reg_out[1] && ff_reg_out[4] &&
|
||||
((!aa_reg_out[3] && aa_reg_out[2] && aa_reg_out[1]) || aa_reg_out[3]);
|
||||
assign daa_h1 = !ff_reg_out[0] && (aa_reg_out[7] && (aa_reg_out[6] || aa_reg_out[5]));
|
||||
assign daa_h2 = ff_reg_out[0] &&
|
||||
(!aa_reg_out[7] && !aa_reg_out[6] && (!aa_reg_out[5] || !aa_reg_out[4]));
|
||||
assign daa_h3 = !ff_reg_out[0] &&
|
||||
(aa_reg_out[7] && (aa_reg_out[6] || aa_reg_out[5] || aa_reg_out[4]));
|
||||
assign daa_h4 = ff_reg_out[0] && (!aa_reg_out[7] && !aa_reg_out[6]);
|
||||
assign daa_h5 = ff_reg_out[0] &&
|
||||
((aa_reg_out[6] && aa_reg_out[5] && aa_reg_out[4]) || aa_reg_out[7]);
|
||||
assign daa_h6 = !ff_reg_out[0] &&
|
||||
((!aa_reg_out[6] && !aa_reg_out[5] && !aa_reg_out[4]) || !aa_reg_out[7]);
|
||||
assign daa_h7 = ff_reg_out[0] && ((aa_reg_out[6] && aa_reg_out[5]) || aa_reg_out[7]);
|
||||
|
||||
assign daa1 = daa_l2 || daa_l3 || daa_l5;
|
||||
assign daa2 = daa_l2 || daa_l3;
|
||||
assign daa3 = daa_l5;
|
||||
assign daa4 = daa_l5 && (daa_h6 || daa_h7);
|
||||
assign daa5 = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
|
||||
(daa_l3 && (daa_h1 || daa_h4)) || (daa_l4 && daa_h5) ||
|
||||
(daa_l5 && daa_h6);
|
||||
assign daa6 = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
|
||||
(daa_l3 && (daa_h1 || daa_h4)) || (daa_l5 && daa_h6);
|
||||
assign daa7 = (daa_l4 && daa_h5) || (daa_l5 && (daa_h6 || daa_h7));
|
||||
|
||||
assign daa_out = {daa7, daa6, daa5, daa4, daa3, daa2, daa1, 1'b0};
|
||||
assign carry_daa = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
|
||||
(daa_l3 && (daa_h1 || daa_h4)) || (daa_l4 && daa_h5) ||
|
||||
(daa_l5 && daa_h7);
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt/restart address generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign rst_addr = {2'b00, inst_reg[5:3], 3'b000};
|
||||
|
||||
always @ (nmi_reg or imd2_reg or imd1_reg or din0_reg or din1_reg) begin
|
||||
casex ({nmi_reg, imd2_reg, imd1_reg})
|
||||
3'b001: int_addr = 16'h0038;
|
||||
3'b010: int_addr = {din1_reg, din0_reg};
|
||||
3'b1xx: int_addr = 16'h0066;
|
||||
default: int_addr = 16'h0000;
|
||||
endcase
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* alu input selects */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
aluamux AMUX ( .adda_in(adda_in), .alua_in(alua_in), .alua_reg(alua_reg),
|
||||
.aa_reg_out(aa_reg_out), .bit_mask(bit_mask), .daa_out(daa_out),
|
||||
.hl_reg_out(hl_reg_out), .ii_reg(ii_reg), .int_addr(int_addr),
|
||||
.ix_reg(ix_reg), .iy_reg(iy_reg), .pc_reg(pc_reg), .rr_reg(rr_reg),
|
||||
.rst_addr(rst_addr), .tmp_reg(tmp_reg) );
|
||||
|
||||
alubmux BMUX ( .addb_in(addb_in), .alub_in(alub_in), .alub_reg(alub_reg),
|
||||
.af_reg_out(af_reg_out), .bc_reg_out(bc_reg_out), .de_reg_out(de_reg_out),
|
||||
.din0_reg(din0_reg), .din1_reg(din1_reg), .hl_reg_out(hl_reg_out),
|
||||
.ix_reg(ix_reg), .iy_reg(iy_reg), .pc_reg(pc_reg), .sp_reg(sp_reg),
|
||||
.tmp_reg(tmp_reg) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* function units */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
alu_log ALULOG ( .logic_c(logic_c), .logic_hc(logic_hc), .logic_out(logic_out),
|
||||
.alua_in(alua_in), .alub_in(alub_in), .aluop_reg(aluop_reg[`AOP_IDX:0]),
|
||||
.carry_bit(carry_bit) );
|
||||
|
||||
alu_math ALUMATH ( .adder_c(adder_c), .adder_hc(adder_hc), .adder_out(adder_out),
|
||||
.adder_ov(adder_ov), .alua_in(alua_in), .alub_in(alub_in),
|
||||
.aluop_reg(aluop_reg[`AOP_IDX:0]), .carry_bit(carry_bit),
|
||||
.carry_daa(carry_daa), .daa_op(daa_op), .word_op(word_op) );
|
||||
|
||||
alu_shft ALUSHFT ( .shft_c(shft_c), .shft_out(shft_out), .alub_in(alub_in[7:0]),
|
||||
.aluop_reg(aluop_reg[`AOP_IDX:0]), .carry_bit(carry_bit) );
|
||||
wire [15:0] mult_out = alub_in[15:8] * alub_in[7:0];
|
||||
aluout ALUOUT ( .cry_nxt(cry_nxt), .data_bus(data_bus), .hcar_nxt(hcar_nxt),
|
||||
.one_nxt(one_nxt), .par_nxt(par_nxt), .sign_nxt(sign_nxt),
|
||||
.zero_nxt(zero_nxt), .adder_c(adder_c), .adder_hc(adder_hc),
|
||||
.adder_out(adder_out), .hi_byte(hi_byte), .logic_c(logic_c),
|
||||
.logic_hc(logic_hc), .logic_out(logic_out), .shft_c(shft_c),
|
||||
.shft_out(shft_out), .mult_out(mult_out), .unit_sel(aluop_reg[7:6]), .word_op(word_op) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* flag generation */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign alu_carry = decr_op ^ cry_nxt;
|
||||
assign alu_hcar = (hflg_ctl[1]) ? hflg_ctl[0] : (decr_op ^ hcar_nxt);
|
||||
assign alu_neg = (nflg_ctl[1]) ? nflg_ctl[0] : sign_nxt;
|
||||
assign alu_one = one_nxt;
|
||||
assign alu_sign = sign_nxt;
|
||||
assign alu_zero = zero_nxt;
|
||||
|
||||
always @ (pflg_ctl or adder_ov or ief2_reg or par_nxt or zero_nxt) begin
|
||||
case (pflg_ctl)
|
||||
`PFLG_V: alu_ovflo = adder_ov;
|
||||
`PFLG_1: alu_ovflo = 1'b1;
|
||||
`PFLG_P: alu_ovflo = par_nxt;
|
||||
`PFLG_B: alu_ovflo = !zero_nxt;
|
||||
`PFLG_F: alu_ovflo = ief2_reg;
|
||||
default: alu_ovflo = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign new_flags[7] = (sflg_en) ? alu_sign : ff_reg_out[7];
|
||||
assign new_flags[6] = (zflg_en) ? alu_zero : ff_reg_out[6];
|
||||
assign new_flags[5] = ff_reg_out[5];
|
||||
assign new_flags[4] = (|hflg_ctl) ? alu_hcar : ff_reg_out[4];
|
||||
assign new_flags[3] = ff_reg_out[3];
|
||||
assign new_flags[2] = (|pflg_ctl) ? alu_ovflo : ff_reg_out[2];
|
||||
assign new_flags[1] = (|nflg_ctl) ? alu_neg : ff_reg_out[1];
|
||||
assign new_flags[0] = (cflg_en) ? alu_carry : ff_reg_out[0];
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* address alu */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign bsign_ext = {addb_in[7], addb_in[7], addb_in[7], addb_in[7],
|
||||
addb_in[7], addb_in[7], addb_in[7], addb_in[7]};
|
||||
|
||||
always @ (aluop_reg or adda_in or addb_in or bsign_ext) begin
|
||||
case (aluop_reg)
|
||||
`ALUOP_ADS: adda_out = adda_in + {bsign_ext[15:8], addb_in[7:0]};
|
||||
`ALUOP_BADD,
|
||||
`ALUOP_ADD: adda_out = adda_in + addb_in;
|
||||
`ALUOP_APAS: adda_out = adda_in;
|
||||
default: adda_out = addb_in;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign addr_alu8 = (addsel_reg[`AD_ALU8]) ? {8'h00, adda_out[7:0]} : 16'h0000;
|
||||
assign addr_alu = (addsel_reg[`AD_ALU]) ? adda_out : 16'h0000;
|
||||
assign addr_hl = (addsel_reg[`AD_HL]) ? hl_reg_out : 16'h0000;
|
||||
assign addr_pc = (addsel_reg[`AD_PC]) ? pc_reg : 16'h0000;
|
||||
assign addr_sp = (addsel_reg[`AD_SP]) ? sp_reg : 16'h0000;
|
||||
|
||||
assign addr_reg_in = addr_alu8 | addr_alu | addr_hl | addr_pc | addr_sp;
|
||||
|
||||
endmodule
|
||||
468
common/CPU/z180/defines.v
Normal file
468
common/CPU/z180/defines.v
Normal file
@@ -0,0 +1,468 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** define file to make the code more readable Rev 0.0 06/18/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* page register control - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define MAIN_PG 4'b0000 //no instruction prefix byte(s)
|
||||
`define INTR_PG 4'b0001 //interrupt acknowledge
|
||||
`define CB_PAGE 4'b0010 //CB instruction prefix
|
||||
`define DMA_PG 4'b0011 //dma acknowledge
|
||||
`define DD_PAGE 4'b0100 //DD instruction prefix
|
||||
`define FD_PAGE 4'b0101 //FD instruction prefix
|
||||
`define DDCB_PG 4'b0110 //DD-CB instruction prefix
|
||||
`define FDCB_PG 4'b0111 //FD-CB instruction prefix
|
||||
`define ED_PAGE 4'b1000 //ED instruction prefix
|
||||
`define DEC_MAIN 4'b0x0x //main page or DD page or FD page
|
||||
`define DEC_ED 4'b1xxx //ED page
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* program counter register control: pc_sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define PCCTL_IDX 2
|
||||
`define PC_NUL 3'b000 //No operation on PC
|
||||
`define PC_LD 3'b001 //PC loaded unconditionally
|
||||
`define PC_NILD 3'b011 //PC loaded if no interrupt, sample interrupt
|
||||
`define PC_INT 3'b100 //Sample interrupt/dma only
|
||||
`define PC_DMA 3'b110 //Sample dma only
|
||||
`define PC_NILD2 3'b111 //PC loaded if no latched interrupt
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* address bus select: add_sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define ADCTL_IDX 4
|
||||
`define ADD_RSTVAL 5'b00000 //Pipeline register reset value
|
||||
`define ADD_PC 5'b00001 //Select address register from PC
|
||||
`define ADD_HL 5'b00010 //Select address register from HL
|
||||
`define ADD_SP 5'b00100 //Select address register from SP
|
||||
`define ADD_ALU 5'b01000 //Select address register from ALU
|
||||
`define ADD_ALU8 5'b10000 //Select address register from {8'h0, ALU[7:0]}
|
||||
|
||||
`define AD_PC 0 //Address from PC
|
||||
`define AD_HL 1 //Address from HL
|
||||
`define AD_SP 2 //Address from SP
|
||||
`define AD_ALU 3 //Address from ALU
|
||||
`define AD_ALU8 4 //Address from {8'h0, ALU[7:0]}
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* transaction type select: tran_sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define TTYPE_IDX 5
|
||||
`define TRAN_RSTVAL 6'b000000 //Transaction type reset value
|
||||
`define TRAN_IAK 6'b000001 //Intack transaction
|
||||
`define TRAN_IDL 6'b000010 //Idle transaction
|
||||
`define TRAN_IF 6'b000100 //Instruction fetch transaction
|
||||
`define TRAN_IO 6'b001000 //I/O transaction
|
||||
`define TRAN_MEM 6'b010000 //Memory (data) transaction
|
||||
`define TRAN_STK 6'b100000 //Memory (stack) transaction
|
||||
|
||||
`define TT_IAK 0 //Interrupt acknowledge transaction
|
||||
`define TT_IDL 1 //Idle transaction
|
||||
`define TT_IF 2 //Instruction fetch transaction
|
||||
`define TT_IO 3 //I/O transaction
|
||||
`define TT_MEM 4 //Memory (data) transaction
|
||||
`define TT_STK 5 //Memory (stack) transaction
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* data output control: do_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define DO_IDX 2
|
||||
`define DO_NUL 3'b000 //No load
|
||||
`define DO_IO 3'b010 //Load i/o data from lsb
|
||||
`define DO_LSB 3'b100 //Load mem data from lsb
|
||||
`define DO_MSB 3'b101 //Load mem data from msb
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* data input control: di_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define DI_IDX 1
|
||||
`define DI_NUL 2'b00 //No load
|
||||
`define DI_DI0 2'b01 //Load din0
|
||||
`define DI_DI1 2'b10 //Load din1
|
||||
`define DI_DI10 2'b11 //Load both din0 and din1
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt enable control: ief_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define IEF_IDX 2
|
||||
`define IEF_NUL 3'b000 //No load
|
||||
`define IEF_0 3'b010 //Load zero
|
||||
`define IEF_1 3'b011 //Load one
|
||||
`define IEF_NMI 3'b100 //ief2 <= ief1, ief1 <= 0
|
||||
`define IEF_RTN 3'b101 //ief1 <= ief2
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* int mode control: imd_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define IMD_IDX 1
|
||||
`define IMD_NUL 2'b00 //No load
|
||||
`define IMD_0 2'b01 //Set interrupt mode 0
|
||||
`define IMD_1 2'b10 //Set interrupt mode 1
|
||||
`define IMD_2 2'b11 //Set interrupt mode 2
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* half-carry flag control: hflg_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define HFLG_IDX 1
|
||||
`define HFLG_NUL 2'b00 //No load
|
||||
`define HFLG_H 2'b01 //Load half-carry result
|
||||
`define HFLG_0 2'b10 //Load zero
|
||||
`define HFLG_1 2'b11 //Load one
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* parity/overflow flag control: pflg_ctl */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define PFLG_IDX 2
|
||||
`define PFLG_NUL 3'b000 //No load
|
||||
`define PFLG_V 3'b001 //Load overflow result
|
||||
`define PFLG_0 3'b010 //Load zero
|
||||
`define PFLG_1 3'b011 //Load one
|
||||
`define PFLG_P 3'b100 //Load parity result
|
||||
`define PFLG_B 3'b101 //Load block count zero result
|
||||
`define PFLG_F 3'b111 //Load ief
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* negate flag control: nflg_ctl - DO NOT MODIFY */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define NFLG_IDX 1
|
||||
`define NFLG_NUL 2'b00 //No load
|
||||
`define NFLG_S 2'b01 //Load sign result
|
||||
`define NFLG_0 2'b10 //Load zero
|
||||
`define NFLG_1 2'b11 //Load one
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* temporary flag control: tflg_ctl */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define TFLG_IDX 1
|
||||
`define TFLG_NUL 2'b00 //No load
|
||||
`define TFLG_Z 2'b01 //Load zero result
|
||||
`define TFLG_1 2'b10 //Load one result (blk out)
|
||||
`define TFLG_B 2'b11 //Load blk cp result
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* write register control: wr_sel - unencoded */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define WREG_IDX 16
|
||||
`define WREG_BB 17'b11000000000000000 //Select B to write
|
||||
`define WREG_BC 17'b11100000000000000 //Select BC to write
|
||||
`define WREG_CC 17'b10100000000000000 //Select C to write
|
||||
`define WREG_DD 17'b10010000000000000 //Select D to write
|
||||
`define WREG_DE 17'b10011000000000000 //Select DE to write
|
||||
`define WREG_EE 17'b10001000000000000 //Select E to write
|
||||
`define WREG_HH 17'b10000100000000000 //Select H to write
|
||||
`define WREG_HL 17'b10000110000000000 //Select HL to write
|
||||
`define WREG_LL 17'b10000010000000000 //Select L to write
|
||||
`define WREG_DEHL 17'b10011110000000000 //Select DEHL to write (ex case)
|
||||
`define WREG_AA 17'b10000001000000000 //Select A to write
|
||||
`define WREG_AF 17'b10000001100000000 //Select A and F to write
|
||||
`define WREG_FF 17'b10000000100000000 //Select F to write
|
||||
`define WREG_SP 17'b10000000010000000 //Select SP to write
|
||||
`define WREG_TMP 17'b10000000001000000 //Select TMP register to write
|
||||
`define WREG_IXH 17'b10000000000100000 //Select IXH to write
|
||||
`define WREG_IX 17'b10000000000110000 //Select IX to write
|
||||
`define WREG_IXL 17'b10000000000010000 //Select IXL to write
|
||||
`define WREG_IYH 17'b10000000000001000 //Select IYH to write
|
||||
`define WREG_IY 17'b10000000000001100 //Select IY to write
|
||||
`define WREG_IYL 17'b10000000000000100 //Select IYL to write
|
||||
`define WREG_II 17'b10000000000000010 //Select I register to write
|
||||
`define WREG_RR 17'b10000000000000001 //Select R register to write
|
||||
`define WREG_NUL 17'b00000000000000000 //No register write
|
||||
|
||||
`define WR_REG 16 //register write
|
||||
`define WR_BB 15 //BB register index
|
||||
`define WR_CC 14 //CC register index
|
||||
`define WR_DD 13 //DD register index
|
||||
`define WR_EE 12 //EE register index
|
||||
`define WR_HH 11 //HH register index
|
||||
`define WR_LL 10 //LL register index
|
||||
`define WR_AA 9 //AA register index
|
||||
`define WR_FF 8 //FF register index
|
||||
`define WR_SP 7 //SP register index
|
||||
`define WR_TMP 6 //TMP register index
|
||||
`define WR_IXH 5 //IXH register index
|
||||
`define WR_IXL 4 //IXL register index
|
||||
`define WR_IYH 3 //IYH register index
|
||||
`define WR_IYL 2 //IYL register index
|
||||
`define WR_II 1 //II register index
|
||||
`define WR_RR 0 //RR register index
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* ALU input A control: alua_sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define ALUA_IDX 14
|
||||
`define ALUA_RSTVAL 15'h0000 //Reset value for pipeline controls
|
||||
`define ALUA_ZER 15'h0000 //Select 16'h0000 (default)
|
||||
`define ALUA_ONE 15'h0001 //Select 16'h0001
|
||||
`define ALUA_M1 15'h0002 //Select 16'hFFFF
|
||||
`define ALUA_M2 15'h0004 //Select 16'hFFFE
|
||||
`define ALUA_HL 15'h0008 //Select HL register
|
||||
`define ALUA_IX 15'h0010 //Select IX register
|
||||
`define ALUA_IY 15'h0020 //Select IY register
|
||||
`define ALUA_PC 15'h0040 //Select PC register
|
||||
`define ALUA_AA 15'h0080 //Select A register
|
||||
`define ALUA_BIT 15'h0100 //Select bit select constant
|
||||
`define ALUA_DAA 15'h0200 //Select decimal adjust constant
|
||||
`define ALUA_II 15'h0400 //Select I register
|
||||
`define ALUA_RR 15'h0800 //Select R register
|
||||
`define ALUA_INT 15'h1000 //Select interrupt address
|
||||
`define ALUA_TMP 15'h2000 //Select TMP register
|
||||
`define ALUA_RST 15'h4000 //Select restart address
|
||||
|
||||
`define AA_ONE 0 //alua one
|
||||
`define AA_M1 1 //alua -1
|
||||
`define AA_M2 2 //alua -2
|
||||
`define AA_HL 3 //alua hl
|
||||
`define AA_IX 4 //alua ix
|
||||
`define AA_IY 5 //alua iy
|
||||
`define AA_PC 6 //alua pc
|
||||
`define AA_AA 7 //alua aa
|
||||
`define AA_BIT 8 //alua bit
|
||||
`define AA_DAA 9 //alua daa
|
||||
`define AA_II 10 //alua ii
|
||||
`define AA_RR 11 //alua rr
|
||||
`define AA_INT 12 //alua interrupt
|
||||
`define AA_TMP 13 //alua tmp
|
||||
`define AA_RST 14 //alua restart
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* ALU input B control: alub_sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define ALUB_IDX 12
|
||||
`define ALUB_RSTVAL 13'h1000 //Reset value for pipeline controls
|
||||
`define ALUB_AF 13'h1002 //Select A and F registers
|
||||
`define ALUB_AA 13'h1003 //Select A register
|
||||
`define ALUB_BC 13'h0004 //Select BC register
|
||||
`define ALUB_BB 13'h0005 //Select B register
|
||||
`define ALUB_CC 13'h0004 //Select C register
|
||||
`define ALUB_DE 13'h0008 //Select DE register
|
||||
`define ALUB_DD 13'h0009 //Select D register
|
||||
`define ALUB_EE 13'h0008 //Select E register
|
||||
`define ALUB_HL 13'h0010 //Select HL register
|
||||
`define ALUB_HH 13'h0011 //Select H register
|
||||
`define ALUB_LL 13'h0010 //Select L register
|
||||
`define ALUB_IX 13'h0020 //Select IX register
|
||||
`define ALUB_IXH 13'h0021 //Select IX register high byte
|
||||
`define ALUB_IXL 13'h0020 //Select IX register low byte
|
||||
`define ALUB_IY 13'h0040 //Select IY register
|
||||
`define ALUB_IYH 13'h0041 //Select IY register high byte
|
||||
`define ALUB_IYL 13'h0040 //Select IY register low byte
|
||||
`define ALUB_SP 13'h0080 //Select SP register
|
||||
`define ALUB_SPH 13'h0081 //Select SP register high byte
|
||||
`define ALUB_DIN 13'h0100 //Select data input register
|
||||
`define ALUB_DINH 13'h0101 //Select data input register high byte
|
||||
`define ALUB_IO 13'h0200 //Select i/o address
|
||||
`define ALUB_TMP 13'h0400 //Select TMP register
|
||||
`define ALUB_TMPH 13'h0401 //Select TMP register high byte
|
||||
`define ALUB_PC 13'h1800 //Select PC register
|
||||
`define ALUB_PCH 13'h1801 //Select PC register high byte
|
||||
|
||||
`define AB_SHR 0 //alub shift right
|
||||
`define AB_AF 1 //alub af
|
||||
`define AB_BC 2 //alub bc
|
||||
`define AB_DE 3 //alub de
|
||||
`define AB_HL 4 //alub hl
|
||||
`define AB_IX 5 //alub ix
|
||||
`define AB_IY 6 //alub iy
|
||||
`define AB_SP 7 //alub sp
|
||||
`define AB_DIN 8 //alub din
|
||||
`define AB_IO 9 //alub io
|
||||
`define AB_TMP 10 //alub tmp
|
||||
`define AB_PC 11 //alub pc
|
||||
`define AB_ADR 12 //alub address pc
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* ALU operation control: aluop_sel - 2 MSBs fixed for unit sel */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define ALUOP_IDX 7
|
||||
`define ALUOP_RSTVAL 8'b00000000 //Reset Value for pipeline controls
|
||||
`define ALUOP_ADD 8'b01000000 //ALU math: add
|
||||
`define ALUOP_BADD 8'b01000001 //ALU math: byte add
|
||||
`define ALUOP_BDEC 8'b01000011 //ALU math: byte add (decrement)
|
||||
`define ALUOP_ADS 8'b01000100 //ALU math: add signed byte
|
||||
`define ALUOP_DAA 8'b01000101 //ALU math: byte add (daa)
|
||||
`define ALUOP_ADC 8'b01001000 //ALU math: add with carry
|
||||
`define ALUOP_BADC 8'b01001001 //ALU math: byte add with carry
|
||||
`define ALUOP_SUB 8'b01010000 //ALU math: subtract
|
||||
`define ALUOP_BSUB 8'b01010001 //ALU math: subtract
|
||||
`define ALUOP_SBC 8'b01100000 //ALU math: subtract with carry
|
||||
`define ALUOP_BSBC 8'b01100001 //ALU math: byte subtract with carry
|
||||
|
||||
`define ALUOP_PASS 8'b00000000 //ALU logic: pass b bus
|
||||
`define ALUOP_BAND 8'b00000011 //ALU logic: byte and
|
||||
`define ALUOP_BOR 8'b00000101 //ALU logic: byte or
|
||||
`define ALUOP_BXOR 8'b00001001 //ALU logic: byte or
|
||||
`define ALUOP_CCF 8'b00010000 //ALU logic: complement carry
|
||||
`define ALUOP_SCF 8'b00010010 //ALU logic: set carry
|
||||
`define ALUOP_RLD1 8'b00011000 //ALU logic: rld first step
|
||||
`define ALUOP_RLD2 8'b00011010 //ALU logic: rld second step
|
||||
`define ALUOP_RRD1 8'b00011100 //ALU logic: rrd first step
|
||||
`define ALUOP_RRD2 8'b00011110 //ALU logic: rrd second step
|
||||
`define ALUOP_APAS 8'b00100000 //ALU logic: pass a bus
|
||||
|
||||
`define ALUOP_RL 8'b10000000 //ALU shft: rotate left
|
||||
`define ALUOP_RLA 8'b10000001 //ALU shft: rotate left acc
|
||||
`define ALUOP_RLC 8'b10000010 //ALU shft: rotate left circular
|
||||
`define ALUOP_RLCA 8'b10000011 //ALU shft: rotate left circular acc
|
||||
`define ALUOP_RR 8'b10000100 //ALU shft: rotate right
|
||||
`define ALUOP_RRA 8'b10000101 //ALU shft: rotate right acc
|
||||
`define ALUOP_RRC 8'b10001000 //ALU shft: rotate right circular
|
||||
`define ALUOP_RRCA 8'b10001001 //ALU shft: rotate right circular acc
|
||||
`define ALUOP_SLA 8'b10010000 //ALU shft: shift left arithmetic
|
||||
`define ALUOP_SLL 8'b10011000 //ALU shft: shift left logical (x = (x << 1) | 1)
|
||||
`define ALUOP_SRL 8'b10100000 //ALU shft: shift right logical
|
||||
`define ALUOP_SRA 8'b10101000 //ALU shft: shift right arithmetic
|
||||
|
||||
`define ALUOP_MLT 8'b11000000 //ALU mult: 8 bit multiplication
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* ALU operation control: 6 encoded */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define AOP_IDX 5
|
||||
`define AOP_ADD 6'b000000 //ALU math: add
|
||||
`define AOP_BADD 6'b000001 //ALU math: byte add
|
||||
`define AOP_BDEC 6'b000011 //ALU math: byte add (decrement)
|
||||
`define AOP_ADS 6'b000100 //ALU math: add signed byte
|
||||
`define AOP_DAA 6'b000101 //ALU math: byte add (daa)
|
||||
`define AOP_ADC 6'b001000 //ALU math: add with carry
|
||||
`define AOP_BADC 6'b001001 //ALU math: byte add with carry
|
||||
`define AOP_SUB 6'b010000 //ALU math: subtract
|
||||
`define AOP_BSUB 6'b010001 //ALU math: subtract
|
||||
`define AOP_SBC 6'b100000 //ALU math: subtract with carry
|
||||
`define AOP_BSBC 6'b100001 //ALU math: byte subtract with carry
|
||||
|
||||
`define AOP_PASS 6'b000000 //ALU logic: pass b bus
|
||||
`define AOP_BAND 6'b000011 //ALU logic: byte and
|
||||
`define AOP_BOR 6'b000101 //ALU logic: byte or
|
||||
`define AOP_BXOR 6'b001001 //ALU logic: byte or
|
||||
`define AOP_CCF 6'b010000 //ALU logic: complement carry
|
||||
`define AOP_SCF 6'b010010 //ALU logic: set carry
|
||||
`define AOP_RLD1 6'b011000 //ALU logic: rld first step
|
||||
`define AOP_RLD2 6'b011010 //ALU logic: rld second step
|
||||
`define AOP_RRD1 6'b011100 //ALU logic: rrd first step
|
||||
`define AOP_RRD2 6'b011110 //ALU logic: rrd second step
|
||||
`define AOP_APAS 6'b100000 //ALU logic: pass a bus
|
||||
|
||||
`define AOP_RL 6'b000000 //ALU shft: rotate left
|
||||
`define AOP_RLA 6'b000001 //ALU shft: rotate left acc
|
||||
`define AOP_RLC 6'b000010 //ALU shft: rotate left circular
|
||||
`define AOP_RLCA 6'b000011 //ALU shft: rotate left circular acc
|
||||
`define AOP_RR 6'b000100 //ALU shft: rotate right
|
||||
`define AOP_RRA 6'b000101 //ALU shft: rotate right acc
|
||||
`define AOP_RRC 6'b001000 //ALU shft: rotate right circular
|
||||
`define AOP_RRCA 6'b001001 //ALU shft: rotate right circular acc
|
||||
`define AOP_SLA 6'b010000 //ALU shft: shift left arithmetic
|
||||
`define AOP_SLL 6'b011000 //ALU shft: shift left logical
|
||||
`define AOP_SRL 6'b100000 //ALU shft: shift right logical
|
||||
`define AOP_SRA 6'b101000 //ALU shft: shift right arithmetic
|
||||
|
||||
`define AOP_MLT 6'b000000 //ALU mult: 8 bit multiplication
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* machine state - pseudo-one-hot */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
`define STATE_IDX 31
|
||||
`define sRST 32'b00000000000000000000000000000000 //reset
|
||||
`define sDEC1 32'b00000000000000000000000000000011 //decode 1st opcode
|
||||
`define sIF2B 32'b00000000000000000000000000000101 //fetch 2nd opcode (2)
|
||||
`define sDEC2 32'b00000000000000000000000000001001 //decode 2nd opcode
|
||||
`define sOF1B 32'b00000000000000000000000000010001 //fetch 1st operand (2)
|
||||
`define sOF2A 32'b00000000000000000000000000100001 //fetch 2nd operand (1)
|
||||
`define sOF2B 32'b00000000000000000000000001000001 //fetch 2nd operand (2)
|
||||
`define sIF3A 32'b00000000000000000000000010000001 //fetch 3rd opcode (1)
|
||||
`define sIF3B 32'b00000000000000000000000100000001 //fetch 3rd opcode (2)
|
||||
`define sADR1 32'b00000000000000000000001000000001 //address calculate (1)
|
||||
`define sADR2 32'b00000000000000000000010000000001 //address calculate (2)
|
||||
`define sRD1A 32'b00000000000000000000100000000001 //read 1st operand (1)
|
||||
`define sRD1B 32'b00000000000000000001000000000001 //read 1st operand (2)
|
||||
`define sRD2A 32'b00000000000000000010000000000001 //read 2nd operand (1)
|
||||
`define sRD2B 32'b00000000000000000100000000000001 //read 2nd operand (2)
|
||||
`define sWR1A 32'b00000000000000001000000000000001 //write 1st operand (1)
|
||||
`define sWR1B 32'b00000000000000010000000000000001 //write 1st operand (2)
|
||||
`define sWR2A 32'b00000000000000100000000000000001 //write 2nd operand (1)
|
||||
`define sWR2B 32'b00000000000001000000000000000001 //write 2nd operand (2)
|
||||
`define sBLK1 32'b00000000000010000000000000000001 //block instruction (1)
|
||||
`define sBLK2 32'b00000000000100000000000000000001 //block instruction (2)
|
||||
`define sPCA 32'b00000000001000000000000000000001 //PC adjust
|
||||
`define sPCO 32'b00000000010000000000000000000001 //PC output
|
||||
`define sIF1A 32'b00000000100000000000000000000001 //fetch 1st opcode (1)
|
||||
`define sIF1B 32'b00000001000000000000000000000001 //fetch 1st opcode (2)
|
||||
`define sINTA 32'b00000010000000000000000000000001 //interrupt acknowledge (1)
|
||||
`define sINTB 32'b00000100000000000000000000000001 //interrupt acknowledge (2)
|
||||
`define sHLTA 32'b00001000000000000000000000000001 //halt & sleep (1)
|
||||
`define sHLTB 32'b00010000000000000000000000000001 //halt & sleep (2)
|
||||
`define sDMA1 32'b00100000000000000000000000000001 //dma transfer (1)
|
||||
`define sDMA2 32'b01000000000000000000000000000001 //dma transfer (2)
|
||||
`define sRSTE 32'b10000000000000000000000000000001 //reset exit
|
||||
|
||||
`define RST 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0 //reset
|
||||
`define DEC1 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx11 //decode 1st opcode
|
||||
`define IF2B 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x1 //fetch 2nd opcode (2)
|
||||
`define DEC2 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxx1xx1 //decode 2nd opcode
|
||||
`define OF1B 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxx1xxx1 //fetch 1st operand (2)
|
||||
`define OF2A 32'bxxxxxxxxxxxxxxxxxxxxxxxxxx1xxxx1 //fetch 2nd operand (1)
|
||||
`define OF2B 32'bxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxx1 //fetch 2nd operand (2)
|
||||
`define IF3A 32'bxxxxxxxxxxxxxxxxxxxxxxxx1xxxxxx1 //fetch 3rd opcode (1)
|
||||
`define IF3B 32'bxxxxxxxxxxxxxxxxxxxxxxx1xxxxxxx1 //fetch 3rd opcode (2)
|
||||
`define ADR1 32'bxxxxxxxxxxxxxxxxxxxxxx1xxxxxxxx1 //address calculate (1)
|
||||
`define ADR2 32'bxxxxxxxxxxxxxxxxxxxxx1xxxxxxxxx1 //address calculate (2)
|
||||
`define RD1A 32'bxxxxxxxxxxxxxxxxxxxx1xxxxxxxxxx1 //read 1st operand (1)
|
||||
`define RD1B 32'bxxxxxxxxxxxxxxxxxxx1xxxxxxxxxxx1 //read 1st operand (2)
|
||||
`define RD2A 32'bxxxxxxxxxxxxxxxxxx1xxxxxxxxxxxx1 //read 2nd operand (1)
|
||||
`define RD2B 32'bxxxxxxxxxxxxxxxxx1xxxxxxxxxxxxx1 //read 2nd operand (2)
|
||||
`define WR1A 32'bxxxxxxxxxxxxxxxx1xxxxxxxxxxxxxx1 //write 1st operand (1)
|
||||
`define WR1B 32'bxxxxxxxxxxxxxxx1xxxxxxxxxxxxxxx1 //write 1st operand (2)
|
||||
`define WR2A 32'bxxxxxxxxxxxxxx1xxxxxxxxxxxxxxxx1 //write 2nd operand (1)
|
||||
`define WR2B 32'bxxxxxxxxxxxxx1xxxxxxxxxxxxxxxxx1 //write 2nd operand (2)
|
||||
`define BLK1 32'bxxxxxxxxxxxx1xxxxxxxxxxxxxxxxxx1 //block instruction (1)
|
||||
`define BLK2 32'bxxxxxxxxxxx1xxxxxxxxxxxxxxxxxxx1 //block instruction (2)
|
||||
`define PCA 32'bxxxxxxxxxx1xxxxxxxxxxxxxxxxxxxx1 //PC adjust
|
||||
`define PCO 32'bxxxxxxxxx1xxxxxxxxxxxxxxxxxxxxx1 //PC output
|
||||
`define IF1A 32'bxxxxxxxx1xxxxxxxxxxxxxxxxxxxxxx1 //fetch 1st opcode (1)
|
||||
`define IF1B 32'bxxxxxxx1xxxxxxxxxxxxxxxxxxxxxxx1 //fetch 1st opcode (2)
|
||||
`define INTA 32'bxxxxxx1xxxxxxxxxxxxxxxxxxxxxxxx1 //interrupt acknowledge (1)
|
||||
`define INTB 32'bxxxxx1xxxxxxxxxxxxxxxxxxxxxxxxx1 //interrupt acknowledge (2)
|
||||
`define HLTA 32'bxxxx1xxxxxxxxxxxxxxxxxxxxxxxxxx1 //halt & sleep (1)
|
||||
`define HLTB 32'bxxx1xxxxxxxxxxxxxxxxxxxxxxxxxxx1 //halt & sleep (2)
|
||||
`define DMA1 32'bxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx1 //dma transfer (1)
|
||||
`define DMA2 32'bx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxx1 //dma transfer (2)
|
||||
`define RSTE 32'b1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1 //reset exit
|
||||
153
common/CPU/z180/extint.v
Normal file
153
common/CPU/z180/extint.v
Normal file
@@ -0,0 +1,153 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** external interface module Rev 0.0 07/21/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module extint (data_in, dma_ack, ftch_tran, halt_tran, iack_tran, io_addr_out, io_data_out,
|
||||
io_read, io_strobe, io_tran, ivec_rd, mem_addr_out, mem_data_out, mem_rd,
|
||||
mem_tran, mem_wr, reti_tran, t1, addr_reg_in, clkc, dmar_reg,
|
||||
dout_io_reg, dout_mem_reg, halt_nxt, if_frst, inta_frst, io_data_in,
|
||||
ivec_data_in, ld_dmaa, ld_wait, mem_data_in, output_inh, rd_frst, rd_nxt,
|
||||
resetb, reti_nxt, tran_sel, wr_frst);
|
||||
|
||||
input clkc; /* main cpu clock */
|
||||
input dmar_reg; /* latched dma request */
|
||||
input halt_nxt; /* halt cycle identifier */
|
||||
input if_frst; /* first part of fetch cycle identifier */
|
||||
input inta_frst; /* first part of intack cycle identifier */
|
||||
input ld_dmaa; /* load dma request */
|
||||
input ld_wait; /* load wait request */
|
||||
input output_inh; /* disable cpu outputs */
|
||||
input rd_frst; /* first part of read cycle identifier */
|
||||
input rd_nxt; /* read cycle identifier */
|
||||
input resetb; /* internal reset */
|
||||
input reti_nxt; /* reti cycle identifier */
|
||||
input wr_frst; /* first part of write cycle identifier */
|
||||
input [7:0] dout_io_reg; /* io data output */
|
||||
input [7:0] dout_mem_reg; /* mem data output */
|
||||
input [7:0] io_data_in; /* i/o input data bus */
|
||||
input [7:0] ivec_data_in; /* interrupt vector bus */
|
||||
input [7:0] mem_data_in; /* memory input bus */
|
||||
input [15:0] addr_reg_in; /* processor logical address bus */
|
||||
input [`TTYPE_IDX:0] tran_sel; /* transaction type select */
|
||||
output dma_ack; /* dma acknowledge */
|
||||
output ftch_tran; /* instruction fetch transaction */
|
||||
output halt_tran; /* halt transaction */
|
||||
output iack_tran; /* interrupt acknowledge transaction */
|
||||
output io_read; /* i/o read enable */
|
||||
output io_strobe; /* i/o data strobe */
|
||||
output io_tran; /* i/o transaction */
|
||||
output ivec_rd; /* interrupt vector enable */
|
||||
output mem_rd; /* memory read enable */
|
||||
output mem_tran; /* memory transaction */
|
||||
output mem_wr; /* memory write enable */
|
||||
output reti_tran; /* return from interrupt transaction */
|
||||
output t1; /* first clock of transaction */
|
||||
output [7:0] data_in; /* data input bus */
|
||||
output [7:0] io_data_out; /* i/o output data bus */
|
||||
output [7:0] mem_data_out; /* memory output data bus */
|
||||
output [15:0] io_addr_out; /* i/o address bus */
|
||||
output [15:0] mem_addr_out; /* memory address bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire ld_io_addr; /* update io address */
|
||||
wire ld_mem_addr; /* update memory address */
|
||||
wire [7:0] io_data_out; /* i/o output data bus */
|
||||
wire [7:0] mem_data_out; /* memory output data bus */
|
||||
|
||||
reg dma_ack; /* dma acknowledge */
|
||||
reg ftch_tran; /* inst fetch transaction */
|
||||
reg halt_tran; /* halt transaction */
|
||||
reg iack_tran; /* int ack transaction */
|
||||
reg io_read; /* i/o read enable */
|
||||
reg io_tran; /* i/o transaction */
|
||||
reg io_strobe; /* i/o data strobe */
|
||||
reg ivec_rd; /* interrupt vector enable */
|
||||
reg mem_rd; /* memory read enable */
|
||||
reg mem_tran; /* memory transaction */
|
||||
reg mem_wr; /* memory write enable */
|
||||
reg out_inh_reg; /* latched output inhibit */
|
||||
reg reti_tran; /* reti transaction */
|
||||
reg t1; /* first clock of transaction */
|
||||
reg [7:0] data_in; /* data input bus */
|
||||
reg [15:0] io_addr_out; /* i/o address bus */
|
||||
reg [15:0] mem_addr_out; /* memory address bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* misc signals & buses */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign io_data_out = (out_inh_reg) ? 8'h00 : dout_io_reg;
|
||||
assign mem_data_out = (out_inh_reg) ? 8'h00 : dout_mem_reg;
|
||||
assign ld_io_addr = tran_sel[`TT_IO] || output_inh;
|
||||
assign ld_mem_addr = tran_sel[`TT_IAK] || tran_sel[`TT_IDL] || tran_sel[`TT_IF] ||
|
||||
tran_sel[`TT_MEM] || tran_sel[`TT_STK];
|
||||
|
||||
always @ (iack_tran or io_tran or io_data_in or ivec_data_in or mem_data_in) begin
|
||||
case ({iack_tran, io_tran})
|
||||
2'b01: data_in = io_data_in;
|
||||
2'b10: data_in = ivec_data_in;
|
||||
default: data_in = mem_data_in;
|
||||
endcase
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* timing generation */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
dma_ack <= 1'b0;
|
||||
ftch_tran <= 1'b0;
|
||||
halt_tran <= 1'b0;
|
||||
iack_tran <= 1'b0;
|
||||
io_addr_out <= 16'h0000;
|
||||
io_read <= 1'b0;
|
||||
io_tran <= 1'b0;
|
||||
mem_addr_out <= 16'h0000;
|
||||
mem_tran <= 1'b0;
|
||||
out_inh_reg <= 1'b0;
|
||||
reti_tran <= 1'b0;
|
||||
end
|
||||
else if (|tran_sel) begin
|
||||
dma_ack <= ld_dmaa && dmar_reg;
|
||||
ftch_tran <= tran_sel[`TT_IF];
|
||||
halt_tran <= halt_nxt;
|
||||
iack_tran <= tran_sel[`TT_IAK];
|
||||
if (ld_io_addr) io_addr_out <= (output_inh) ? 16'h0000 : addr_reg_in;
|
||||
io_read <= tran_sel[`TT_IO] && rd_nxt;
|
||||
io_tran <= tran_sel[`TT_IO];
|
||||
if (ld_mem_addr) mem_addr_out <= (output_inh) ? 16'h0000 : addr_reg_in;
|
||||
mem_tran <= (tran_sel[`TT_IDL] || tran_sel[`TT_IF] || tran_sel[`TT_MEM] ||
|
||||
tran_sel[`TT_STK]) && !output_inh;
|
||||
out_inh_reg <= output_inh;
|
||||
reti_tran <= reti_nxt;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) begin
|
||||
io_strobe <= 1'b0;
|
||||
ivec_rd <= 1'b0;
|
||||
mem_rd <= 1'b0;
|
||||
mem_wr <= 1'b0;
|
||||
t1 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
io_strobe <= io_tran && (rd_frst || wr_frst);
|
||||
ivec_rd <= iack_tran && inta_frst;
|
||||
mem_rd <= (if_frst || (mem_tran && rd_frst)) && ld_wait;
|
||||
mem_wr <= mem_tran && wr_frst;
|
||||
t1 <= |tran_sel && !(halt_nxt || dmar_reg);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
19
common/CPU/z180/hierarchy.v
Normal file
19
common/CPU/z180/hierarchy.v
Normal file
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** chip design file include list Rev 0.0 07/17/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
`include "defines.v" /* control signal mnemonics */
|
||||
`include "control.v" /* processor control */
|
||||
`include "datapath.v" /* processor data path */
|
||||
`include "alu_log.v" /* alu logic unit */
|
||||
`include "alu_math.v" /* alu math unit */
|
||||
`include "alu_shft.v" /* alu shifter unit */
|
||||
`include "aluamux.v" /* alu a input multiplexer */
|
||||
`include "alubmux.v" /* alu b input multiplexer */
|
||||
`include "aluout.v" /* alu output multiplexer */
|
||||
`include "extint.v" /* processor external interface */
|
||||
`include "machine.v" /* processor state machine */
|
||||
`include "y80_top.v" /* cpu top level */
|
||||
51
common/CPU/z180/machine.v
Normal file
51
common/CPU/z180/machine.v
Normal file
@@ -0,0 +1,51 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** **/
|
||||
/** state machine module Rev 0.0 07/01/2011 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module machine (ld_ctrl, state_reg, wait_st, clkc, dmar_reg, intr_reg, ld_inta, ld_wait,
|
||||
resetb, state_nxt, wait_req);
|
||||
|
||||
input clkc; /* main cpu clock */
|
||||
input dmar_reg; /* latched dma request */
|
||||
input intr_reg; /* latched interrupt request */
|
||||
input ld_inta; /* load interrupt request */
|
||||
input ld_wait; /* load wait request */
|
||||
input resetb; /* internal reset */
|
||||
input wait_req; /* wait request */
|
||||
input [`STATE_IDX:0] state_nxt; /* next processor state */
|
||||
output ld_ctrl; /* load control register */
|
||||
output wait_st; /* wait state identifier */
|
||||
output [`STATE_IDX:0] state_reg; /* current processor state */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire ld_ctrl; /* advance state */
|
||||
|
||||
reg wait_st; /* wait state - inhibit op */
|
||||
reg [`STATE_IDX:0] state_reg; /* current processor state */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* processor state machine */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
assign ld_ctrl = !ld_wait || !wait_req;
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) wait_st <= 1'b0;
|
||||
else wait_st <= !ld_ctrl;
|
||||
end
|
||||
|
||||
always @ (posedge clkc or negedge resetb) begin
|
||||
if (!resetb) state_reg <= `sRST;
|
||||
else if (ld_ctrl) state_reg <= (ld_inta && dmar_reg) ? `sDMA1 :
|
||||
(ld_inta && intr_reg) ? `sINTA : state_nxt;
|
||||
end
|
||||
|
||||
endmodule
|
||||
573
common/CPU/z180/top_levl.v
Normal file
573
common/CPU/z180/top_levl.v
Normal file
@@ -0,0 +1,573 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** Y80e processor test bench Rev 0.0 06/18/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
`timescale 1ns / 10ps /* set time scale */
|
||||
`include "version.v" /* select version */
|
||||
`include "hierarchy.v" /* include sources */
|
||||
|
||||
module top_levl;
|
||||
|
||||
wire DMA_ACK; /* dma acknowledge */
|
||||
wire HALT_TRAN; /* halt transaction */
|
||||
wire IACK_TRAN; /* int ack transaction */
|
||||
wire IO_READ; /* i/o read/write status */
|
||||
wire IO_STROBE; /* i/o strobe */
|
||||
wire IO_TRAN; /* i/o transaction */
|
||||
wire IVEC_RD; /* int vector read strobe */
|
||||
wire MEM_RD; /* mem read strobe */
|
||||
wire MEM_TRAN; /* mem transaction */
|
||||
wire MEM_WR; /* mem write strobe */
|
||||
wire RETI_TRAN; /* reti transaction */
|
||||
wire T1; /* first clock of transaction */
|
||||
wire [7:0] IO_DATA_OUT; /* i/o data output bus */
|
||||
wire [7:0] MEM_DATA_OUT; /* mem data output bus */
|
||||
wire [15:0] IO_ADDR; /* i/o address bus */
|
||||
wire [15:0] MEM_ADDR; /* mem address bus */
|
||||
|
||||
reg CLEARB; /* master (test) reset */
|
||||
reg CLKC; /* clock */
|
||||
reg DMA_REQ; /* dma request */
|
||||
reg INT_REQ; /* interrupt request */
|
||||
reg NMI_REQ; /* non-maskable interrupt req */
|
||||
reg RESETB; /* internal (user) reset */
|
||||
reg WAIT_REQ; /* wait request */
|
||||
reg [7:0] IO_DATA_IN; /* i/o data input bus */
|
||||
reg [7:0] IVEC_DATA_IN; /* vector input bus */
|
||||
reg [7:0] MEM_DATA_IN; /* mem data input bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* testbench internal variables */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
reg CLR_INT; /* deassert interrupt */
|
||||
reg CLR_NMI; /* deassert nmi */
|
||||
reg DISABLE_BREQ; /* bus req generator control */
|
||||
reg DISABLE_INT; /* interrupt generator control */
|
||||
reg DISABLE_WAIT; /* wait generator control */
|
||||
reg INT_TYPE; /* int type during bus req */
|
||||
reg PAT_DONE; /* pattern done flag */
|
||||
reg TRIG_INT; /* assert interrupt */
|
||||
reg TRIG_NMI; /* assert nmi */
|
||||
reg [3:0] PAT_CNT; /* counter to track patterns */
|
||||
reg [15:0] CMP_ERR_L; /* error counter */
|
||||
|
||||
reg wait_dly; /* wait request state machine */
|
||||
reg [5:0] breq_mach; /* bus request state machine */
|
||||
|
||||
reg TREF0, TREF1, TREF2, TREF3, TREF4; /* timing generator */
|
||||
reg TREF5, TREF6, TREF7, TREF8, TREF9;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* read memory and write data compare memory */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
reg [7:0] rdmem [0:65535];
|
||||
reg [7:0] wrmem [0:65535];
|
||||
|
||||
wire [7:0] wr_data = (MEM_TRAN) ? wrmem[MEM_ADDR] :
|
||||
(IO_TRAN) ? wrmem[IO_ADDR] : 8'hxx;
|
||||
|
||||
wire [7:0] rd_data = rdmem[MEM_ADDR];
|
||||
wire [7:0] iord_data = rdmem[IO_ADDR];
|
||||
|
||||
always @ (posedge TREF6) begin
|
||||
IO_DATA_IN = (IO_TRAN && IO_READ && IO_STROBE && !WAIT_REQ) ? iord_data : 8'hxx;
|
||||
MEM_DATA_IN = (MEM_TRAN && MEM_RD && !WAIT_REQ) ? rd_data : 8'hxx;
|
||||
end
|
||||
|
||||
always @ (posedge TREF6) begin
|
||||
IVEC_DATA_IN = (IACK_TRAN && IVEC_RD && !WAIT_REQ) ? rd_data : 8'hxx;
|
||||
end
|
||||
|
||||
always @ (posedge TREF0) begin
|
||||
IO_DATA_IN = 8'hxx;
|
||||
MEM_DATA_IN = 8'hxx;
|
||||
IVEC_DATA_IN = 8'hxx;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* instantiate the design */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
y80_top Y80 ( .dma_ack(DMA_ACK), .halt_tran(HALT_TRAN), .iack_tran(IACK_TRAN),
|
||||
.io_addr_out(IO_ADDR), .io_data_out(IO_DATA_OUT), .io_read(IO_READ),
|
||||
.io_strobe(IO_STROBE), .io_tran(IO_TRAN), .ivec_rd(IVEC_RD),
|
||||
.mem_addr_out(MEM_ADDR), .mem_data_out(MEM_DATA_OUT), .mem_rd(MEM_RD),
|
||||
.mem_tran(MEM_TRAN), .mem_wr(MEM_WR), .reti_tran(RETI_TRAN), .t1(T1),
|
||||
.clearb(CLEARB), .clkc(CLKC), .dma_req(DMA_REQ), .int_req(INT_REQ),
|
||||
.io_data_in(IO_DATA_IN), .ivec_data_in(IVEC_DATA_IN),
|
||||
.mem_data_in(MEM_DATA_IN), .nmi_req(NMI_REQ), .resetb(RESETB),
|
||||
.wait_req(WAIT_REQ) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* timing generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
initial begin
|
||||
TREF0 = 1;
|
||||
CLKC = 1;
|
||||
end
|
||||
|
||||
always begin
|
||||
#10 TREF0 <= 1'b0;
|
||||
TREF1 <= 1'b1;
|
||||
#10 TREF1 <= 1'b0;
|
||||
TREF2 <= 1'b1;
|
||||
#10 TREF2 <= 1'b0;
|
||||
TREF3 <= 1'b1;
|
||||
#10 TREF3 <= 1'b0;
|
||||
TREF4 <= 1'b1;
|
||||
#10 TREF4 <= 1'b0;
|
||||
TREF5 <= 1'b1;
|
||||
#10 TREF5 <= 1'b0;
|
||||
TREF6 <= 1'b1;
|
||||
#10 TREF6 <= 1'b0;
|
||||
TREF7 <= 1'b1;
|
||||
#10 TREF7 <= 1'b0;
|
||||
TREF8 <= 1'b1;
|
||||
#10 TREF8 <= 1'b0;
|
||||
TREF9 <= 1'b1;
|
||||
#10 TREF9 <= 1'b0;
|
||||
TREF0 <= 1'b1;
|
||||
end
|
||||
|
||||
always @ (posedge TREF3) CLKC = 0;
|
||||
always @ (posedge TREF8) CLKC = 1;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* initialize input signals */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
initial begin
|
||||
CLEARB = 1;
|
||||
DMA_REQ = 0;
|
||||
INT_REQ = 0;
|
||||
NMI_REQ = 0;
|
||||
RESETB = 1;
|
||||
WAIT_REQ = 0;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* initialize testbench variables */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
initial begin
|
||||
breq_mach = 6'b000000;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
CLR_INT = 0;
|
||||
CLR_NMI = 0;
|
||||
DISABLE_BREQ = 1;
|
||||
DISABLE_INT = 1;
|
||||
DISABLE_WAIT = 1;
|
||||
INT_TYPE = 0;
|
||||
PAT_DONE = 0;
|
||||
TRIG_INT = 0;
|
||||
TRIG_NMI = 0;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* reset and clear task */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
task resettask;
|
||||
begin
|
||||
wait(TREF6);
|
||||
RESETB = 0;
|
||||
wait(TREF0);
|
||||
wait(TREF6);
|
||||
wait(TREF0);
|
||||
wait(TREF6);
|
||||
RESETB = 1;
|
||||
CLR_INT = 1;
|
||||
CLR_NMI = 1;
|
||||
wait(TREF0);
|
||||
PAT_DONE = 0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task cleartask;
|
||||
begin
|
||||
wait(TREF6);
|
||||
CLEARB = 0;
|
||||
RESETB = 0;
|
||||
wait(TREF0);
|
||||
wait(TREF6);
|
||||
wait(TREF0);
|
||||
wait(TREF6);
|
||||
CLEARB = 1;
|
||||
RESETB = 1;
|
||||
CLR_INT = 1;
|
||||
CLR_NMI = 1;
|
||||
wait(TREF0);
|
||||
PAT_DONE = 0;
|
||||
end
|
||||
endtask
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* error log */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge TREF4) begin
|
||||
if (MEM_WR) CMP_ERR_L = CMP_ERR_L + (MEM_DATA_OUT != wr_data);
|
||||
if (!IO_READ && IO_STROBE) CMP_ERR_L = CMP_ERR_L + (IO_DATA_OUT != wr_data);
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* end-of-pattern detect */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge TREF4) begin
|
||||
PAT_DONE = (MEM_ADDR[15:0] == 16'h00c3);
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt/nmi request generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge TREF4) begin
|
||||
TRIG_INT = !((MEM_ADDR[15:13] == 3'b110) && (MEM_ADDR[8:0] == 9'h0ff)) ||
|
||||
DISABLE_INT || |breq_mach;
|
||||
TRIG_NMI = !((MEM_ADDR[15:13] == 3'b110) && (MEM_ADDR[8:0] == 9'h1ff)) ||
|
||||
DISABLE_INT || |breq_mach;
|
||||
CLR_INT = (MEM_ADDR[15:13] == 3'b111);
|
||||
CLR_NMI = (MEM_ADDR[15:13] == 3'b111);
|
||||
if (T1) INT_TYPE = MEM_ADDR[8];
|
||||
end
|
||||
|
||||
always @ (negedge TRIG_NMI) begin
|
||||
NMI_REQ = 1;
|
||||
end
|
||||
|
||||
always @ (posedge CLR_NMI) begin
|
||||
NMI_REQ = 0;
|
||||
end
|
||||
|
||||
always @ (negedge TRIG_INT) begin
|
||||
INT_REQ = 1;
|
||||
end
|
||||
|
||||
always @ (posedge CLR_INT) begin
|
||||
wait(TREF0);
|
||||
wait(TREF4);
|
||||
wait(TREF0);
|
||||
wait(TREF4);
|
||||
INT_REQ = 0;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interrupt request generator (during Halt) */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
integer j;
|
||||
|
||||
always @ (posedge HALT_TRAN) begin
|
||||
for (j=0; j < 10; j=j+1) begin
|
||||
wait (TREF6);
|
||||
wait (TREF0);
|
||||
end
|
||||
wait (TREF6);
|
||||
INT_REQ = HALT_TRAN && !INT_TYPE;
|
||||
NMI_REQ = HALT_TRAN && INT_TYPE;
|
||||
wait (TREF0);
|
||||
for (j=0; j < 12; j=j+1) begin
|
||||
wait (TREF6);
|
||||
wait (TREF0);
|
||||
end
|
||||
INT_REQ = 0;
|
||||
NMI_REQ = 0;
|
||||
wait (TREF6);
|
||||
wait (TREF0);
|
||||
wait (TREF6);
|
||||
NMI_REQ = HALT_TRAN && INT_TYPE;
|
||||
wait (TREF0);
|
||||
wait (TREF6);
|
||||
wait (TREF0);
|
||||
NMI_REQ = 0;
|
||||
end
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* wait request generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge CLKC) begin
|
||||
wait_dly <= T1;
|
||||
end
|
||||
|
||||
always @ (posedge TREF6) WAIT_REQ = !DISABLE_WAIT && (T1 || wait_dly);
|
||||
always @ (posedge TREF9) WAIT_REQ = 1'b0;
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* bus request generator */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
always @ (posedge CLKC) begin
|
||||
breq_mach <= (DISABLE_BREQ) ? 6'b000000 :
|
||||
(T1) ? 6'b000001 : {breq_mach[4:0], wait_dly};
|
||||
end
|
||||
|
||||
always @ (posedge TREF6) DMA_REQ = !DISABLE_BREQ &&
|
||||
(T1 || |breq_mach[2:0] || (HALT_TRAN && |breq_mach));
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* run the test patterns */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
initial begin
|
||||
$readmemh("setup_hl.vm", rdmem);
|
||||
cleartask;
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 0; /* interrupt generator on */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h1;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("int_ops.vm", rdmem);
|
||||
$readmemh("int_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 1; /* interrupt generator off */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h2;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("alu_ops.vm", rdmem);
|
||||
$readmemh("alu_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h3;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("dat_mov.vm", rdmem);
|
||||
$readmemh("dat_movd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h4;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("bit_ops.vm", rdmem);
|
||||
$readmemh("bit_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h5;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("jmp_ops.vm", rdmem);
|
||||
$readmemh("jmp_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h6;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("io_ops.vm", rdmem);
|
||||
$readmemh("io_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h7;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("180_ops.vm", rdmem);
|
||||
$readmemh("180_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h8;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("ez8_ops.vm", rdmem);
|
||||
$readmemh("ez8_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 0; /* interrupt generator on */
|
||||
DISABLE_WAIT = 0; /* wait generator on */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h1;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("int_ops.vm", rdmem);
|
||||
$readmemh("int_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 1; /* interrupt generator off */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h2;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("alu_ops.vm", rdmem);
|
||||
$readmemh("alu_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h3;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("dat_mov.vm", rdmem);
|
||||
$readmemh("dat_movd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h4;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("bit_ops.vm", rdmem);
|
||||
$readmemh("bit_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h5;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("jmp_ops.vm", rdmem);
|
||||
$readmemh("jmp_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h6;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("io_ops.vm", rdmem);
|
||||
$readmemh("io_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h7;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("180_ops.vm", rdmem);
|
||||
$readmemh("180_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h8;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("ez8_ops.vm", rdmem);
|
||||
$readmemh("ez8_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 0; /* interrupt generator on */
|
||||
DISABLE_BREQ = 0; /* bus req generator on */
|
||||
DISABLE_WAIT = 1; /* wait generator off */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h1;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("int_ops.vm", rdmem);
|
||||
$readmemh("int_opss.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
DISABLE_INT = 1; /* interrupt generator off */
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h2;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("alu_ops.vm", rdmem);
|
||||
$readmemh("alu_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h3;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("dat_mov.vm", rdmem);
|
||||
$readmemh("dat_movd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h4;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("bit_ops.vm", rdmem);
|
||||
$readmemh("bit_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h5;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("jmp_ops.vm", rdmem);
|
||||
$readmemh("jmp_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h6;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("io_ops.vm", rdmem);
|
||||
$readmemh("io_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h7;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("180_ops.vm", rdmem);
|
||||
$readmemh("180_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
resettask;
|
||||
CMP_ERR_L = 16'h0000;
|
||||
PAT_CNT = 5'h8;
|
||||
$readmemh("blank_xx.vm", rdmem);
|
||||
$readmemh("blank_xx.vm", wrmem);
|
||||
$readmemh("ez8_ops.vm", rdmem);
|
||||
$readmemh("ez8_opsd.vm", wrmem);
|
||||
wait (PAT_DONE);
|
||||
|
||||
$stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
62
common/CPU/z180/version.v
Normal file
62
common/CPU/z180/version.v
Normal file
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2010, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** version definition file Rev 0.0 06/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* SELECT ONLY ONE OPTION PER GROUP! default is first option */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* enable/disable refresh register emulation (if enabled then breaks testbench) */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
// `define RREG_EMU /* enable emulation */
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* select CPU or MPU */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
// `define Y90_CPU /* stand-alone cpu only */
|
||||
// `define Y90_MPU /* integrated version */
|
||||
`define Y90_180 /* clone version */
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* select the operation of the H flag for the CCF instruction */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
`define Z80_CCF /* z80 CCF operation */
|
||||
// `define Z180_CCF /* z180 CCF operation */
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* select the implementation of the MLT instruction */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
`define MUL_NORM /* parallel multiplier */
|
||||
// `define MUL_FAST /* serial multiplier */
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* select the value reported in the System Status Block for dreq_bus (Y90 MPU Only) */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
`define DREQ_LOG /* log dreq timeouts */
|
||||
// `define DREQ_ACC /* count dreq timeouts */
|
||||
|
||||
/*******************************************************************************************/
|
||||
/* */
|
||||
/* select the value reported in the System Status Block for wait_req (Y90 MPU Only) */
|
||||
/* */
|
||||
/*******************************************************************************************/
|
||||
`define WAIT_LOG /* log wait timeouts */
|
||||
// `define WAIT_ACC /* count wait timeouts */
|
||||
194
common/CPU/z180/y80_top.v
Normal file
194
common/CPU/z180/y80_top.v
Normal file
@@ -0,0 +1,194 @@
|
||||
/*******************************************************************************************/
|
||||
/** **/
|
||||
/** ORIGINAL COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED **/
|
||||
/** COPYRIGHT (C) 2012, SERGEY BELYASHOV **/
|
||||
/** **/
|
||||
/** processor top level Rev 0.0 06/13/2012 **/
|
||||
/** **/
|
||||
/*******************************************************************************************/
|
||||
module y80_top (dma_ack, halt_tran, iack_tran, io_addr_out, io_data_out, io_read, io_strobe,
|
||||
io_tran, ivec_rd, mem_addr_out, mem_data_out, mem_rd, mem_tran, mem_wr,
|
||||
reti_tran, t1, clearb, clkc, dma_req, int_req, io_data_in, ivec_data_in,
|
||||
mem_data_in, nmi_req, resetb, wait_req);
|
||||
|
||||
input clearb; /* master (test) reset */
|
||||
input clkc; /* main cpu clock */
|
||||
input dma_req; /* dma request */
|
||||
input int_req; /* interrupt request */
|
||||
input nmi_req; /* nmi request */
|
||||
input resetb; /* internal (user) reset */
|
||||
input wait_req; /* wait request */
|
||||
input [7:0] io_data_in; /* i/o input data bus */
|
||||
input [7:0] ivec_data_in; /* interrupt vector bus */
|
||||
input [7:0] mem_data_in; /* memory input bus */
|
||||
output dma_ack; /* dma acknowledge */
|
||||
output halt_tran; /* halt transaction */
|
||||
output iack_tran; /* interrupt acknowledge transaction */
|
||||
output io_read; /* i/o read enable */
|
||||
output io_tran; /* i/o transaction */
|
||||
output io_strobe; /* i/o data strobe */
|
||||
output ivec_rd; /* interrupt vector enable */
|
||||
output mem_rd; /* memory read enable */
|
||||
output mem_tran; /* memory transaction */
|
||||
output mem_wr; /* memory write enable */
|
||||
output reti_tran; /* return from interrupt transaction */
|
||||
output t1; /* first clock of transaction */
|
||||
output [7:0] io_data_out; /* i/o output data bus */
|
||||
output [7:0] mem_data_out; /* memory output data bus */
|
||||
output [15:0] io_addr_out; /* i/o address bus */
|
||||
output [15:0] mem_addr_out; /* memory address bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* signal declarations */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
wire burst_done; /* burst/mlt done */
|
||||
wire cflg_en; /* carry flag control */
|
||||
wire carry_bit; /* carry flag */
|
||||
wire dma_ack; /* dma acknowledge */
|
||||
wire dmar_reg; /* latched dma request */
|
||||
wire ex_af_pls; /* exchange af,af' */
|
||||
wire ex_bank_pls; /* exchange register bank */
|
||||
wire ex_dehl_inst; /* exchange de,hl */
|
||||
wire ftch_tran; /* inst fetch transaction */
|
||||
wire halt_nxt, halt_tran; /* halt transaction */
|
||||
wire iack_tran; /* int ack transaction */
|
||||
wire if_frst; /* first clock if ifetch */
|
||||
wire inta_frst; /* first clock of intack */
|
||||
wire intr_reg; /* latched interrupt request */
|
||||
wire io_read; /* i/o read enable */
|
||||
wire io_tran; /* i/o transaction */
|
||||
wire io_strobe; /* i/o data strobe */
|
||||
wire ivec_rd; /* interrupt vector enable */
|
||||
wire ld_ctrl; /* load control register */
|
||||
wire ld_dmaa; /* load dma request */
|
||||
wire ld_inst; /* load instruction register */
|
||||
wire ld_inta; /* sample latched int */
|
||||
wire ld_page; /* load page register */
|
||||
wire ld_wait; /* sample wait input */
|
||||
wire mem_rd; /* memory read enable */
|
||||
wire mem_tran; /* memory transaction */
|
||||
wire mem_wr; /* memory write enable */
|
||||
wire output_inh; /* disable cpu outputs */
|
||||
wire par_bit; /* parity flag */
|
||||
wire rd_brst; /* burst read */
|
||||
wire rd_frst; /* first clock of read */
|
||||
wire rd_nxt; /* read trans next */
|
||||
wire reti_nxt, reti_tran; /* reti transaction */
|
||||
wire rreg_en; /* update refresh register */
|
||||
wire sflg_en; /* sign flag control */
|
||||
wire sign_bit; /* sign flag */
|
||||
wire tflg_reg; /* temporary flag */
|
||||
wire t1; /* first clock of transaction */
|
||||
wire vector_int; /* int vector enable */
|
||||
wire wait_st; /* wait state identifier */
|
||||
wire wr_brst; /* burst write */
|
||||
wire wr_frst; /* first clock of write */
|
||||
wire xhlt_reg; /* halt exit */
|
||||
wire zero_bit; /* zero flag */
|
||||
wire zflg_en; /* zero flag control */
|
||||
wire [3:0] page_sel; /* inst decode page control */
|
||||
wire [3:0] page_reg; /* instruction decode "page" */
|
||||
wire [7:0] inst_reg; /* instruction register */
|
||||
wire [7:0] data_in; /* read data bus */
|
||||
wire [7:0] dout_io_reg, dout_mem_reg; /* write data bus */
|
||||
wire [15:0] addr_reg_in; /* processor logical address */
|
||||
wire [7:0] io_data_out; /* i/o output data bus */
|
||||
wire [7:0] mem_data_out; /* memory output data bus */
|
||||
wire [15:0] io_addr_out; /* i/o address bus */
|
||||
wire [15:0] mem_addr_out; /* memory address bus */
|
||||
wire [`ADCTL_IDX:0] add_sel; /* address output mux control */
|
||||
wire [`ALUA_IDX:0] alua_sel; /* alu input a mux control */
|
||||
wire [`ALUB_IDX:0] alub_sel; /* alu input b mux control */
|
||||
wire [`ALUOP_IDX:0] aluop_sel; /* alu operation control */
|
||||
wire [`DI_IDX:0] di_ctl; /* data input control */
|
||||
wire [`DO_IDX:0] do_ctl; /* data output control */
|
||||
wire [`HFLG_IDX:0] hflg_ctl; /* half-carry flag control */
|
||||
wire [`IEF_IDX:0] ief_ctl; /* interrupt enable control */
|
||||
wire [`IMD_IDX:0] imd_ctl; /* interrupt mode control */
|
||||
wire [`NFLG_IDX:0] nflg_ctl; /* negate flag control */
|
||||
wire [`PCCTL_IDX:0] pc_sel; /* pc source control */
|
||||
wire [`PFLG_IDX:0] pflg_ctl; /* parity/overflow flag control */
|
||||
wire [`STATE_IDX:0] state_nxt, state_reg; /* machine state */
|
||||
wire [`TFLG_IDX:0] tflg_ctl; /* temp flag control */
|
||||
wire [`TTYPE_IDX:0] tran_sel; /* transaction type */
|
||||
wire [`WREG_IDX:0] wr_addr; /* register write address bus */
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* interface module */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
extint EXTINT ( .data_in(data_in), .dma_ack(dma_ack), .ftch_tran(ftch_tran),
|
||||
.halt_tran(halt_tran), .iack_tran(iack_tran),
|
||||
.io_addr_out(io_addr_out), .io_data_out(io_data_out),
|
||||
.io_read(io_read), .io_strobe(io_strobe), .io_tran(io_tran),
|
||||
.ivec_rd(ivec_rd), .mem_addr_out(mem_addr_out),
|
||||
.mem_data_out(mem_data_out), .mem_rd(mem_rd), .mem_tran(mem_tran),
|
||||
.mem_wr(mem_wr), .reti_tran(reti_tran), .t1(t1),
|
||||
.addr_reg_in(addr_reg_in), .clkc(clkc), .dmar_reg(dmar_reg),
|
||||
.dout_io_reg(dout_io_reg), .dout_mem_reg(dout_mem_reg),
|
||||
.halt_nxt(halt_nxt), .if_frst(if_frst), .inta_frst(inta_frst),
|
||||
.io_data_in(io_data_in), .ivec_data_in(ivec_data_in),
|
||||
.ld_dmaa(ld_dmaa), .ld_wait(ld_wait), .mem_data_in(mem_data_in),
|
||||
.output_inh(output_inh), .rd_frst(rd_frst), .rd_nxt(rd_nxt),
|
||||
.resetb(resetb), .reti_nxt(reti_nxt), .tran_sel(tran_sel),
|
||||
.wr_frst(wr_frst) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* state machine module */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
machine MACHINE ( .ld_ctrl(ld_ctrl), .state_reg(state_reg), .wait_st(wait_st),
|
||||
.clkc(clkc), .dmar_reg(dmar_reg), .intr_reg(intr_reg),
|
||||
.ld_inta(ld_inta), .ld_wait(ld_wait), .resetb(resetb),
|
||||
.state_nxt(state_nxt), .wait_req(wait_req) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* control module */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
control CONTROL ( .add_sel(add_sel), .alua_sel(alua_sel), .alub_sel(alub_sel),
|
||||
.aluop_sel(aluop_sel), .cflg_en(cflg_en), .di_ctl(di_ctl),
|
||||
.do_ctl(do_ctl), .ex_af_pls(ex_af_pls), .ex_bank_pls(ex_bank_pls),
|
||||
.ex_dehl_inst(ex_dehl_inst), .halt_nxt(halt_nxt), .hflg_ctl(hflg_ctl),
|
||||
.ief_ctl(ief_ctl), .if_frst(if_frst), .inta_frst(inta_frst),
|
||||
.imd_ctl(imd_ctl), .ld_dmaa(ld_dmaa), .ld_inst(ld_inst),
|
||||
.ld_inta(ld_inta), .ld_page(ld_page), .ld_wait(ld_wait),
|
||||
.nflg_ctl(nflg_ctl), .output_inh(output_inh), .page_sel(page_sel),
|
||||
.pc_sel(pc_sel), .pflg_ctl(pflg_ctl), .rd_frst(rd_frst),
|
||||
.rd_nxt(rd_nxt), .reti_nxt(reti_nxt), .rreg_en(rreg_en), .sflg_en(sflg_en),
|
||||
.state_nxt(state_nxt), .tflg_ctl(tflg_ctl), .tran_sel(tran_sel),
|
||||
.wr_addr(wr_addr), .wr_frst(wr_frst), .zflg_en(zflg_en),
|
||||
.carry_bit(carry_bit), .dmar_reg(dmar_reg), .inst_reg(inst_reg),
|
||||
.intr_reg(intr_reg), .page_reg(page_reg), .par_bit(par_bit),
|
||||
.sign_bit(sign_bit), .state_reg(state_reg), .tflg_reg(tflg_reg),
|
||||
.vector_int(vector_int), .xhlt_reg(xhlt_reg), .zero_bit(zero_bit),
|
||||
.int_req(int_req) );
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* */
|
||||
/* data path module */
|
||||
/* */
|
||||
/*****************************************************************************************/
|
||||
datapath DATAPATH ( .addr_reg_in(addr_reg_in), .carry_bit(carry_bit), .dmar_reg(dmar_reg),
|
||||
.dout_io_reg(dout_io_reg), .dout_mem_reg(dout_mem_reg),
|
||||
.inst_reg(inst_reg), .intr_reg(intr_reg), .page_reg(page_reg),
|
||||
.par_bit(par_bit), .sign_bit(sign_bit), .tflg_reg(tflg_reg),
|
||||
.vector_int(vector_int), .xhlt_reg(xhlt_reg), .zero_bit(zero_bit),
|
||||
.add_sel(add_sel), .alua_sel(alua_sel), .alub_sel(alub_sel),
|
||||
.aluop_sel(aluop_sel), .clearb(clearb), .clkc(clkc), .cflg_en(cflg_en),
|
||||
.data_in(data_in), .di_ctl(di_ctl), .dma_req(dma_req), .do_ctl(do_ctl),
|
||||
.ex_af_pls(ex_af_pls), .ex_bank_pls(ex_bank_pls),
|
||||
.ex_dehl_inst(ex_dehl_inst), .hflg_ctl(hflg_ctl), .ief_ctl(ief_ctl),
|
||||
.imd_ctl(imd_ctl), .int_req(int_req), .ivec_rd(ivec_rd),
|
||||
.ld_ctrl(ld_ctrl), .ld_inst(ld_inst), .ld_page(ld_page),
|
||||
.nflg_ctl(nflg_ctl), .nmi_req(nmi_req), .page_sel(page_sel),
|
||||
.pc_sel(pc_sel), .pflg_ctl(pflg_ctl), .resetb(resetb), .rreg_en(rreg_en),
|
||||
.sflg_en(sflg_en), .tflg_ctl(tflg_ctl), .wait_st(wait_st),
|
||||
.wr_addr(wr_addr), .zflg_en(zflg_en) );
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user