Redo timers, init, QoS

This commit is contained in:
Zane Kaminski 2024-10-03 07:59:29 -04:00
parent 5e958a385b
commit 3b97a15817
4 changed files with 207 additions and 91 deletions

View File

@ -1,28 +1,31 @@
module CNT(
/* FSB clock and E clock inputs */
input CLK, input E,
input CLK, input C8M, input E,
/* Refresh request */
output reg RefReq, output reg RefUrg,
/* Reset, button */
output reg nRESout, input nRESin, input nIPL2,
/* Mac PDS bus master control outputs */
output reg AoutOE, output reg nBR_IOB,
/* QoS control */
/* QoS select inputs */
input BACT,
input QoSCS,
output reg QoSEN);
input SndQoSCS,
/* QoS outputs */
output reg QoSEN,
output reg SndQoSReady);
/* E clock synchronization */
reg [1:0] Er; always @(posedge CLK) Er[1:0] <= { Er[0], E };
wire EFall = Er[1] && !Er[0];
/* C8M clock synchronization */
reg [3:0] C8Mr; always @(posedge CLK) C8Mr[3:0] <= { C8Mr[2:0], C8M };
/* NMI and reset synchronization */
reg nIPL2r; always @(posedge CLK) nIPL2r <= nIPL2;
reg nRESr; always @(posedge CLK) nRESr <= nRESin;
/* Startup sequence state */
reg [1:0] IS = 0;
/* Timer counts from 0 to 1010 (10) -- 11 states == 14.042 us
* Refresh timer sequence
* | Timer | RefReq | RefUrg |
@ -41,68 +44,105 @@ module CNT(
* back to timer==0
*/
reg [3:0] Timer = 0;
reg TimerTC;
wire TimerTC = Timer==10;
reg TimerTick;
always @(posedge CLK) begin
if (EFall) begin
if (TimerTC) Timer <= 0;
else Timer <= Timer+1;
RefUrg <= Timer==8 || Timer==9;
RefReq <= Timer!=10;
TimerTC <= Timer==9;
end
end
/* During init (IS!=3) long timer counts from 0 to 4095.
* 4096 states == 57.516 ms */
reg [11:0] LTimer;
reg LTimerTC;
always @(posedge CLK) begin
if (EFall && TimerTC) begin
LTimer <= LTimer+1;
LTimerTC <= LTimer[11:0]==12'hFFE;
end
end
always @(posedge CLK) TimerTick <= EFall && TimerTC;
/* QoS select latch */
reg QoSCSr;
always @(posedge CLK) if (BACT) QoSCSr <= QoSCS;
always @(posedge CLK) QoSCSr <= (BACT && (QoSCS || SndQoSCS)) || !nRESr;
/* QoS timer
* In the absence of a QoS trigger, QS==0.
* When Qos triggered, QS is set to 1 and counts 1, 2, 3, 0.
* While QS!=0, QoS is enabled.
* QoS enable period is 28.124 us - 42.240 us */
reg [1:0] QS;
reg [3:0] QS;
always @(posedge CLK) begin
if (!nRESr || QoSCSr) QS[1:0] <= 1;
else if (QS==0) QS[1:0] <= 0;
else if (EFall && TimerTC) QS[1:0] <= QS+1;
if (QoSCSr) QS <= 15;
else if (QS==0) QS <= 0;
else if (TimerTick) QS <= QS-1;
end
/* QoS enable control */
always @(posedge CLK) if (!BACT) QoSEN <= QoSCSr || QS!=0;
always @(posedge CLK) if (!BACT) QoSEN <= QS!=0;
/* Sound QoS select latch */
reg SndQoSCSr;
always @(posedge CLK) SndQoSCSr <= BACT && SndQoSCS;
/* Sound QoS timer */
reg [1:0] SndQS;
always @(posedge CLK) begin
if (SndQoSCSr) SndQS <= 3;
else if (QoSCSr) SndQS <= 0;
else if (SndQS==0) SndQS <= 0;
else if (TimerTick) SndQS <= SndQS-1;
end
/* Wait state timer */
reg [3:0] Wait;
always @(posedge CLK) begin
if (!BACT) Wait <= 0;
else Wait <= Wait+1;
end
/* Sound QoS ready control */
always @(posedge CLK) begin
if (!BACT) SndQoSReady <= SndQS==0;
else if (QoSCSr && !SndQoSCSr) SndQoSReady <= 1;
else if (Wait==15) SndQoSReady <= 1;
end
/* Long timer counts from 0 to 4095.
* 4096 states == 57.516 ms */
reg [11:0] LTimer;
wire LTimerTC = LTimer[11:0]==12'hFFF;
reg LTimerTick;
always @(posedge CLK) if (TimerTick) LTimer <= LTimer+1;
always @(posedge CLK) LTimerTick <= TimerTick && LTimerTC;
/* C8M duty cycle check and power-on reset */
reg nPOR = 0;
always @(posedge CLK) begin
if (C8Mr[3:0]==4'b0000 || C8Mr[3:0]==4'b1111) nPOR <= 0;
else if (C8Mr[1:0]==2'b01) nPOR <= 1;
end
/* Startup sequence state control */
wire ISTC = EFall && TimerTC && LTimerTC;
reg [1:0] IS = 0;
always @(posedge CLK) begin
if (nPOR) IS <= 0;
else case (IS[1:0])
0: if (LTimerTick) IS <= 1;
1: if (LTimerTick) IS <= 2;
2: if (LTimerTick && nIPL2r) IS <= 3;
3: IS <= 3;
endcase
end
/* Startup sequence */
always @(posedge CLK) begin
case (IS[1:0])
0: begin
0, 1: begin
AoutOE <= 0; // Tristate PDS address and control
nRESout <= 0; // Hold reset low
nBR_IOB <= 0; // Default to request bus
if (ISTC) IS <= 1;
end 1: begin
end 2: begin
AoutOE <= 0;
nRESout <= 0;
nBR_IOB <= !(!nBR_IOB && nIPL2r); // Disable bus request if NMI pressed
if (ISTC && nIPL2r) IS <= 2;
end 2: begin
AoutOE <= !nBR_IOB;
nRESout <= 0;
if (ISTC) IS <= 3;
if (!nIPL2r) nBR_IOB <= 1; // Disable bus request if NMI pressed
end 3: begin
nRESout <= 1; // Release reset
IS <= 3;
AoutOE <= !nBR_IOB;
if (LTimerTick) nRESout <= 1; // Release reset after a while
end
endcase
end

View File

@ -8,7 +8,8 @@ module CS(
/* Device select outputs */
output IOCS, output IORealCS, output IOPWCS, output IACS,
output ROMCS, output ROMCS4X,
output RAMCS, output RAMCS0X, output QoSCS);
output RAMCS, output RAMCS0X,
output QoSCS, output SndQoSCS);
/* Overlay control */
reg Overlay;
@ -49,6 +50,7 @@ module CS(
((A[15:12]==4'hF) && (A[11:8]==4'hD || A[11:8]==4'hE || A[11:8]==4'hF)) ||
((A[15:12]==4'hA) && (A[11:8]==4'h1 || A[11:8]==4'h2 || A[11:8]==4'h3)));
assign QoSCS = IACKCS || VIACS || IWMCS || SCCCS || SCSICS || SndRAMCSWR;
assign SndQoSCS = SndRAMCSWR;
/* Select signals - IOB domain */
assign IACS = A[23:20]==4'hF; // IACK

View File

@ -7,7 +7,7 @@ module FSB(
input ROMCS,
input RAMCS, input RAMReady,
input IOPWCS, input IOPWReady, input IONPReady,
input QoSEN,
input QoSEN, input SndQoSReady,
/* Interrupt acknowledge select */
input IACS);
@ -21,7 +21,7 @@ module FSB(
wire Ready = (RAMCS && !QoSEN && RAMReady && !IOPWCS) ||
(RAMCS && !QoSEN && RAMReady && IOPWCS && IOPWReady) ||
(ROMCS && !QoSEN) ||
(IONPReady);
(IONPReady && SndQoSReady);
always @(posedge FCLK) nDTACK <= !(Ready && BACT && !IACS);
always @(posedge FCLK, posedge nAS) begin
if (nAS) nVPA <= 1;

View File

@ -44,14 +44,14 @@ module WarpSE(
assign MCKE = 1;
/* GA gated (translated) address output */
//assign GA[23:22] = A_FSB[23:22];
assign GA[23:22] = (
assign GA[23:22] = A_FSB[23:22];
/*assign GA[23:22] = (
// $800000-$8FFFFF to $000000-$0FFFFF (1 MB)
(A_FSB[23:20]==4'h8) ||
// $700000-$7EFFFF to $300000-$3EFFFF (960 kB)
(A_FSB[23:20]==4'h7 && A_FSB[19:16]!=4'hF) ||
// $600000-$6FFFFF to $200000-$2FFFFF (1 MB)
(A_FSB[23:20]==4'h6)) ? 2'b00 : A_FSB[23:22];
(A_FSB[23:20]==4'h6)) ? 2'b00 : A_FSB[23:22];*/
/* Reset input and open-drain output */
wire nRESin = nRES;
@ -65,41 +65,65 @@ module WarpSE(
/* Refresh request/ack signals */
wire RefReq, RefUrg;
/* QoS enable */
wire QoSEN;
/* FSB chip select signals */
wire IOCS, IORealCS, IOPWCS, IACS;
wire ROMCS, ROMCS4X;
wire RAMCS, RAMCS0X, QoSCS;
wire RAMCS, RAMCS0X;
wire QoSCS, SndQoSCS;
CS cs(
/* MC68HC000 interface */
A_FSB[23:08], FCLK, nRESin, nWE_FSB,
.A(A_FSB[23:08]),
.CLK(FCLK),
.nRES(nRESin),
.nWE(nWE_FSB),
/* /AS cycle detection */
BACT,
.BACT(BACT),
/* QoS enable input */
QoSEN,
.QoSEN(QoSEN),
/* Device select outputs */
IOCS, IORealCS, IOPWCS, IACS,
ROMCS, ROMCS4X,
RAMCS, RAMCS0X, QoSCS);
.IOCS(IOCS),
.IORealCS(IORealCS),
.IOPWCS(IOPWCS),
.IACS(IACS),
.ROMCS(ROMCS),
.ROMCS4X(ROMCS4X),
.RAMCS(RAMCS),
.RAMCS0X(RAMCS0X),
.QoSCS(QoSCS),
.SndQoSCS(SndQoSCS));
wire RAMReady;
RAM ram(
/* MC68HC000 interface */
FCLK, A_FSB[21:1], nWE_FSB,
nAS_FSB, nLDS_FSB, nUDS_FSB, nDTACK_FSB,
.CLK(FCLK),
.A(A_FSB[21:1]),
.nWE(nWE_FSB),
.nAS(nAS_FSB),
.nLDS(nLDS_FSB),
.nUDS(nUDS_FSB),
.nDTACK(nDTACK_FSB),
/* AS cycle detection inputs */
BACT, BACTr,
.BACT(BACT),
.BACTr(BACTr),
/* RAM and ROM select inputs */
RAMCS, RAMCS0X, ROMCS, ROMCS4X,
.RAMCS(RAMCS),
.RAMCS0X(RAMCS0X),
.ROMCS(ROMCS),
.ROMCS4X(ROMCS4X),
/* RAM ready output */
RAMReady,
.RAMReady(RAMReady),
/* Refresh Counter Interface */
RefReq, RefUrg,
.RefReqIn(RefReq),
.RefUrgIn(RefUrg),
/* DRAM and NOR flash interface */
RA[11:0], nRAS, nCAS,
nRAMLWE, nRAMUWE, nOE, nROMOE, nROMWE);
.RA(RA[11:0]),
.nRAS(nRAS),
.nCAS(nCAS),
.nLWE(nRAMLWE),
.nUWE(nRAMUWE),
.nOE(nOE),
.nROMOE(nROMOE),
.nROMWE(nROMWE));
wire IONPReady, IOPWReady;
wire IORDREQ, IOWRREQ;
@ -110,23 +134,36 @@ module WarpSE(
wire IOACT, IODONE, IOBERR;
IOBS iobs(
/* MC68HC000 interface */
FCLK, nWE_FSB, nAS_FSB, nLDS_FSB, nUDS_FSB,
.CLK(FCLK),
.nWE(nWE_FSB),
.nAS(nAS_FSB),
.nLDS(nLDS_FSB),
.nUDS(nUDS_FSB),
/* AS cycle detection */
BACT,
.BACT(BACT),
/* Select signals */
IOCS, IORealCS, IOPWCS,
.IOCS(IOCS),
.IORealCS(IORealCS),
.IOPWCS(IOPWCS),
/* FSB cycle termination outputs */
IONPReady, IOPWReady, nBERR_FSB,
.IONPReady(IONPReady),
.IOPWReady(IOPWReady),
.nBERR_FSB(nBERR_FSB),
/* Read data OE control */
nDinOE,
.nDinOE(nDinOE),
/* IOB Master Controller Interface */
IORDREQ, IOWRREQ,
IOACT, IODONE, IOBERR,
.IORDREQ(IORDREQ),
.IOWRREQ(IOWRREQ),
.IOACT(IOACT),
.IODONEin(IODONE),
.IOBERR(IOBERR),
/* FIFO primary level control */
ALE0S, IOL0, IOU0,
.ALE0(ALE0S),
.IOL0(IOL0),
.IOU0(IOU0),
/* FIFO secondary level control */
ALE1);
.ALE1(ALE1));
wire AoutOE;
assign nAoutOE = !AoutOE;
wire nAS_IOBout, nLDS_IOBout, nUDS_IOBout, nVMA_IOBout;
@ -136,38 +173,75 @@ module WarpSE(
assign nVMA_IOB = AoutOE ? nVMA_IOBout : 1'bZ;
IOBM iobm(
/* PDS interface */
C16M, C8M, E,
nAS_IOBout, nLDS_IOBout, nUDS_IOBout, nVMA_IOBout,
nDTACK_IOB, nVPA_IOB, nBERR_IOB, nRESin,
.C16M(C16M),
.C8M(C8M),
.E(E),
.nASout(nAS_IOBout),
.nLDS(nLDS_IOBout),
.nUDS(nUDS_IOBout),
.nVMA(nVMA_IOBout),
.nDTACK(nDTACK_IOB),
.nVPA(nVPA_IOB),
.nBERR(nBERR_IOB),
.nRES(nRESin),
/* PDS address and data latch control */
AoutOE, nDoutOE, ALE0M, nDinLE,
.AoutOE(AoutOE),
.nDoutOE(nDoutOE),
.ALE0(ALE0M),
.nDinLE(nDinLE),
/* IO bus slave port interface */
IORDREQ, IOWRREQ, IOL0, IOU0,
IOACT, IODONE, IOBERR);
.IORDREQ(IORDREQ),
.IOWRREQ(IOWRREQ),
.IOLDS(IOL0),
.IOUDS(IOU0),
.IOACT(IOACT),
.IODONE(IODONE),
.IOBERR(IOBERR));
wire QoSEN, SndQoSReady;
CNT cnt(
/* FSB clock and E clock inputs */
FCLK, E,
/* FSB clock, 7.8336 MHz clock, and E clock inputs */
.CLK(FCLK),
.C8M(C8M),
.E(E),
/* Refresh request */
RefReq, RefUrg,
.RefReq(RefReq),
.RefUrg(RefUrg),
/* Reset, button */
nRESout, nRESin, nIPL2,
.nRESout(nRESout),
.nRESin(nRESin),
.nIPL2(nIPL2),
/* Mac PDS bus master control outputs */
AoutOE, nBR_IOB,
/* QoS control */
BACT, QoSCS, QoSEN);
.AoutOE(AoutOE),
.nBR_IOB(nBR_IOB),
/* QoS select inputs */
.BACT(BACT),
.QoSCS(QoSCS),
.SndQoSCS(SndQoSCS),
/* QoS outputs */
.QoSEN(QoSEN),
.SndQoSReady(SndQoSReady));
FSB fsb(
/* MC68HC000 interface */
FCLK, nAS_FSB, nDTACK_FSB, nVPA_FSB,
.FCLK(FCLK),
.nAS(nAS_FSB),
.nDTACK(nDTACK_FSB),
.nVPA(nVPA_FSB),
/* FSB cycle detection */
BACT, BACTr,
.BACT(BACT),
.BACTr(BACTr),
/* Ready inputs */
ROMCS4X,
RAMCS0X, RAMReady,
IOPWCS, IOPWReady, IONPReady,
QoSEN,
.ROMCS(ROMCS4X),
.RAMCS(RAMCS0X),
.RAMReady(RAMReady),
.IOPWCS(IOPWCS),
.IOPWReady(IOPWReady),
.IONPReady(IONPReady),
.QoSEN(QoSEN),
.SndQoSReady(SndQoSReady),
/* Interrupt acknowledge select */
IACS);
.IACS(IACS));
endmodule