Warp-SE/cpld/IOBS.v

152 lines
4.5 KiB
Coq
Raw Normal View History

2021-10-29 10:04:59 +00:00
module IOBS(
/* MC68HC000 interface */
input CLK, input nWE, input nAS, input nLDS, input nUDS,
/* AS cycle detection */
2024-10-03 15:31:14 +00:00
input BACT, input BACTr,
2023-03-30 15:50:05 +00:00
/* Select signals */
input IOCS, input IORealCS, input IOPWCS,
2024-10-20 23:51:05 +00:00
/* I/O wait state input */
input IOWS,
/* Slowdown write gate configutation */
input SlowdownIOWriteGate,
2023-03-30 15:50:05 +00:00
/* FSB cycle termination outputs */
output reg IONPReady, output IOPWReady, output reg nBERR_FSB,
2021-10-29 10:04:59 +00:00
/* Read data OE control */
output nDinOE,
/* IOB master controller interface */
2024-10-03 15:48:59 +00:00
output reg IOREQ, output reg IORW,
2024-10-07 05:37:58 +00:00
input IOACT, input IODONEin, input nBERR_IOB,
2021-10-29 10:04:59 +00:00
/* FIFO primary level control */
output reg ALE0, output reg IOL0, output reg IOU0,
2021-10-29 10:04:59 +00:00
/* FIFO secondary level control */
output reg ALE1);
/* IOACT input synchronization */
reg IOACTr = 0; always @(posedge CLK) IOACTr <= IOACT;
2024-10-20 23:51:05 +00:00
/* IODONE input synchronization */
2024-10-07 10:09:43 +00:00
reg IODONErf; always @(negedge CLK) IODONErf <= IODONEin;
2024-10-20 23:51:05 +00:00
reg IODONErr; always @(posedge CLK) IODONErr <= IODONErf;
reg [1:0] IODONEr;
2024-10-20 23:51:05 +00:00
always @(posedge CLK) IODONEr[1:0] <= !IOWS ?
{ IODONEr[0], IODONErf } : // 0 I/O wait states
{ IODONEr[0], IODONErr }; // 1 I/O wait state
2021-10-29 10:04:59 +00:00
/* Read data OE control */
2024-10-03 15:31:14 +00:00
assign nDinOE = !(!nAS && BACTr && IORealCS && nWE);
2021-10-29 10:04:59 +00:00
2023-03-30 15:50:05 +00:00
/* I/O transfer state
* TS0 - I/O bridge idle:
* asserts IOREQ
2023-04-01 08:46:47 +00:00
* transitions to TS3 when BACT && IOCS && !ALE1 && !Sent
2023-03-30 15:50:05 +00:00
* TS3 - starting I/O transfer:
latches LDS and UDS from FSB or FIFO secondary level
transitions immediately to TS2
* TS2 - waiting for IOBM to begin:
transitions to TS1 when IOACT true
* TS1 - waiting for IOBM to finish:
* transitions to TS1 when IOACT false */
reg [1:0] TS = 0;
2023-03-31 10:17:08 +00:00
reg Sent = 0;
2021-10-29 10:04:59 +00:00
/* FIFO secondary level control */
reg Load1; reg Clear1;
reg IORW1; reg IOL1; reg IOU1;
always @(posedge CLK) begin // ALE and R/W load control
2023-03-30 15:50:05 +00:00
// If write currently posting (TS!=0),
// I/O selected, and FIFO secondary level empty
if (BACT && IOPWCS && !ALE1 && !Sent && TS!=0) begin
2023-03-30 15:50:05 +00:00
// Latch R/W now but latch address and LDS/UDS next cycle
2024-10-20 23:51:05 +00:00
IORW1 <= SlowdownIOWriteGate ? (!IORealCS ? 1 : nWE) : nWE;
2021-10-29 10:04:59 +00:00
Load1 <= 1;
2021-11-22 13:28:06 +00:00
end else Load1 <= 0;
end
always @(posedge CLK) begin // ALE clear control
2023-03-30 15:50:05 +00:00
// Make address latch transparent in cycle after TS3
// (i.e. first TS2 cycle that's not part of current write)
2024-10-03 09:51:10 +00:00
if (TS==3) Clear1 <= 1;
2021-11-22 13:28:06 +00:00
else Clear1 <= 0;
end
always @(posedge CLK) begin // LDS, UDS, ALE control
if (Load1) begin // Latch address, LDS, UDS when Load1 true
2023-04-01 08:46:47 +00:00
ALE1 <= 1;
IOL1 <= !nLDS;
IOU1 <= !nUDS;
2023-03-30 15:50:05 +00:00
end else if (Clear1) ALE1 <= 0;
2021-10-29 10:04:59 +00:00
end
/* FIFO primary level control */
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
2023-03-30 15:50:05 +00:00
if (TS==0) begin
2024-10-03 15:48:59 +00:00
// Start IOREQ if FIFO secondary level occupied or FSB request
if (ALE1 || (BACT && IOCS && !ALE1 && !Sent)) begin
// Request transfer from IOBM
2024-10-03 09:51:10 +00:00
TS <= 3;
2024-10-03 15:48:59 +00:00
IOREQ <= 1;
end else begin // Otherwise stay in idle
TS <= 0;
IOREQ <= 0;
end
// Latch R/W and data strobes from FIFO secondary or FSB
if (ALE1) begin // If FIFO secondary level occupied
IORW <= IORW1;
IOL0 <= IOL1;
IOU0 <= IOU1;
2024-10-03 15:48:59 +00:00
end else begin // FSB request
2024-10-20 23:51:05 +00:00
IORW <= SlowdownIOWriteGate ? (!IORealCS ? 1 : nWE) : nWE;
IOL0 <= !nLDS;
IOU0 <= !nUDS;
2021-10-29 10:04:59 +00:00
end
2024-10-03 15:48:59 +00:00
2021-10-29 10:04:59 +00:00
ALE0 <= 0;
2024-10-03 09:51:10 +00:00
end else if (TS==3) begin
2024-10-03 15:48:59 +00:00
TS <= 2; // Always go to TS2
IOREQ <= 1; // Keep IOREQ active
ALE0 <= 1; // Latch address (and data)
2024-10-03 15:48:59 +00:00
// Latch data strobes again from FIFO or FSB as appropriate
2021-10-29 10:04:59 +00:00
if (ALE1) begin
IOL0 <= IOL1;
IOU0 <= IOU1;
end else begin
IOL0 <= !nLDS;
IOU0 <= !nUDS;
2021-10-29 10:04:59 +00:00
end
2023-03-30 15:50:05 +00:00
end else if (TS==2) begin
2024-10-03 09:51:10 +00:00
// Wait for IOACT then withdraw IOREQ and enter TS1
2021-10-29 10:04:59 +00:00
if (IOACTr) begin
2024-10-03 09:51:10 +00:00
TS <= 1;
2024-10-03 15:48:59 +00:00
IOREQ <= 0;
end else begin
TS <= 2;
IOREQ <= 1;
end
ALE0 <= 1; // Keep address latched
2024-10-03 09:51:10 +00:00
end else if (TS==1) begin
2023-03-30 15:50:05 +00:00
// Wait for IOACT low (transfer over) before going back to idle
if (!IOACTr) TS <= 0;
2024-10-03 09:51:10 +00:00
else TS <= 1;
2024-10-03 15:48:59 +00:00
IOREQ <= 0;
ALE0 <= 0; // Release addr latch since it's controlled by IOBM now
2021-10-29 10:04:59 +00:00
end
end
/* Sent control */
always @(posedge CLK) begin
if (!BACT) Sent <= 0;
else if (BACT && IOCS && !ALE1 && (IOPWCS || TS==0)) Sent <= 1;
end
/* Nonposted and posted ready */
assign IOPWReady = !ALE1 || Sent; // Posted write reaedy
always @(posedge CLK) begin // Nonposted read/write ready
if (!BACT) IONPReady <= 0;
else if (Sent && !IOPWCS && IODONE) IONPReady <= 1;
2021-10-29 10:04:59 +00:00
end
/* BERR control */
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
if (!BACT) nBERR_FSB <= 1;
2024-10-07 05:37:58 +00:00
else if (Sent && IODONE && nBERR_IOB) nBERR_FSB <= 0;
2021-10-29 10:04:59 +00:00
end
endmodule