Warp-SE/cpld/RAM.v

163 lines
4.2 KiB
Coq
Raw Normal View History

2021-10-29 10:04:59 +00:00
module RAM(
/* MC68HC000 interface */
2023-04-10 23:28:13 +00:00
input CLK, input [21:1] A, input nWE,
input nAS, input nLDS, input nUDS, input nDTACK,
2021-10-29 10:04:59 +00:00
/* AS cycle detection */
input BACT, input BACTr,
2021-10-29 10:04:59 +00:00
/* Select and ready signals */
2024-09-22 01:52:46 +00:00
input RAMCS, input RAMCS0X, input ROMCS, input ROMCS4X,
/* RAM ready output */
output reg RAMReady,
2021-10-29 10:04:59 +00:00
/* Refresh Counter Interface */
input RefReqIn, input RefUrgIn,
2021-10-29 10:04:59 +00:00
/* DRAM and NOR flash interface */
output [11:0] RA, output nRAS, output reg nCAS,
2024-03-29 08:02:32 +00:00
output nLWE, output nUWE, output reg nOE, output nROMOE, output nROMWE);
2023-04-10 23:28:13 +00:00
/* BACT and /DTACK registration */
reg DTACKr; always @(posedge CLK) DTACKr <= !nDTACK;
/* RAM control state */
2023-04-11 00:33:44 +00:00
reg [2:0] RS = 0;
reg RASEN = 0;
reg RASEL = 0;
reg RASrr = 0;
reg RASrf = 0;
/* Refresh command generation */
reg RefDone; // Refresh done "remember"
always @(posedge CLK) begin
if (!RefReqIn && !RefUrgIn) RefDone <= 0;
else if (RS[2]) RefDone <= 1;
end
wire RefReq = RefReqIn && !RefDone;
wire RefUrg = RefUrgIn && !RefDone;
/* RAM control signals */
2023-04-11 00:33:44 +00:00
assign nRAS = !((!nAS && RAMCS && RASEN) || RASrr || RASrf);
assign nLWE = !(!nLDS && !nWE && RASEL);
assign nUWE = !(!nUDS && !nWE && RASEL);
2024-03-29 08:02:32 +00:00
always @(posedge CLK) nOE <= !(BACT && nWE && !(BACTr && DTACKr));
2021-10-29 10:04:59 +00:00
/* ROM control signals */
2024-03-29 08:02:32 +00:00
assign nROMOE = !(ROMCS && !nAS && nWE);
2024-09-22 01:52:46 +00:00
assign nROMWE = !(ROMCS4X && !nAS && !nWE);
2021-10-29 10:04:59 +00:00
2022-09-04 01:32:05 +00:00
/* RAM address mux (and ROM address on RA8) */
// RA11 doesn't do anything so both should be identical.
assign RA[11] = !RASEL ? A[19] : A[20]; // ROM address 19
assign RA[03] = !RASEL ? A[19] : A[20];
// RA10 has only row so different rows but same column.
assign RA[10] = !RASEL ? A[17] : A[07];
assign RA[02] = !RASEL ? A[16] : A[07];
// Remainder of RA bus is unpaired
assign RA[09] = !RASEL ? A[15] : A[08];
assign RA[08] = !RASEL ? A[18] : A[21]; // ROM address 18
assign RA[07] = !RASEL ? A[14] : A[06];
assign RA[06] = !RASEL ? A[13] : A[05];
assign RA[05] = !RASEL ? A[12] : A[04];
assign RA[04] = !RASEL ? A[11] : A[03];
assign RA[01] = !RASEL ? A[10] : A[02];
assign RA[00] = !RASEL ? A[09] : A[01];
2023-04-11 00:33:44 +00:00
2023-04-15 11:12:24 +00:00
wire RS0toRef = // Refresh during first clock of non-RAM access
(RefReq && BACT && !BACTr && !RAMCS0X) ||
2023-04-15 11:12:24 +00:00
// Urgent refresh while bus inactive
(RefUrg && !BACT) ||
// Urgent refresh during non-RAM access
2023-04-11 00:33:44 +00:00
(RefUrg && BACT && !RAMCS0X) ||
2023-04-15 11:12:24 +00:00
// Urgent refresh if RAM is disabled
(RefUrg && !RASEN);
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
2023-04-11 00:33:44 +00:00
case (RS[2:0])
2023-04-10 23:28:13 +00:00
0: begin // Idle/ready
2023-04-15 04:30:11 +00:00
if (RS0toRef) begin // Refresh RAS I
2023-04-11 00:33:44 +00:00
RS <= 4;
RASEL <= 0;
2023-04-15 04:30:11 +00:00
RASrr <= 1;
RASEN <= 0;
RAMReady <= 0;
2023-04-10 23:28:13 +00:00
end else if (BACT && RAMCS && RASEN) begin // Access RAM
RS <= 1;
RASEL <= 1;
RASrr <= 1;
RASEN <= 1;
RAMReady <= 1;
2023-04-10 23:28:13 +00:00
end else begin // Stay in idle/ready
RS <= 0;
RASEL <= 0;
RASrr <= 0;
RASEN <= 1;
RAMReady <= 1;
end
2023-04-10 23:28:13 +00:00
end 1: begin // RAM access
2021-10-29 10:04:59 +00:00
RS <= 2;
RASEL <= 1;
RASrr <= 0;
RASEN <= 0;
RAMReady <= 1;
2023-04-10 23:28:13 +00:00
end 2: begin // finish RAM access
2023-04-15 04:30:11 +00:00
if (DTACKr) RS <= 3; // Cycle ending
else RS <= 2; // Cycle not ending yet
RASEL <= 0;
RASrr <= 0;
RASEN <= 0;
RAMReady <= 1;
2023-04-10 23:28:13 +00:00
end 3: begin //AS cycle complete
if (RefUrg) begin // Refresh RAS
RS <= 4;
RASEL <= 0;
RASrr <= 1;
RASEN <= 0;
RAMReady <= 0;
2023-04-10 23:28:13 +00:00
end else begin // Cycle ended so go abck to idle/ready
RS <= 0;
RASEL <= 0;
RASrr <= 0;
RASEN <= 1;
RAMReady <= 1;
end
2023-04-15 04:30:11 +00:00
end 4: begin // Refresh RAS II
RS <= 5;
RASEL <= 0;
RASrr <= 1;
RASEN <= 0;
RAMReady <= 0;
end 5: begin // Refresh precharge I
2023-04-10 23:28:13 +00:00
RS <= 6;
2021-10-29 10:04:59 +00:00
RASEL <= 0;
2023-04-15 04:30:11 +00:00
RASrr <= 0;
RASEN <= 0;
RAMReady <= 0;
end 6: begin // Refresh precharge II
RS <= 7;
RASEL <= 0;
RASrr <= 0;
RASEN <= 0;
RAMReady <= 0;
2023-04-11 00:33:44 +00:00
end 7: begin // Reenable RAM and go to idle/ready
RS <= 0;
2021-10-29 10:04:59 +00:00
RASEL <= 0;
RASrr <= 0;
RASEN <= 1;
RAMReady <= 1;
2021-10-29 10:04:59 +00:00
end
endcase
2021-10-29 10:04:59 +00:00
end
2023-04-10 23:28:13 +00:00
always @(negedge CLK) begin
RASrf <= RS==1;
2023-04-10 23:28:13 +00:00
case (RS[2:0])
2023-04-11 00:33:44 +00:00
0: nCAS <= !RS0toRef;
2023-04-10 23:28:13 +00:00
1: nCAS <= 0;
2: nCAS <= DTACKr;
3: nCAS <= !RefUrg;
4: nCAS <= !RefUrg;
5: nCAS <= 1;
6: nCAS <= 1;
7: nCAS <= 1;
endcase
end
2021-10-29 10:04:59 +00:00
endmodule