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( module CNT(
/* FSB clock and E clock inputs */ /* FSB clock and E clock inputs */
input CLK, input E, input CLK, input C8M, input E,
/* Refresh request */ /* Refresh request */
output reg RefReq, output reg RefUrg, output reg RefReq, output reg RefUrg,
/* Reset, button */ /* Reset, button */
output reg nRESout, input nRESin, input nIPL2, output reg nRESout, input nRESin, input nIPL2,
/* Mac PDS bus master control outputs */ /* Mac PDS bus master control outputs */
output reg AoutOE, output reg nBR_IOB, output reg AoutOE, output reg nBR_IOB,
/* QoS control */ /* QoS select inputs */
input BACT, input BACT,
input QoSCS, input QoSCS,
output reg QoSEN); input SndQoSCS,
/* QoS outputs */
output reg QoSEN,
output reg SndQoSReady);
/* E clock synchronization */ /* E clock synchronization */
reg [1:0] Er; always @(posedge CLK) Er[1:0] <= { Er[0], E }; reg [1:0] Er; always @(posedge CLK) Er[1:0] <= { Er[0], E };
wire EFall = Er[1] && !Er[0]; 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 */ /* NMI and reset synchronization */
reg nIPL2r; always @(posedge CLK) nIPL2r <= nIPL2; reg nIPL2r; always @(posedge CLK) nIPL2r <= nIPL2;
reg nRESr; always @(posedge CLK) nRESr <= nRESin; 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 /* Timer counts from 0 to 1010 (10) -- 11 states == 14.042 us
* Refresh timer sequence * Refresh timer sequence
* | Timer | RefReq | RefUrg | * | Timer | RefReq | RefUrg |
@ -41,68 +44,105 @@ module CNT(
* back to timer==0 * back to timer==0
*/ */
reg [3:0] Timer = 0; reg [3:0] Timer = 0;
reg TimerTC; wire TimerTC = Timer==10;
reg TimerTick;
always @(posedge CLK) begin always @(posedge CLK) begin
if (EFall) begin if (EFall) begin
if (TimerTC) Timer <= 0; if (TimerTC) Timer <= 0;
else Timer <= Timer+1; else Timer <= Timer+1;
RefUrg <= Timer==8 || Timer==9; RefUrg <= Timer==8 || Timer==9;
RefReq <= Timer!=10; 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
end end
always @(posedge CLK) TimerTick <= EFall && TimerTC;
/* QoS select latch */ /* QoS select latch */
reg QoSCSr; reg QoSCSr;
always @(posedge CLK) if (BACT) QoSCSr <= QoSCS; always @(posedge CLK) QoSCSr <= (BACT && (QoSCS || SndQoSCS)) || !nRESr;
/* QoS timer /* QoS timer
* In the absence of a QoS trigger, QS==0. * In the absence of a QoS trigger, QS==0.
* When Qos triggered, QS is set to 1 and counts 1, 2, 3, 0. * When Qos triggered, QS is set to 1 and counts 1, 2, 3, 0.
* While QS!=0, QoS is enabled. * While QS!=0, QoS is enabled.
* QoS enable period is 28.124 us - 42.240 us */ * QoS enable period is 28.124 us - 42.240 us */
reg [1:0] QS; reg [3:0] QS;
always @(posedge CLK) begin always @(posedge CLK) begin
if (!nRESr || QoSCSr) QS[1:0] <= 1; if (QoSCSr) QS <= 15;
else if (QS==0) QS[1:0] <= 0; else if (QS==0) QS <= 0;
else if (EFall && TimerTC) QS[1:0] <= QS+1; else if (TimerTick) QS <= QS-1;
end end
/* QoS enable control */ /* 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 */ /* 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 always @(posedge CLK) begin
case (IS[1:0]) case (IS[1:0])
0: begin 0, 1: begin
AoutOE <= 0; // Tristate PDS address and control AoutOE <= 0; // Tristate PDS address and control
nRESout <= 0; // Hold reset low nRESout <= 0; // Hold reset low
nBR_IOB <= 0; // Default to request bus nBR_IOB <= 0; // Default to request bus
if (ISTC) IS <= 1; end 2: begin
end 1: begin
AoutOE <= 0; AoutOE <= 0;
nRESout <= 0; nRESout <= 0;
nBR_IOB <= !(!nBR_IOB && nIPL2r); // Disable bus request if NMI pressed if (!nIPL2r) nBR_IOB <= 1; // Disable bus request if NMI pressed
if (ISTC && nIPL2r) IS <= 2;
end 2: begin
AoutOE <= !nBR_IOB;
nRESout <= 0;
if (ISTC) IS <= 3;
end 3: begin end 3: begin
nRESout <= 1; // Release reset AoutOE <= !nBR_IOB;
IS <= 3; if (LTimerTick) nRESout <= 1; // Release reset after a while
end end
endcase endcase
end end

View File

@ -8,7 +8,8 @@ module CS(
/* Device select outputs */ /* Device select outputs */
output IOCS, output IORealCS, output IOPWCS, output IACS, output IOCS, output IORealCS, output IOPWCS, output IACS,
output ROMCS, output ROMCS4X, output ROMCS, output ROMCS4X,
output RAMCS, output RAMCS0X, output QoSCS); output RAMCS, output RAMCS0X,
output QoSCS, output SndQoSCS);
/* Overlay control */ /* Overlay control */
reg Overlay; 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'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))); ((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 QoSCS = IACKCS || VIACS || IWMCS || SCCCS || SCSICS || SndRAMCSWR;
assign SndQoSCS = SndRAMCSWR;
/* Select signals - IOB domain */ /* Select signals - IOB domain */
assign IACS = A[23:20]==4'hF; // IACK assign IACS = A[23:20]==4'hF; // IACK

View File

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

View File

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