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

Subversion Repositories next186

[/] [next186/] [trunk/] [Next186_CPU.v] - Diff between revs 3 and 5

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

Rev 3 Rev 5
Line 49... Line 49...
//              In order to couple the CPU unit with a single bus, these sepparate data/instruction buses must be multiplexed by
//              In order to couple the CPU unit with a single bus, these sepparate data/instruction buses must be multiplexed by
//              a dedicated bus interface unit (BIU).
//              a dedicated bus interface unit (BIU).
//              It is able to execute up to 40Mips on Spartan XC3S700AN speed grade -4, performances comparable with a 486 CPU.
//              It is able to execute up to 40Mips on Spartan XC3S700AN speed grade -4, performances comparable with a 486 CPU.
//              Small size, the CPU + BIU requires ~25%  or 1500 slices - on Spartan XC3S700AN
//              Small size, the CPU + BIU requires ~25%  or 1500 slices - on Spartan XC3S700AN
// 
// 
 
//      16May2012 - fixed CMPS/SCAS bug when interrupted on the <equal> item
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
`timescale 1ns / 1ps
 
 
module Next186_CPU(
module Next186_CPU(
    output [19:0] ADDR,
    output [19:0] ADDR,
Line 176... Line 177...
// interrupts
// interrupts
        wire SAMPLEINT = ~(WE[2] & RASEL[1:0] == 2'b10) & ~status[2] & ~status[4] & ~status[5]; // not load SS, no prefix
        wire SAMPLEINT = ~(WE[2] & RASEL[1:0] == 2'b10) & ~status[2] & ~status[4] & ~status[5]; // not load SS, no prefix
        wire NMIACK = SNMI & ~FNMI;     // NMI acknowledged
        wire NMIACK = SNMI & ~FNMI;     // NMI acknowledged
        wire INTRACK = FLAGS[9] & (~WE[4] | FIN[9]) & SINTR;                    // INTR acknowledged (IF and not CLI in progress)
        wire INTRACK = FLAGS[9] & (~WE[4] | FIN[9]) & SINTR;                    // INTR acknowledged (IF and not CLI in progress)
        wire IACK = IRQ | (SAMPLEINT & (NMIACK | INTRACK)) | (~WE[2] & ~HALT & FLAGS[8]); // interrupt acknowledged
        wire IACK = IRQ | (SAMPLEINT & (NMIACK | INTRACK)) | (~WE[2] & ~HALT & FLAGS[8]); // interrupt acknowledged
 
        reg CMPS;       // early EQ test for CMPS
 
        reg SCAS;   // early EQ test for SCAS
 
 
        Next186_Regs REGS (
        Next186_Regs REGS (
    .RASEL(RASEL),
    .RASEL(RASEL),
    .RBSEL(RBSEL),
    .RBSEL(RBSEL),
    .BASEL(BASEL),
    .BASEL(BASEL),
Line 288... Line 291...
                                        FETCH[2] <= INSTR[23:16];
                                        FETCH[2] <= INSTR[23:16];
                                        FETCH[1] <= INSTR[15:8];
                                        FETCH[1] <= INSTR[15:8];
                                        FETCH[0] <= INSTR[7:0];
                                        FETCH[0] <= INSTR[7:0];
                                        STAGE <= 0;
                                        STAGE <= 0;
                                        CPUStatus[5:0] <= status[5:0];
                                        CPUStatus[5:0] <= status[5:0];
                                        TZF <= status[3];
 
                                        ICODE1 <= ICODE(INSTR[7:0]);
                                        ICODE1 <= ICODE(INSTR[7:0]);
                                end else begin          // no interrupt, no fetch
                                end else begin          // no interrupt, no fetch
                                        STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1;
                                        STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1;
                                        if(&DOSEL) {FETCH[3], FETCH[2]} <= |DISEL ? DIN : RB;
                                        if(&DOSEL) {FETCH[3], FETCH[2]} <= |DISEL ? DIN : RB;
                                        TZF <= FIN[6];          // zero flag for REP
                                        TZF <= FIN[6];          // zero flag for BOUND
                                        TLF <= FIN[7] != FIN[11];       // less flag for BOUND
                                        TLF <= FIN[7] != FIN[11];       // less flag for BOUND
                                end
                                end
                        end
                        end
                        if(IFETCH & ~status[2] & ~status[4] & ~status[5]) CRTIP <= IPIN; // no prefix
                        if(IFETCH & ~status[2] & ~status[4] & ~status[5]) CRTIP <= IPIN; // no prefix
                        SRST <= RST;                            // level detection RST
                        SRST <= RST;                            // level detection RST
Line 307... Line 309...
                                SNMI <= 1'b0;
                                SNMI <= 1'b0;
                                FNMI <= 1'b0;
                                FNMI <= 1'b0;
                        end
                        end
                        if(~|STAGE[1:0]) DIVQSGN <= QSGN;
                        if(~|STAGE[1:0]) DIVQSGN <= QSGN;
                        RDIVEXC <= DIVOP & DIVEXC & ~IDIV; // bit 8/16 for unsigned DIV
                        RDIVEXC <= DIVOP & DIVEXC & ~IDIV; // bit 8/16 for unsigned DIV
 
                        CMPS <= (~FETCH[0][0] | (FETCH[3] == DIN[15:8])) & (FETCH[2] == DIN[7:0]); // early EQ test for CMPS
 
                        SCAS <= (~FETCH[0][0] | (AX[15:8] == DIN[15:8])) & (AX[7:0] == DIN[7:0]);  // early EQ test for SCAS
                end
                end
 
 
        always @(ISEL, FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5])
        always @(ISEL, FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5])
                case(ISEL)
                case(ISEL)
                        2'b00: DIMM1 = {FETCH[2], FETCH[1]};
                        2'b00: DIMM1 = {FETCH[2], FETCH[1]};
Line 332... Line 336...
                        3'b110: ISIZEI = 6;
                        3'b110: ISIZEI = 6;
                        default: ISIZEI = 5;
                        default: ISIZEI = 5;
                endcase
                endcase
        end
        end
 
 
         always @(FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5], MOD, REG, RM, CPUStatus, USEBP, NOBP, RASEL, ISIZEI, TLF, EAC, COUT, DIVEND, DIVC, QSGN,
         always @(FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5], MOD, REG, RM, CPUStatus, USEBP, NOBP, RASEL, ISIZEI, TLF, EAC, COUT, DIVEND, DIVC, QSGN, CMPS, SCAS,
                                 WBIT, ISIZES, ISELS, WRBIT, ISIZEW, STAGE, NULLSHIFT, ALUCONT, FLAGS, CXZ, RCXZ, NRORCXLE1, TZF, JMPC, LOOPC, ICODE1, DIVQSGN, DIVSGN, DIVRSGN, SOUT) begin
                                 WBIT, ISIZES, ISELS, WRBIT, ISIZEW, STAGE, NULLSHIFT, ALUCONT, FLAGS, CXZ, RCXZ, NRORCXLE1, TZF, JMPC, LOOPC, ICODE1, DIVQSGN, DIVSGN, DIVRSGN, SOUT) begin
                WORD = FETCH[0][0];
                WORD = FETCH[0][0];
                BASEL = FETCH[0][1] | &MOD;
                BASEL = FETCH[0][1] | &MOD;
                RASEL = FETCH[0][1] ? REG : RM; // destination
                RASEL = FETCH[0][1] ? REG : RM; // destination
                BBSEL = {1'b0, !FETCH[0][1] | &MOD};
                BBSEL = {1'b0, !FETCH[0][1] | &MOD};
Line 1061... Line 1065...
                        33: begin
                        33: begin
                                DISP16 = 1'b0;
                                DISP16 = 1'b0;
                                AEXT = 1'b0;
                                AEXT = 1'b0;
                                NOBP = 1'b1;    // for RSSEL
                                NOBP = 1'b1;    // for RSSEL
                                case(STAGE[1:0])
                                case(STAGE[1:0])
                                        2'b00: begin            // stage1, read ES:[DI] in FETCH[2:1], inc/dec DI
                                        2'b00: begin            // stage1, read ES:[DI] in FETCH[3:2], inc/dec DI
                                                RASEL = 3'b111;         // SI
                                                RASEL = 3'b111;         // SI
                                                RSSEL = 2'b00;          // ES
                                                RSSEL = 2'b00;          // ES
                                                ALUOP = {4'b0100, FLAGS[10]};
                                                ALUOP = {4'b0100, FLAGS[10]};
                                                EAC = 4'b0101;          // DI+DISP
                                                EAC = 4'b0101;          // DI+DISP
                                                DISEL = 2'b11;          // ALU 16bit
                                                DISEL = 2'b11;          // ALU 16bit
                                                DOSEL = 2'b11;          // read data to FETCH
                                                DOSEL = 2'b11;          // read data to FETCH
                                                IFETCH = CPUStatus[4] && (~|CXZ || (CPUStatus[3] ^ TZF));       // REP & CX==0
                                                IFETCH = RCXZ;//(~|CXZ || (CPUStatus[3] ^ TZF));        // REP & CX==0
                                                MREQ = ~IFETCH;
                                                MREQ = ~RCXZ;
                                                WE[1:0] = IFETCH ? 2'b00 : 2'b11;                // RASEL_HI, RASEL_LO
                                                WE[1:0] = IFETCH ? 2'b00 : 2'b11;                // RASEL_HI, RASEL_LO
                                        end
                                        end
                                        2'b01: begin            // stage2, read DS:[SI] in TMP16, inc/dec SI
                                        2'b01: begin            // stage2, read DS:[SI] in TMP16, inc/dec SI
                                                RASEL = 3'b110;         // DI
                                                RASEL = 3'b110;         // DI
                                                ALUOP = {4'b0100, FLAGS[10]};
                                                ALUOP = {4'b0100, FLAGS[10]};
                                                EAC = 4'b0100;          // SI+DISP
                                                EAC = 4'b0100;          // SI+DISP
                                                DISEL = 2'b11;          // ALU 16bit
                                                DISEL = 2'b11;          // ALU 16bit
                                                IFETCH = 1'b0;
                                                IFETCH = 1'b0;
                                                WE[3:0] = 4'b1011;               // RASEL_HI, RASEL_LO
                                                WE[3:0] = 4'b1011;               // RASEL_HI, RASEL_LO
                                        end
                                        end
                                        2'b10: begin            // stage3, compare TMP16 wit imm, set flags, dec CX
                                        2'b10: begin            // stage3, compare TMP16 with imm, set flags, dec CX
                                                BASEL = 1'b0;                   // TMP16
                                                BASEL = 1'b0;                   // TMP16
                                                BBSEL = 2'b10;                  // imm
                                                BBSEL = 2'b10;                  // imm
                                                ISEL = 2'b01;
                                                ISEL = 2'b01;
                                                WE[4] = 1'b1;                   // flags
                                                WE[4] = 1'b1;                   // flags
                                                ALUOP = 5'b00111;               // cmp
                                                ALUOP = 5'b00111;               // cmp
                                                MREQ = 1'b0;
                                                MREQ = 1'b0;
                                                IFETCH = ~CPUStatus[4];
                                                IFETCH = NRORCXLE1 | (CPUStatus[3] ^ CMPS);
                                                DECCX = CPUStatus[4];
                                                DECCX = CPUStatus[4];
                                                ALUSTAGE = 1'b1;
                                                ALUSTAGE = 1'b1;
                                                REPINT = 1'b1;
                                                REPINT = 1'b1;
                                        end
                                        end
                                endcase
                                endcase
Line 1099... Line 1103...
                        end
                        end
// --------------------------------  (rep)scas --------------------------------
// --------------------------------  (rep)scas --------------------------------
                        34: begin
                        34: begin
                                DISP16 = 1'b0;
                                DISP16 = 1'b0;
                                AEXT = 1'b0;
                                AEXT = 1'b0;
                                NOBP = 1'b1;    // for RSSEL (not really necesary, but with it the synthesis generates better speed)
 
                                if(!STAGE[0]) begin      // stage1, read ES:[DI] in TMP16, inc/dec DI
                                if(!STAGE[0]) begin      // stage1, read ES:[DI] in TMP16, inc/dec DI
                                        RASEL = 3'b111;         // DI
                                        RASEL = 3'b111;         // DI
                                        RSSEL = 2'b00;          // ES
                                        RSSEL = 2'b00;          // ES
                                        ALUOP = {4'b0100, FLAGS[10]};
                                        ALUOP = {4'b0100, FLAGS[10]};
                                        EAC = 4'b0101;          // DI+DISP
                                        EAC = 4'b0101;          // DI+DISP
                                        DISEL = 2'b11;          // ALU 16bit
                                        DISEL = 2'b11;          // ALU 16bit
                                        IFETCH = CPUStatus[4] && (~|CXZ || (CPUStatus[3] ^ TZF));       // REP & CX==0
                                        IFETCH = RCXZ;//(~|CXZ || (CPUStatus[3] ^ TZF));        // REP & CX==0
                                        MREQ = ~IFETCH;
                                        MREQ = ~RCXZ;
                                        WE[3:0] = IFETCH ? 4'b0000 : 4'b1011;            // TMP16, RASEL_HI, RASEL_LO
                                        WE[3:0] = IFETCH ? 4'b0000 : 4'b1011;            // TMP16, RASEL_HI, RASEL_LO
                                end else begin  //stage2, compare AL/AX with TMP16, set flags, dec CX
                                end else begin  //stage2, compare AL/AX with TMP16, set flags, dec CX
                                        RASEL = 3'b000;         // AL/AX
                                        RASEL = 3'b000;         // AL/AX
                                        BBSEL = 2'b00;                  // TMP16
                                        BBSEL = 2'b00;                  // TMP16
                                        WE[4] = 1'b1;                   // flags
                                        WE[4] = 1'b1;                   // flags
                                        ALUOP = 5'b00111;               // cmp
                                        ALUOP = 5'b00111;               // cmp
                                        MREQ = 1'b0;
                                        MREQ = 1'b0;
                                        IFETCH = ~CPUStatus[4];
                                        IFETCH = NRORCXLE1 | (CPUStatus[3] ^ SCAS);
                                        DECCX = CPUStatus[4];
                                        DECCX = CPUStatus[4];
                                        REPINT = 1'b1;
                                        REPINT = 1'b1;
                                end
                                end
                                ISIZE = IFETCH ? 1 : 0;
                                ISIZE = IFETCH ? 1 : 0;
                        end
                        end

powered by: WebSVN 2.1.0

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