Warp-SE/cpld/IOBS.v

144 lines
3.9 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 */
input BACT,
2023-03-30 15:50:05 +00:00
/* Select signals */
input IOCS, input IOPWCS, input ROMCS,
/* FSB cycle termination outputs */
output IOBS_Ready, output reg nBERR_FSB,
2021-10-29 10:04:59 +00:00
/* Read data OE control */
output nDinOE,
/* IOB Master Controller Interface */
output reg IOREQ, input IOACT, input IOBERR,
/* FIFO primary level control */
output reg ALE0, output reg IORW0, output reg IOL0, output reg IOU0,
/* FIFO secondary level control */
output reg ALE1);
/* IOACT input synchronization */
reg IOACTr = 0;
always @(posedge CLK) begin IOACTr <= IOACT; end
/* Read data OE control */
2023-03-30 15:50:05 +00:00
assign nDinOE = !(!nAS && IOCS && nWE && !ROMCS);
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-03-31 10:17:08 +00:00
* transitions to TS3 when BACT && IOCS && !ALE1 && !Sent true
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 second level control */
reg Load1;
2021-11-22 13:28:06 +00:00
reg Clear1;
2021-10-29 10:04:59 +00:00
reg IORW1;
reg IOL1;
reg IOU1;
always @(posedge CLK) begin
2023-03-30 15:50:05 +00:00
// If write currently posting (TS!=0),
// I/O selected, and FIFO secondary level empty
2023-03-31 10:17:08 +00:00
if (TS!=0 && BACT && IOCS && !ALE1 && !Sent && IOPWCS) begin
2023-03-30 15:50:05 +00:00
// Latch R/W now but latch address and LDS/UDS next cycle
2021-10-29 10:04:59 +00:00
IORW1 <= nWE;
Load1 <= 1;
2021-11-22 13:28:06 +00:00
end else Load1 <= 0;
end
always @(posedge CLK) begin
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)
if (TS==3) Clear1 <= 1;
2021-11-22 13:28:06 +00:00
else Clear1 <= 0;
end
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
if (Load1) begin
2023-03-30 15:50:05 +00:00
// Latch address, LDS, UDS when Load1 true
ALE0 <= 1;
2021-10-29 10:04:59 +00:00
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 */
always @(posedge CLK) begin
2023-03-30 15:50:05 +00:00
if (TS==0) begin
if (ALE1) begin // If FIFO secondary level occupied
// Request transfer from IOBM and latch R/W from FIFO
TS <= 3;
2021-10-29 10:04:59 +00:00
IOREQ <= 1;
IORW0 <= IORW1;
2023-03-31 10:17:08 +00:00
end else if (BACT && IOCS && !ALE1 && !Sent) begin // If I/O selected and FIFO empty
2023-03-30 15:50:05 +00:00
// Request transfer from IOBM and latch R/W from FSB
TS <= 3;
2021-10-29 10:04:59 +00:00
IOREQ <= 1;
IORW0 <= nWE;
2023-03-30 15:50:05 +00:00
end else begin // Otherwise stay in idle
TS <= 0;
2021-10-29 10:04:59 +00:00
IOREQ <= 0;
end
ALE0 <= 0;
2023-03-30 15:50:05 +00:00
end else if (TS==3) begin
// Always go to TS2. Keep IOREQ active
TS <= 2;
2021-10-29 10:04:59 +00:00
IOREQ <= 1;
2023-03-30 15:50:05 +00:00
// Latch address (and data)
2021-10-29 10:04:59 +00:00
ALE0 <= 1;
2023-03-30 15:50:05 +00:00
// Latch data strobes 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;
end
2023-03-30 15:50:05 +00:00
end else if (TS==2) begin
// Wait for IOACT then withdraw IOREQ and enter TS1
2021-10-29 10:04:59 +00:00
if (IOACTr) begin
2023-03-30 15:50:05 +00:00
TS <= 1;
2021-10-29 10:04:59 +00:00
IOREQ <= 0;
end else begin
2023-03-30 15:50:05 +00:00
TS <= 2;
2021-10-29 10:04:59 +00:00
IOREQ <= 1;
end
2023-03-30 15:50:05 +00:00
ALE0 <= 1;
end else if (TS==1) begin
// Wait for IOACT low (transfer over) before going back to idle
if (~IOACTr) TS <= 0;
2023-03-31 10:14:53 +00:00
else TS <= 1;
2021-10-29 10:04:59 +00:00
IOREQ <= 0;
2023-03-30 15:50:05 +00:00
// Address latch released since it's controlled by IOBM now
2021-10-29 10:04:59 +00:00
ALE0 <= 0;
end
end
2023-03-31 10:17:08 +00:00
/* Sent, ready, BERR control */
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
2023-03-31 10:17:08 +00:00
if (~BACT) Sent <= 0;
else if (BACT && IOCS && !ALE1 && !Sent && (TS==0 || IOPWCS)) Sent <= 1;
2021-10-29 10:04:59 +00:00
end
always @(posedge CLK) begin
if (~BACT) begin
2023-03-30 15:50:05 +00:00
// Deassert IOReady and /BERR when bus inactive
2021-10-29 10:04:59 +00:00
IOReady <= 0;
2023-03-22 01:11:58 +00:00
nBERR_FSB <= 1;
2023-03-31 10:17:08 +00:00
end else if (BACT && IOCS && !IOPWCS && !ALE1 && Sent &&
(TS==0 || (TS==1 && !IOACTr))) begin
2023-03-30 15:50:05 +00:00
// If transaction submitted, FIFO second level empty,
// and in or entering TS0, all transactions including
// current are complete. So terminate cycle.
2023-03-22 01:11:58 +00:00
IOReady <= !IOBERR;
nBERR_FSB <= !IOBERR;
2021-10-29 10:04:59 +00:00
end
end
2023-03-31 10:14:53 +00:00
assign IOBS_Ready = !IOCS || ((IOReady) || (IOPWCS && !ALE1));
2021-10-29 10:04:59 +00:00
endmodule