diff --git a/cpld/CNT.v b/cpld/CNT.v index 1e48f5c..445dade 100644 --- a/cpld/CNT.v +++ b/cpld/CNT.v @@ -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 diff --git a/cpld/CS.v b/cpld/CS.v index 549a4a1..b6707d4 100644 --- a/cpld/CS.v +++ b/cpld/CS.v @@ -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 diff --git a/cpld/FSB.v b/cpld/FSB.v index d932e5b..510b1f5 100644 --- a/cpld/FSB.v +++ b/cpld/FSB.v @@ -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; diff --git a/cpld/WarpSE.v b/cpld/WarpSE.v index d00d65c..20ae80e 100644 --- a/cpld/WarpSE.v +++ b/cpld/WarpSE.v @@ -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