Line 42... |
Line 42... |
// Next8080 processor features:
|
// Next8080 processor features:
|
// Fast conditional jump/call/ret takes only 1 T state if not executed
|
// Fast conditional jump/call/ret takes only 1 T state if not executed
|
// Each CPU machine cycle takes (mainly) one clock T state. This makes this processor over 4 times faster than a 8080 at the same
|
// Each CPU machine cycle takes (mainly) one clock T state. This makes this processor over 4 times faster than a 8080 at the same
|
// clock frequency (some instructions are up to 10 times faster).
|
// clock frequency (some instructions are up to 10 times faster).
|
// Only 8080 instructions available (minus DAA, which = CPL) + some extra: JR, DJNZ
|
// Only 8080 instructions available (minus DAA, which = CPL) + some extra: JR, DJNZ
|
// Only IM0 supported, flags 3 and 5 always 0, opcodes DD, ED, FD, CB treated as NOP
|
// Only IM0 supported, flags 3 and 5 always 0, opcodes ED, FD, CB treated as NOP
|
// No H and N flags, always 0
|
// No H and N flags, always 0
|
|
|
|
// Indexed mode: after the new instruction INDEX i8 [0xdd, i8], the next instruction (only) will use (mem+i8) instead of (mem)
|
|
// No interrupt is accepted after INDEX i8. i8 is a signed 8bit value.
|
|
// Indexed mode applies to the following instructions:
|
|
// 02h = ld (bc+i8),a
|
|
// 12h = ld (de+i8),a
|
|
// 22h = ld (hl+i8),a instead of ld (nn),hl. Ex: [0xdd 0xff 0x22] will execute ld (hl-1),a
|
|
// 32h = ld (sp+i8),a instead of ld (nn),a. Ex: [0xdd 0x13 0x32] will execute ld (sp+13h),a
|
|
// 0Ah = ld a,(bc+i8)
|
|
// 1Ah = ld a,(de+i8)
|
|
// 2Ah = ld a,(hl+i8),a instead of ld hl,(nn)
|
|
// 3Ah = ld a,(sp+i8),a instead of ld a,(nn)
|
|
// All the other instructions which uses memory at (hl): ld r,(hl+i8); ld (hl+i8),r; inc (hl+i8); dec (hl+i8); ld (hl+i8),n; op a,(hl);
|
|
|
// ~450 LUT6
|
// ~450 LUT6
|
// See NextZ80 for more detais
|
// See NextZ80 for more detais
|
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
Line 68... |
Line 82... |
output reg HALT,
|
output reg HALT,
|
output reg M1
|
output reg M1
|
);
|
);
|
|
|
// connections and registers
|
// connections and registers
|
reg [1:0] CPUStatus = 0; // 0=HL-HL', 1=EI
|
reg [2:0] CPUStatus = 0; // 0=HL-DE, 1=EI, 2-indexed mode
|
wire [7:0] ALU8FLAGS;
|
wire [7:0] ALU8FLAGS;
|
wire [7:0] FLAGS;
|
wire [7:0] FLAGS;
|
wire [7:0] ALU80;
|
wire [7:0] ALU80;
|
wire [7:0] ALU81;
|
wire [7:0] ALU81;
|
wire [15:0]ALU160;
|
wire [15:0]ALU160;
|
Line 94... |
Line 108... |
reg [4:0] ALU8OP;
|
reg [4:0] ALU8OP;
|
reg [2:0] ALU16OP;
|
reg [2:0] ALU16OP;
|
reg next_stage;
|
reg next_stage;
|
reg [3:0]REG_WSEL;
|
reg [3:0]REG_WSEL;
|
reg [3:0]REG_RSEL;
|
reg [3:0]REG_RSEL;
|
reg [2:0]status; // 0=HL-HL', 1=EI, 2=set EI
|
reg [3:0]status; // 0=HL-DE, 1=EI, 2=set EI, 3=set indexed mode
|
// FETCH[5:3]: 000 NZ, 001 Z, 010 NC, 011 C, 100 PO, 101 PE, 110 P, 111 M
|
// FETCH[5:3]: 000 NZ, 001 Z, 010 NC, 011 C, 100 PO, 101 PE, 110 P, 111 M
|
wire [7:0]FlagMux = {FLAGS[7], !FLAGS[7], FLAGS[2], !FLAGS[2], FLAGS[0], !FLAGS[0], FLAGS[6], !FLAGS[6]};
|
wire [7:0]FlagMux = {FLAGS[7], !FLAGS[7], FLAGS[2], !FLAGS[2], FLAGS[0], !FLAGS[0], FLAGS[6], !FLAGS[6]};
|
reg tzf;
|
reg tzf;
|
reg SRESET = 0;
|
reg SRESET = 0;
|
reg SINT = 0;
|
reg SINT = 0;
|
Line 151... |
Line 165... |
if(SRESET) FETCH <= 9'b110000000;
|
if(SRESET) FETCH <= 9'b110000000;
|
else
|
else
|
if(FETCH[8:6] == 3'b110) {FETCH[8:7]} <= 2'b00; // exit RESET state
|
if(FETCH[8:6] == 3'b110) {FETCH[8:7]} <= 2'b00; // exit RESET state
|
else begin
|
else begin
|
if(M1) FETCH <= {1'b0, DI};
|
if(M1) FETCH <= {1'b0, DI};
|
if(!next_stage & SINT & CPUStatus[1] & !status[2]) {FETCH[8:6], FETCH[1:0]} <= {3'b100, HALT, M1}; // INT request
|
if(!next_stage & SINT & CPUStatus[1] & !status[2] & !status[3]) {FETCH[8:6], FETCH[1:0]} <= {3'b100, HALT, M1}; // INT request
|
end
|
end
|
if(next_stage) STAGE <= STAGE + 1'b1;
|
if(next_stage) STAGE <= STAGE + 1'b1;
|
else STAGE <= 0;
|
else STAGE <= 0;
|
CPUStatus[0] <= CPUStatus[0] ^ status[0];
|
CPUStatus[0] <= CPUStatus[0] ^ status[0];
|
if(status[2]) CPUStatus[1] <= status[1]; // EI
|
if(status[2]) CPUStatus[1] <= status[1]; // EI
|
|
if(!next_stage) CPUStatus[2] <= status[3];
|
tzf <= ALU8FLAGS[6];
|
tzf <= ALU8FLAGS[6];
|
end
|
end
|
|
|
assign opd[0] = FETCH[0] ^ &FETCH[2:1];
|
assign opd[0] = FETCH[0] ^ &FETCH[2:1];
|
assign opd[2:1] = FETCH[2:1];
|
assign opd[2:1] = FETCH[2:1];
|
Line 181... |
Line 196... |
M1 = 1;
|
M1 = 1;
|
MREQ = 1;
|
MREQ = 1;
|
WR = 0;
|
WR = 0;
|
HALT = 0;
|
HALT = 0;
|
IORQ = 0;
|
IORQ = 0;
|
status = 3'b000;
|
status = 4'b0000;
|
|
|
|
|
case(FETCH[8:6])
|
case(FETCH[8:6])
|
//------------------------------------------- block 00 ----------------------------------------------------
|
//------------------------------------------- block 00 ----------------------------------------------------
|
3'b000:
|
3'b000:
|
Line 260... |
Line 275... |
// ----------------------- LD (BC) A - LD (DE) A - LD (nn) HL, LD (nn),A --------------------
|
// ----------------------- LD (BC) A - LD (DE) A - LD (nn) HL, LD (nn),A --------------------
|
// ----------------------- LD A (BC) - LD A (DE) - LD HL (nn), LD A (nn) --------------------
|
// ----------------------- LD A (BC) - LD A (DE) - LD HL (nn), LD A (nn) --------------------
|
4'b0010, 4'b1010:
|
4'b0010, 4'b1010:
|
case(STAGE[2:0])
|
case(STAGE[2:0])
|
3'b000:
|
3'b000:
|
if(FETCH[5] == 0) begin // LD (BC) A, LD (DE) A - stage1
|
if(!FETCH[5] | CPUStatus[2]) begin // LD (BC) A, LD (DE) A - stage1
|
if(FETCH[3]) DINW_SEL = 1; // DI
|
DINW_SEL = 1; // DI
|
else DO_SEL = 2'b00; // ALU80
|
DO_SEL = 2'b00; // ALU80
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
WE = {4'b000x, FETCH[3], 1'bx}; // hi
|
WE = {4'b000x, FETCH[3], 1'bx}; // hi
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = FETCH[3] ? 4'b011x : 4'b0110; // A
|
REG_WSEL = FETCH[3] ? 4'b011x : 4'b0110; // A
|
REG_RSEL = {op16, 1'bx};
|
REG_RSEL = {op16, 1'bx};
|
M1 = 0;
|
M1 = 0;
|
Line 279... |
Line 295... |
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b111x;
|
REG_WSEL = 4'b111x;
|
M1 = 0;
|
M1 = 0;
|
end
|
end
|
3'b001:
|
3'b001:
|
if(FETCH[5] == 0) begin // LD (BC), A, LD (DE), A - stage2
|
if(!FETCH[5] | CPUStatus[2]) begin // LD (BC), A, LD (DE), A - stage2
|
ALU160_SEL = 1; // pc
|
ALU160_SEL = 1; // pc
|
WE = 6'b010x00; // PC
|
WE = 6'b010x00; // PC
|
end else begin // LD (nn),A - LH (nn),HL - stage 2
|
end else begin // LD (nn),A - LH (nn),HL - stage 2
|
ALU160_SEL = 1; // pc
|
ALU160_SEL = 1; // pc
|
DINW_SEL = 1; // DI
|
DINW_SEL = 1; // DI
|
Line 366... |
Line 382... |
ALU8OP = {3'b010, FETCH[0], 1'b0}; // inc / dec
|
ALU8OP = {3'b010, FETCH[0], 1'b0}; // inc / dec
|
REG_WSEL = {1'b0, opd[5:3]};
|
REG_WSEL = {1'b0, opd[5:3]};
|
end else case({STAGE[1:0]})
|
end else case({STAGE[1:0]})
|
2'b00: begin // (HL) - stage1
|
2'b00: begin // (HL) - stage1
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
DINW_SEL = 1; // DI
|
DINW_SEL = 1; // DI
|
WE = 6'b000001; // lo
|
WE = 6'b000001; // lo
|
ALU16OP = 3'd0;
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b011x; // tmpLO
|
REG_WSEL = 4'b011x; // tmpLO
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
end
|
end
|
2'b01: begin // (HL) stage2
|
2'b01: begin // (HL) stage2
|
DO_SEL = 2'b11; // ALU80OUT
|
DO_SEL = 2'b11; // ALU80OUT
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
WE = 6'b100x0x; // flags
|
WE = 6'b100x0x; // flags
|
ALU8OP = {3'b010, FETCH[0], 1'b0}; // inc / dec
|
ALU8OP = {3'b010, FETCH[0], 1'b0}; // inc / dec
|
ALU16OP = 3'd0;
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b0111; // tmpLO
|
REG_WSEL = 4'b0111; // tmpLO
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
WR = 1;
|
WR = 1;
|
Line 409... |
Line 425... |
WE = 6'b010x00; // PC
|
WE = 6'b010x00; // PC
|
end
|
end
|
3'b01_1: begin // (HL) - stage2
|
3'b01_1: begin // (HL) - stage2
|
DO_SEL = 2'b00; // ALU80
|
DO_SEL = 2'b00; // ALU80
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
WE = 6'b000x0x; // nothing
|
WE = 6'b000x0x; // nothing
|
ALU16OP = 3'd0;
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b0111; // tmpLO
|
REG_WSEL = 4'b0111; // tmpLO
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
WR = 1;
|
WR = 1;
|
Line 472... |
Line 488... |
REG_RSEL = {1'b0, opd[2:0]};
|
REG_RSEL = {1'b0, opd[2:0]};
|
end
|
end
|
3'b0_01: // LD r, (HL) 1st stage
|
3'b0_01: // LD r, (HL) 1st stage
|
begin
|
begin
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
DINW_SEL = 1; // DI
|
DINW_SEL = 1; // DI
|
WE = 6'b000x01; // LO
|
WE = 6'b000x01; // LO
|
ALU16OP = 3'd0; // ADD - NOP
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b011x; // A - tmpLO
|
REG_WSEL = 4'b011x; // A - tmpLO
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
end
|
end
|
3'b0_10: // LD (HL), r 1st stage
|
3'b0_10: // LD (HL), r 1st stage
|
begin
|
begin
|
DO_SEL = 0; // ALU80
|
DO_SEL = 0; // ALU80
|
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
WE = 6'b000x00; // no write
|
WE = 6'b000x00; // no write
|
ALU16OP = 3'd0; // ADD - NOP
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = {1'b0, opd[2:0]};
|
REG_WSEL = {1'b0, opd[2:0]};
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
WR = 1;
|
WR = 1;
|
Line 519... |
Line 535... |
REG_WSEL = 4'b0110; // A
|
REG_WSEL = 4'b0110; // A
|
REG_RSEL = {1'b0, opd[2:0]};
|
REG_RSEL = {1'b0, opd[2:0]};
|
end
|
end
|
2'b0_1: // OP r, (HL) 1st stage
|
2'b0_1: // OP r, (HL) 1st stage
|
begin
|
begin
|
ALU160_SEL = 0; // HL
|
ALU160_SEL = 0; // regs
|
|
if(CPUStatus[2]) ALU16OP = 3; // indexed mode
|
DINW_SEL = 1; // DI
|
DINW_SEL = 1; // DI
|
WE = 6'b000x01; // lo
|
WE = 6'b000x01; // lo
|
ALU16OP = 3'd0; // ADD - NOP
|
|
next_stage = 1;
|
next_stage = 1;
|
REG_WSEL = 4'b011x; // A-tmpLO
|
REG_WSEL = 4'b011x; // A-tmpLO
|
REG_RSEL = 4'b010x; // HL
|
REG_RSEL = 4'b010x; // HL
|
M1 = 0;
|
M1 = 0;
|
end
|
end
|
Line 893... |
Line 909... |
ALU160_SEL = 0; // regs
|
ALU160_SEL = 0; // regs
|
WE = 6'b010x00; // PC
|
WE = 6'b010x00; // PC
|
REG_RSEL = 4'b111x; // tmp7
|
REG_RSEL = 4'b111x; // tmp7
|
end
|
end
|
endcase
|
endcase
|
2'b01, 2'b10, 2'b11: begin // DD - IX, ED, FD - IY
|
2'b01: begin // DD - indexed mode
|
|
ALU160_SEL = 1; // PC
|
|
if(!STAGE[0]) begin
|
|
WE = 6'b010100; // PC, tmpHI
|
|
next_stage = 1;
|
|
M1 = 0;
|
|
end else begin
|
|
WE = 6'b010000; // PC
|
|
status[3] = 1'b1; // set indexed mode
|
|
end
|
|
end
|
|
2'b10, 2'b11: begin // ED, FD - IY
|
ALU160_SEL = 1; // PC
|
ALU160_SEL = 1; // PC
|
WE = 6'b010x00; // PC
|
WE = 6'b010x00; // PC
|
end
|
end
|
endcase
|
endcase
|
endcase
|
endcase
|
Line 1211... |
Line 1238... |
case(SEL)
|
case(SEL)
|
0: RAMSEL = 3'b000; // BC
|
0: RAMSEL = 3'b000; // BC
|
1: RAMSEL = rstatus ? 3'b010 : 3'b001; // HL - DE
|
1: RAMSEL = rstatus ? 3'b010 : 3'b001; // HL - DE
|
2: RAMSEL = rstatus ? 3'b001 : 3'b010; // DE - HL
|
2: RAMSEL = rstatus ? 3'b001 : 3'b010; // DE - HL
|
3: RAMSEL = 3'b011; // A-TL
|
3: RAMSEL = 3'b011; // A-TL
|
4: RAMSEL = 3'b100; // I-R
|
default: RAMSEL = 3'b100; // I-R, tmp SP, zero, temp
|
5: RAMSEL = 3'b100; // tmp SP
|
|
6: RAMSEL = 3'b100; // zero
|
|
7: RAMSEL = 3'b100; // temp
|
|
endcase
|
endcase
|
end
|
end
|
endmodule
|
endmodule
|
|
|
module RAM16X8D_regs(
|
module RAM16X8D_regs(
|