Warp-SE/cpld/RAM.v

183 lines
5.2 KiB
Coq
Raw Normal View History

2021-10-29 10:04:59 +00:00
module RAM(
/* MC68HC000 interface */
input CLK, input [21:1] A, input nWE, input nAS, input nLDS, input nUDS,
/* AS cycle detection */
input BACT,
/* Select and ready signals */
2023-03-22 01:11:58 +00:00
input RAMCS, input ROMCS, output RAM_Ready,
2021-10-29 10:04:59 +00:00
/* Refresh Counter Interface */
2023-03-26 08:33:59 +00:00
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,
output nLWE, output nUWE, output nOE, output nROMCS, output nROMWE);
2023-03-22 01:11:58 +00:00
// Save BACT from last clock
reg BACTr; always @(posedge CLK) BACTr <= BACT;
2021-10-29 10:04:59 +00:00
/* RAM control state */
reg [2:0] RS = 0;
2022-09-04 01:32:05 +00:00
reg RAMEN = 0;
2021-10-29 10:04:59 +00:00
reg RAMReady = 0;
reg RASEL = 0; // RASEL controls /CAS signal
2022-09-04 01:32:05 +00:00
/* Refresh request synchronization */
2023-03-22 01:11:58 +00:00
reg RefReqSync; always @(posedge CLK) RefReqSync <= RefReqIn;
2023-03-26 08:33:59 +00:00
reg RegUrgSync; always @(posedge CLK) RegUrgSync <= RefUrgIn;
2023-03-22 01:11:58 +00:00
/* Refresh command generation */
2023-03-26 08:33:59 +00:00
reg RefReq, RefUrg; // Refresh commands
2022-09-04 01:32:05 +00:00
reg RefDone; // Refresh done "remember"
always @(posedge CLK) begin
2023-03-22 01:11:58 +00:00
RefReq <= RefReqSync && !RefDone;
2023-03-26 08:33:59 +00:00
RefUrg <= RegUrgSync && !RefDone;
2023-03-22 01:11:58 +00:00
if (!RefReqSync) RefDone <= 0;
2022-09-04 01:32:05 +00:00
else if (RS==2 || RS==3) RefDone <= 1; // RS2 || RS3 to save 1 input
end
/* Refresh init conditions */
2023-03-22 01:11:58 +00:00
wire RefFromRS0Next = RS==0 && (
2022-09-04 01:32:05 +00:00
// Non-urgent refresh can start during first clock of non-RAM cycle
( BACT && ~BACTr && ~RAMCS && RefReq) ||
// Urgent refresh can start during bus idle
2023-03-26 08:33:59 +00:00
(~BACT && RefUrg) ||
2022-09-04 01:32:05 +00:00
// Urgent refresh can start during non-ram cycle
2023-03-26 08:33:59 +00:00
( BACT && ~RAMCS && RefUrg));
2023-03-22 01:11:58 +00:00
wire RefFromRS0Pre = RS==0 &&
2022-09-04 01:32:05 +00:00
// Urgent refresh can start during long RAM cycle after RAM access done.
2023-03-26 08:33:59 +00:00
BACT && RAMCS && !RAMEN && RefUrg;
2023-03-22 01:11:58 +00:00
wire RefFromRS0 = RefFromRS0Next || RefFromRS0Pre;
2022-09-04 01:32:05 +00:00
// Urgent refresh cannot start when BACT and RAMCS and RAMEN,
// since /RAS has already been asserted. For this we wait for RS7.
2023-03-26 08:33:59 +00:00
wire RefFromRS7 = RS==7 && RefUrg;
2022-09-04 01:32:05 +00:00
/* RAM enable (/AS -> /RAS) */
always @(posedge CLK) begin
if (RS==0) begin
2023-03-22 01:11:58 +00:00
if (RefFromRS0) RAMEN <= 0;
2022-09-04 01:32:05 +00:00
else if (!BACT) RAMEN <= 1;
end else if (RS==7) begin
2023-03-22 01:11:58 +00:00
if (RefFromRS7) RAMEN <= 0;
2023-04-01 12:19:52 +00:00
else RAMEN <= 1;
2022-09-04 01:32:05 +00:00
end
end
2021-10-29 10:04:59 +00:00
/* Refresh state */
reg RefRAS = 0;
2023-03-26 08:33:59 +00:00
assign nROMCS = !ROMCS;
2023-03-27 14:17:22 +00:00
assign nRAS = !((~nAS && RAMCS && RAMEN) || RefRAS);
assign nOE = !(~nAS && nWE);
assign nLWE = !(~nAS && ~nWE && ~nLDS && RAMEN);
assign nUWE = !(~nAS && ~nWE && ~nUDS && RAMEN);
assign nROMWE = !(~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) */
2023-04-02 04:26:06 +00:00
assign RA[11] = ROMCS ? A[19] : !RASEL ? A[21] : A[20];
assign RA[03] = !RASEL ? A[21] : A[20];
assign RA[10] = !RASEL ? A[19] : A[17];
assign RA[02] = !RASEL ? A[18] : A[17];
assign RA[09] = !RASEL ? A[16] : A[08];
assign RA[08] = ROMCS ? A[18] : !RASEL ? A[15] : A[07];
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];
2021-10-29 10:04:59 +00:00
always @(posedge CLK) begin
if (RS==0) begin
2022-09-04 01:32:05 +00:00
// In RS0, RAM is idle and ready for new command.
if (RefFromRS0Next) begin
2021-10-29 10:04:59 +00:00
RS <= 2;
RAMReady <= 0;
RASEL <= 1;
2022-09-04 01:32:05 +00:00
end else if (RefFromRS0Pre) begin
// Urgent ref can start during long RAM cycle after access.
// Must insert one extra precharge state first by going to RS1.
RS <= 1;
RAMReady <= 0;
RASEL <= 0;
end else if (BACT && RAMCS && RAMEN) begin
2021-10-29 10:04:59 +00:00
// RAM access cycle has priority over urgent refresh if RAM access already begun
RS <= 5;
RAMReady <= 0;
RASEL <= 1;
2023-03-22 01:11:58 +00:00
end else if (RefFromRS0Pre) begin
2021-10-29 10:04:59 +00:00
RS <= 1;
RAMReady <= 0;
RASEL <= 0;
end else begin
// No RAM access/refresh requests pending
RS <= 0;
RAMReady <= 1;
RASEL <= 0;
end
RefRAS <= 0;
end else if (RS==1) begin
2022-09-04 01:32:05 +00:00
// RS1 implements extra precharge time before refresh.
2021-10-29 10:04:59 +00:00
RS <= 2;
RAMReady <= 0;
RASEL <= 1;
RefRAS <= 0;
end else if (RS==2) begin
2022-09-04 01:32:05 +00:00
// Refresh RAS pulse asserted ater RS2.
2021-10-29 10:04:59 +00:00
RS <= 3;
RAMReady <= 0;
RASEL <= 1;
RefRAS <= 1;
end else if (RS==3) begin
2022-09-04 01:32:05 +00:00
// RS3 implements requisite RAS pulse width.
2021-10-29 10:04:59 +00:00
RS <= 4;
RAMReady <= 0;
RASEL <= 0;
RefRAS <= 1;
end else if (RS==4) begin
2022-09-04 01:32:05 +00:00
// RS4 implements precharge after RAM refresh.
2021-10-29 10:04:59 +00:00
RS <= 7;
RAMReady <= 0;
RASEL <= 0;
RefRAS <= 0;
end else if (RS==5) begin
2022-09-04 01:32:05 +00:00
// RS5 is first state of R/W operation
2021-10-29 10:04:59 +00:00
RS <= 6;
RAMReady <= 0;
RASEL <= 1;
RefRAS <= 0;
end else if (RS==6) begin
2022-09-04 01:32:05 +00:00
// RS6 is second state of R/W operation
2021-10-29 10:04:59 +00:00
RS <= 7;
RAMReady <= 0;
RASEL <= 0;
RefRAS <= 0;
end else if (RS==7) begin
2022-09-04 01:32:05 +00:00
// RS7 is final state of R/W or refresh operation.
2023-03-26 08:33:59 +00:00
if (~BACT && RefUrg) begin
2022-09-04 01:32:05 +00:00
// If /AS cycle terminated and urgent refresh request,
// we know /RAS has been in precharge so we can go to RS2.
2021-10-29 10:04:59 +00:00
RS <= 2;
RAMReady <= 0;
RASEL <= 1;
2023-03-26 08:33:59 +00:00
end else if (BACT && RefUrg) begin
2022-09-04 01:32:05 +00:00
// But if /AS cycle hasn't terminated and we need to refresh,
// we need to go to RS1 to add additional precharge time.
2021-10-29 10:04:59 +00:00
RS <= 1;
RAMReady <= 0;
RASEL <= 0;
end else begin
2022-09-04 01:32:05 +00:00
// Otherwise if no urgent refresh request, go to RS0.
2021-10-29 10:04:59 +00:00
RS <= 0;
RAMReady <= 1;
RASEL <= 0;
end
RefRAS <= 0;
end
end
always @(negedge CLK) begin nCAS <= ~RASEL; end
2023-03-22 01:11:58 +00:00
assign RAM_Ready = ~RAMCS || RAMReady;
2021-10-29 10:04:59 +00:00
endmodule