Warp-SE/cpld/IOBS.v
2023-03-27 10:17:22 -04:00

118 lines
2.5 KiB
Verilog

module IOBS(
/* MC68HC000 interface */
input CLK, input nWE, input nAS, input nLDS, input nUDS,
/* AS cycle detection */
input BACT,
/* Select and ready signals */
input IOCS, input IOPWCS, output IOBS_Ready, output reg nBERR_FSB,
/* 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 */
assign nDinOE = !(!nAS && IOCS && nWE);
/* Posted read/write state */
reg [1:0] PS = 0;
reg Once = 0;
/* FIFO second level control */
reg Load1;
reg Clear1;
reg IORW1;
reg IOL1;
reg IOU1;
always @(posedge CLK) begin
if (PS!=0 && BACT && IOCS && ~Once && ~ALE1) begin
IORW1 <= nWE;
Load1 <= 1;
end else Load1 <= 0;
end
always @(posedge CLK) begin
if (PS==3 && ALE1) Clear1 <= 1;
else Clear1 <= 0;
end
always @(posedge CLK) begin
if (Load1) ALE1 <= 1;
else if (Clear1) ALE1 <= 0;
end
always @(posedge CLK) begin
if (Load1) begin
IOL1 <= ~nLDS;
IOU1 <= ~nUDS;
end
end
/* FIFO Primary Level Control */
always @(posedge CLK) begin
if (PS==0) begin
if (ALE1) begin
PS <= 3;
IOREQ <= 1;
IORW0 <= IORW1;
end else if (BACT && IOCS && ~Once) begin
PS <= 3;
IOREQ <= 1;
IORW0 <= nWE;
end else begin
PS <= 0;
IOREQ <= 0;
end
ALE0 <= 0;
end else if (PS==3) begin
PS <= 2;
IOREQ <= 1;
ALE0 <= 1;
if (ALE1) begin
IOL0 <= IOL1;
IOU0 <= IOU1;
end else begin
IOL0 <= ~nLDS;
IOU0 <= ~nUDS;
end
end else if (PS==2) begin
if (IOACTr) begin
PS <= 1;
IOREQ <= 0;
end else begin
PS <= 2;
IOREQ <= 1;
end
ALE0 <= 0;
end else if (PS==1) begin
if (~IOACTr) PS <= 0;
else PS <= 2;
IOREQ <= 0;
ALE0 <= 0;
end
end
/* Once, ready, BERR control */
reg IOReady;
wire IOPWReady = ~ALE1;
always @(posedge CLK) begin
if (~BACT) Once <= 0;
else if (IOCS && (PS==0 || (IOPWCS && IOPWReady))) Once <= 1;
end
always @(posedge CLK) begin
if (~BACT) begin
IOReady <= 0;
nBERR_FSB <= 1;
end else if (Once && (PS==0 || PS==1) && ~IOACTr && IOPWReady) begin
IOReady <= !IOBERR;
nBERR_FSB <= !IOBERR;
end
end
assign IOBS_Ready = ~IOCS || IOReady || (IOPWCS && IOPWReady);
endmodule