URL
https://opencores.org/ocsvn/next186/next186/trunk
Subversion Repositories next186
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 19 to Rev 20
- ↔ Reverse comparison
Rev 19 → Rev 20
/next186/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 |
/next186/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 |
/next186/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
+// -------------------------------- 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
MREQ = 1'b0; |
ISIZE = 0; |
IRQ = 1'b1; |
end |
|
/next186/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]; |