Warp-SE/cpld/CNT.v

151 lines
4.0 KiB
Coq
Raw Normal View History

2021-10-29 10:04:59 +00:00
module CNT(
/* FSB clock and E clock inputs */
2024-10-03 11:59:29 +00:00
input CLK, input C8M, input E,
2021-10-29 10:04:59 +00:00
/* Refresh request */
output reg RefReq, output reg RefUrg,
2023-03-26 08:33:59 +00:00
/* Reset, button */
output reg nRESout, input nRESin, input nIPL2,
2023-03-20 04:53:10 +00:00
/* Mac PDS bus master control outputs */
2023-04-08 09:46:13 +00:00
output reg AoutOE, output reg nBR_IOB,
2024-10-03 11:59:29 +00:00
/* QoS select inputs */
2024-09-06 10:05:06 +00:00
input BACT,
2024-10-03 09:51:10 +00:00
input QoSCS,
2024-10-03 11:59:29 +00:00
input SndQoSCS,
/* QoS outputs */
output reg QoSEN,
output reg SndQoSReady);
2023-03-26 08:33:59 +00:00
/* E clock synchronization */
reg [1:0] Er; always @(posedge CLK) Er[1:0] <= { Er[0], E };
2023-03-26 08:33:59 +00:00
wire EFall = Er[1] && !Er[0];
2024-10-03 11:59:29 +00:00
/* C8M clock synchronization */
reg [3:0] C8Mr; always @(posedge CLK) C8Mr[3:0] <= { C8Mr[2:0], C8M };
/* NMI and reset synchronization */
2023-04-08 09:46:13 +00:00
reg nIPL2r; always @(posedge CLK) nIPL2r <= nIPL2;
reg nRESr; always @(posedge CLK) nRESr <= nRESin;
2023-04-08 09:49:29 +00:00
/* Timer counts from 0 to 1010 (10) -- 11 states == 14.042 us
2023-03-22 01:11:58 +00:00
* Refresh timer sequence
2023-04-08 08:08:53 +00:00
* | Timer | RefReq | RefUrg |
* |---------|--------|-----------|
2023-03-22 01:11:58 +00:00
* | 0 0000 | 0 | 0 |
2023-04-08 08:08:53 +00:00
* | 1 0001 | 1 | 0 |
2023-03-26 08:33:59 +00:00
* | 2 0010 | 1 | 0 |
2023-03-22 01:11:58 +00:00
* | 3 0011 | 1 | 0 |
* | 4 0100 | 1 | 0 |
* | 5 0101 | 1 | 0 |
* | 6 0110 | 1 | 0 |
* | 7 0111 | 1 | 0 |
2023-04-08 08:08:53 +00:00
* | 8 1000 | 1 | 0 |
* | 9 1001 | 1 | 1 |
* | 10 1010 | 1 | 1 |
2023-03-20 04:53:10 +00:00
* back to timer==0
2022-09-04 01:32:05 +00:00
*/
2023-03-22 01:11:58 +00:00
reg [3:0] Timer = 0;
2024-10-03 11:59:29 +00:00
wire TimerTC = Timer==10;
reg TimerTick;
2023-03-26 08:33:59 +00:00
always @(posedge CLK) begin
if (EFall) begin
if (TimerTC) Timer <= 0;
else Timer <= Timer+1;
RefUrg <= Timer==8 || Timer==9;
RefReq <= Timer!=10;
2024-10-03 09:51:10 +00:00
end
end
2024-10-03 11:59:29 +00:00
always @(posedge CLK) TimerTick <= EFall && TimerTC;
2024-10-03 09:51:10 +00:00
/* QoS select latch */
reg QoSCSr;
2024-10-03 11:59:29 +00:00
always @(posedge CLK) QoSCSr <= (BACT && (QoSCS || SndQoSCS)) || !nRESr;
2024-10-03 09:51:10 +00:00
/* 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 */
2024-10-03 11:59:29 +00:00
reg [3:0] QS;
2023-04-08 09:46:13 +00:00
always @(posedge CLK) begin
2024-10-03 11:59:29 +00:00
if (QoSCSr) QS <= 15;
else if (QS==0) QS <= 0;
else if (TimerTick) QS <= QS-1;
end
2024-10-03 09:51:10 +00:00
/* QoS enable control */
2024-10-03 11:59:29 +00:00
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
2024-09-29 07:29:49 +00:00
2023-04-08 09:49:29 +00:00
/* Startup sequence state control */
2024-10-03 11:59:29 +00:00
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 */
2023-03-26 08:33:59 +00:00
always @(posedge CLK) begin
2023-04-08 09:46:13 +00:00
case (IS[1:0])
2024-10-03 11:59:29 +00:00
0, 1: begin
2023-03-20 04:53:10 +00:00
AoutOE <= 0; // Tristate PDS address and control
nRESout <= 0; // Hold reset low
2023-03-22 01:11:58 +00:00
nBR_IOB <= 0; // Default to request bus
2023-04-10 02:47:27 +00:00
end 2: begin
2024-10-03 11:59:29 +00:00
AoutOE <= 0;
2023-03-26 08:33:59 +00:00
nRESout <= 0;
2024-10-03 11:59:29 +00:00
if (!nIPL2r) nBR_IOB <= 1; // Disable bus request if NMI pressed
2023-04-10 02:47:27 +00:00
end 3: begin
2024-10-03 11:59:29 +00:00
AoutOE <= !nBR_IOB;
if (LTimerTick) nRESout <= 1; // Release reset after a while
2022-09-04 01:32:05 +00:00
end
2022-09-11 21:15:53 +00:00
endcase
end
2024-10-03 09:51:10 +00:00
2021-10-29 10:04:59 +00:00
endmodule