OpenCores
URL https://opencores.org/ocsvn/nextz80/nextz80/trunk

Subversion Repositories nextz80

[/] [nextz80/] [trunk/] [Next8080CPU.v] - Diff between revs 14 and 17

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 14 Rev 17
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(

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.