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

Subversion Repositories next186

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /next186
    from Rev 19 to Rev 20
    Reverse comparison

Rev 19 → Rev 20

/trunk/Next186_ALU.v
89,6 → 89,7
input INC2,
output reg [15:0]FOUT,
output reg [15:0]ALUOUT,
output [15:0]ALUOUTA,
output reg ALUCONT,
output NULLSHIFT,
output COUT,
119,6 → 120,7
assign {SC8OUT, SUMOUT[7:4]} = SUMOP1[7:4] + SUMOP2[7:4] + AF;
assign {SC16OUT, SUMOUT[15:8]} = SUMOP1[15:8] + SUMOP2[15:8] + SC8OUT;
assign COUT = (WORD ? SC16OUT : SC8OUT) ^ CPLOP2;
assign ALUOUTA = ALUOP == 5'b11111 ? RB : SUMOUT;
 
// SHIFTER
reg [4:0]SHNOPT; // optimized shift
291,7 → 293,7
// 1100 -
// 1101 - SP+2+DISP
// 1110 - DISP[7:0]<<2
// 1111 - PIO
// 1111 -
module Next186_EA(
input [15:0] SP,
input [15:0] BX,
298,7 → 300,6
input [15:0] BP,
input [15:0] SI,
input [15:0] DI,
input [15:0] PIO,
input [15:0] TMP16,
input [7:0] AL,
input [15:0] AIMM,
329,7 → 330,6
4'b1010: OP3 = {8'b00000000, AL}; // XLAT
4'b1001, 4'b1011: OP3 = 16'h0000; // SP/TMP16 + 2
4'b1110: OP3 = {6'b000000, AIMM[7:0], 2'b00}; // int
4'b1111: OP3 = PIO; // in,out
default: OP3 = AIMM;
endcase
end
/trunk/Next186_BIU_2T_delayread.v
101,7 → 101,9
output reg data_bound,
input [1:0]WSEL, // normally {~ADDR[0], ADDR[0]}
output reg RAM_RD,
output reg RAM_WR
output reg RAM_WR,
input IORQ,
input FASTIO
);
 
reg [31:0]queue[3:0];
173,7 → 175,8
end
end else begin
iread = qnofull;
CE186 = 1;
if(IORQ && !WR && !FASTIO) NEXTSTATE = 3;
else CE186 = 1;
end
end else iread = 1; // else nextstate = 1
end
/trunk/Next186_CPU.v
59,13 → 59,17
// 12Apr2013 - fix IDIV when Q=0
// 16May2013 - fix PUSHA SP pushed stack value, which should be the one before PUSHA
// 25May2013 - generate invalid opcode exception for MOV FS and GS
// 08Sep2016 - separate port address (PORT_ADDR)
// 15Sep2017 - implemented SALC undocumented instruction
///////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
 
module Next186_CPU(
output [20:0] ADDR,
input [15:0] DIN,
output [15:0] DOUT,
output [20:0]ADDR, // mem address
output [15:0]PORT_ADDR, // port address
input [15:0]DIN, // mem/port data in
output [15:0]DOUT, // mem data out
output [15:0]POUT, // port data out
input CLK,
input CE,
input INTR,
72,7 → 76,7
input NMI,
input RST,
output reg MREQ,
output wire IORQ,
output reg IORQ,
output reg INTA,
output reg WR,
output reg WORD,
100,6 → 104,7
wire [15:0]FLAGS;
wire [15:0]FIN;
wire [15:0]ALUOUT;
wire [15:0]ALUOUTA;
wire [15:0]AIMM1;
reg [15:0]DIMM1;
wire [15:0]RS;
151,13 → 156,17
reg [5:0]ICODE1 = 23;
reg NULLSEG;
reg DIVOP;
reg DIVIRQ;
reg AAMIRQ;
reg RCOUT;
 
// signals
assign IORQ = &EAC;
// assign IORQ = &EAC;
assign LOCK = CPUStatus[5];
assign FLUSH = ~IPWSEL || (ISIZE == 3'b000);
assign PORT_ADDR = FETCH[0][3] ? DX : {8'h00, FETCH[1]};
wire [15:0]IPADD = ISIZE == 3'b000 ? CRTIP : IP + ISIZE;
wire [15:0]IPIN = IPWSEL ? IPADD : ALUOUT;
wire [15:0]IPIN = IPWSEL ? IPADD : ALUOUTA;
wire [1:0]MOD = FETCH[1][7:6];
wire [2:0]REG = FETCH[1][5:3];
wire [2:0]RM = FETCH[1][2:0];
241,6 → 250,7
.EXOP(FETCH[1][5:3]),
.FLAGOP(FETCH[0][3:0]),
.ALUOUT(ALUOUT),
.ALUOUTA(ALUOUTA),
.WORD(WORD),
.ALUCONT(ALUCONT),
.NULLSHIFT(NULLSHIFT),
256,7 → 266,6
.BP(NOBP ? 16'h0000 : BP),
.SI(SI),
.DI(DI),
.PIO(FETCH[0][3] ? DX : {8'h00, FETCH[1]}),
.TMP16(TMP16),
.AL(AX[7:0]),
.AIMM(AEXT ? {{8{AIMM1[7]}}, AIMM1[7:0]} : (DISP16 ? AIMM1 : 16'h0000)),
264,7 → 273,8
.EAC(EAC)
);
 
assign DOUT = DOSEL[1] ? DOSEL[0] ? AX : TMP16 : DOSEL[0] ? IPADD : ALUOUT;
assign POUT = DOSEL[0] ? AX : TMP16;
assign DOUT = DOSEL[1] ? POUT : DOSEL[0] ? IPADD : ALUOUT;
assign ADDR = {{NULLSEG ? 16'h0000 : RS} + {5'b00000, ADDR16_SP[15:4]}, ADDR16_SP[3:0]};
assign IADDR = {CS + {5'b00000, IPIN[15:4]}, IPIN[3:0]};
assign AIMM1 = ASEL ? {FETCH[3], FETCH[2]} : {FETCH[2], FETCH[1]};
300,7 → 310,7
CPUStatus[5:0] <= status[5:0];
ICODE1 <= ICODE(INSTR[7:0]);
end else begin // no interrupt, no fetch
STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1;
STAGE <= STAGE + {DIVSTAGE, ALUSTAGE} + 1'b1;
if(&DOSEL) {FETCH[3], FETCH[2]} <= |DISEL ? DIN : RB;
TZF <= FIN[6]; // zero flag for BOUND
TLF <= FIN[7] != FIN[11]; // less flag for BOUND
318,6 → 328,9
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
RCOUT <= COUT;
DIVIRQ <= ~|STAGE[6:3] & DIVC & (~STAGE[2] | (~DIVSGN & IDIV)) & (&STAGE[1:0]); // DIV stage4, div loop
AAMIRQ <= ~|STAGE[6:2] & DIVC & (STAGE[1:0] == 2'b01); // AAM stage2, div
end
 
always @(ISEL, FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5])
343,7 → 356,7
endcase
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, CMPS, SCAS,
always @(FETCH[0], FETCH[1], FETCH[2], FETCH[3], FETCH[4], FETCH[5], MOD, REG, RM, CPUStatus, USEBP, NOBP, RASEL, ISIZEI, TLF, EAC, RCOUT, DIVEND, DIVIRQ, AAMIRQ, QSGN, CMPS, SCAS,
WBIT, ISIZES, ISELS, WRBIT, ISIZEW, STAGE, NULLSHIFT, ALUCONT, FLAGS, CXZ, RCXZ, NRORCXLE1, TZF, JMPC, LOOPC, ICODE1, DIVQSGN, DIVSGN, DIVRSGN, FIN, IDIV, AX) begin
WORD = FETCH[0][0];
BASEL = FETCH[0][1] | &MOD;
365,6 → 378,7
ISIZE = 3'bxxx;
IPWSEL = 1'b1; // IP + ISIZE
IFETCH = 1'b1;
IORQ = 1'b0;
status = 6'b00x0xx;
 
DISP16 = MOD == 2'b10 || NOBP;
427,7 → 441,6
DISEL = 2'b00;
ASEL = 1'b0;
AEXT = 1'b0;
MREQ = 1'b1;
WR = FETCH[0][1];
WE[1:0] = WRBIT; // IP, RASEL_HI/RASEL_LO
ISIZE = 3;
688,8 → 701,9
DISEL = 2'b00; //DIN
MREQ = 1'b0;
ISIZE = FETCH[0][3] ? 1 : 2;
EAC = 4'b1111;
NULLSEG = 1'b1;
IORQ = 1'b1;
// EAC = 4'b1111;
// NULLSEG = 1'b1;
end
// -------------------------------- out --------------------------------
16: begin
697,8 → 711,9
MREQ = 1'b0;
WR = 1'b1;
ISIZE = FETCH[0][3] ? 1 : 2;
EAC = 4'b1111;
NULLSEG = 1'b1;
IORQ = 1'b1;
// EAC = 4'b1111;
// NULLSEG = 1'b1;
end
// -------------------------------- xlat --------------------------------
17: begin
901,6 → 916,8
DOSEL = 2'b11;
IFETCH = 1'b0;
DIVSTAGE = ~QSGN;
RASEL = 3'b000; // AX
ALUOP = 5'b01001; // DEC
end
3'b001: begin // stage2, pre dec AX
// WORD = 1'b1;
908,7 → 925,7
WE[1:0] = 2'b11; // RASEL_HI, RASEL_LO
ALUOP = 5'b01001; // DEC
IFETCH = 1'b0;
ALUSTAGE = ~(DIVQSGN && FETCH[0][0] && COUT);
ALUSTAGE = ~(DIVQSGN && FETCH[0][0] && RCOUT);
end
3'b010: begin // stage3, pre dec DX
RASEL = 3'b010; // DX
925,9 → 942,8
DIVSTAGE = ~DIVEND;
ALUSTAGE = ~DIVEND | ~DIVQSGN;
DIVOP = 1'b1;
// IRQ = ~|STAGE[6:3] & DIVC & ~(STAGE[2] & DIVSGN); - DIV bug, fixed 23Dec2012
IRQ = ~|STAGE[6:3] & DIVC & (~STAGE[2] | (~DIVSGN & IDIV)); // early overflow for positive quotient
IFETCH = (DIVEND && ~DIVQSGN && ~DIVRSGN) || IRQ;
IRQ = DIVIRQ; //~|STAGE[6:3] & DIVC & (~STAGE[2] | (~DIVSGN & IDIV)); // early overflow for positive quotient
IFETCH = (DIVEND && ~DIVQSGN && ~DIVRSGN) || DIVIRQ;
end
3'b100: begin // stage5, post inc R
RASEL = WORD ? 3'b010 : 3'b100; // DX/AH
1191,8 → 1207,9
DISEL = 2'b00; //DIN
IFETCH = RCXZ; // REP & CX==0
MREQ = 1'b0;
EAC = {~RCXZ, 3'b111};
NULLSEG = 1'b1;
IORQ = ~RCXZ;
// EAC = {~RCXZ, 3'b111};
// NULLSEG = 1'b1;
end else begin // stage2, write TMP16 in ES:[DI], inc/dec DI, dec CX
RASEL = 3'b111; // DI
RSSEL = 2'b00; // ES
1225,12 → 1242,13
end else begin // stage2, out TMP16 at port DX, dec CX
DOSEL = 2'b10; // TMP16
MREQ = 1'b0;
EAC = 4'b1111;
IORQ = 1'b1;
// EAC = 4'b1111;
WR = 1'b1;
IFETCH = NRORCXLE1; // not REP or CX<=1
DECCX = CPUStatus[4];
REPINT = 1'b1;
NULLSEG = 1'b1;
// NULLSEG = 1'b1;
end
ISIZE = IFETCH ? 1 : 0;
end
1526,8 → 1544,8
DIVSTAGE = ~DIVEND;
ALUSTAGE = ~DIVEND;
DIVOP = 1'b1;
IRQ = ~|STAGE[6:2] & DIVC;
IFETCH = IRQ;
IRQ = AAMIRQ;//~|STAGE[6:2] & DIVC;
IFETCH = AAMIRQ;
end
3'b110: begin // stage 3, AH <- AL, TMP16 <- AH
RASEL = 3'b100; // AH
1627,8 → 1645,17
MREQ = 1'b0;
ISIZE = 0;
IRQ = 1'b1;
end
+// -------------------------------- SALC -------------------------------- + 55: begin + RASEL = 3'b000; // dest AL (WORD is default 0) + BASEL = 1'b0; + BBSEL = 2'b00; + ALUOP = 3; // sbb + MREQ = 1'b0; + WE[0] = 1'b1; // RASEL_LO + ISIZE = 1; + end // -------------------------------- bad opcode/esc -------------------------------- default: begin MREQ = 1'b0; @@ -1793,8 +1820,10 @@ 8'b11010100: ICODE = 53; // -------------------------------- reset, irq, nmi, intr -------------------------------- 8'b00001111: ICODE = 54; -// -------------------------------- bad opcode/esc -------------------------------- - default: ICODE = 55; +// -------------------------------- SALC -------------------------------- + 8'b11010110: ICODE = 55; +// -------------------------------- bad opcode/esc -------------------------------- + default: ICODE = 56; endcase end endfunction
/trunk/Next186_Regs.v
132,12 → 132,7
7: REG_BSEL = DI;
endcase
end
/*
BUFG BUFG_inst (
.O(CLKD), // Clock buffer output
.I(CLK) // Clock buffer input
);
*/
 
always @(posedge CLK)
if(CLKEN) begin
if(WE[0] && ASEL == 0) AX[7:0] <= FDRW[7:0];

powered by: WebSVN 2.1.0

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