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 */
|
2023-07-16 06:25:27 +00:00
|
|
|
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 */
|
2024-10-07 05:30:52 +00:00
|
|
|
output RAMReady,
|
2021-10-29 10:04:59 +00:00
|
|
|
/* Refresh Counter Interface */
|
2023-07-16 03:21:44 +00:00
|
|
|
input RefReqIn, input RefUrgIn,
|
2024-10-07 11:53:56 +00:00
|
|
|
/* DRAM interface */
|
2021-10-29 10:04:59 +00:00
|
|
|
output [11:0] RA, output nRAS, output reg nCAS,
|
2024-10-07 11:53:56 +00:00
|
|
|
output nLWE, output nUWE, output reg nOE,
|
|
|
|
/* NOR flash interface */
|
|
|
|
output nROMOE, output nROMWE);
|
2023-04-10 23:28:13 +00:00
|
|
|
|
2023-04-07 03:11:11 +00:00
|
|
|
/* RAM control state */
|
2024-10-03 15:31:14 +00:00
|
|
|
reg [2:0] RS;
|
|
|
|
reg RASEN;
|
|
|
|
reg RASEL;
|
|
|
|
reg RASrf;
|
|
|
|
reg RefCAS;
|
|
|
|
reg CASEndEN;
|
2023-04-07 03:11:11 +00:00
|
|
|
|
2023-04-07 04:41:16 +00:00
|
|
|
/* Refresh command generation */
|
2023-07-16 03:21:44 +00:00
|
|
|
reg RefDone; // Refresh done "remember"
|
2023-04-07 04:41:16 +00:00
|
|
|
always @(posedge CLK) begin
|
2024-10-07 03:07:15 +00:00
|
|
|
if (!RefReqIn && !RefUrgIn) RefDone <= 0;
|
2023-07-16 03:21:44 +00:00
|
|
|
else if (RS[2]) RefDone <= 1;
|
2023-04-07 04:41:16 +00:00
|
|
|
end
|
2023-07-16 03:21:44 +00:00
|
|
|
wire RefReq = RefReqIn && !RefDone;
|
|
|
|
wire RefUrg = RefUrgIn && !RefDone;
|
2024-10-07 05:30:52 +00:00
|
|
|
|
|
|
|
/* RAM ready control */
|
|
|
|
reg RAMReadyReg;
|
|
|
|
assign RAMReady = RAMReadyReg;//!RS[2];
|
2023-04-07 04:41:16 +00:00
|
|
|
|
2024-10-09 01:12:13 +00:00
|
|
|
/* RAM /RAS control */
|
2024-10-08 11:19:18 +00:00
|
|
|
assign nRAS = !((!nAS && RAMCS && RASEN) || RASrf);
|
2024-10-07 11:53:56 +00:00
|
|
|
|
2024-10-09 01:12:13 +00:00
|
|
|
/* RAM /WE control */
|
2024-10-08 11:19:18 +00:00
|
|
|
assign nLWE = !(!nLDS && RASEL && !nWE);
|
|
|
|
assign nUWE = !(!nUDS && RASEL && !nWE);
|
2024-10-07 11:53:41 +00:00
|
|
|
|
|
|
|
/* RAM /OE control */
|
2024-10-09 01:13:18 +00:00
|
|
|
always @(posedge CLK, posedge nAS) begin
|
2024-10-07 11:53:41 +00:00
|
|
|
if (nAS) nOE <= 1;
|
2024-10-09 01:13:18 +00:00
|
|
|
else nOE <= !(RAMCS && nWE);
|
2024-10-07 11:53:41 +00:00
|
|
|
end
|
2021-10-29 10:04:59 +00:00
|
|
|
|
2024-10-09 01:12:13 +00:00
|
|
|
/* ROM /OE and /WE control */
|
2024-10-03 15:31:14 +00:00
|
|
|
assign nROMOE = !(!nAS && ROMCS && nWE);
|
2024-10-07 11:53:23 +00:00
|
|
|
assign nROMWE = !(!nAS && ROMCS4X && !nWE && BACTr);
|
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-07 03:11:11 +00:00
|
|
|
// 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
|
2023-07-16 03:21:44 +00:00
|
|
|
(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
|
2024-10-03 15:31:14 +00:00
|
|
|
(RefUrg && BACT && !RAMCS0X);
|
2024-10-07 03:07:15 +00:00
|
|
|
wire RS0toRAM = BACT && RAMCS && RASEN;
|
2023-04-10 08:08:23 +00:00
|
|
|
|
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
|
2024-10-03 15:31:14 +00:00
|
|
|
if (RS0toRAM) RS <= 1; // Access RAM
|
|
|
|
else if (RS0toRef) RS <= 4; // To refresh
|
|
|
|
else RS <= 0; // Stay in idle/ready
|
|
|
|
RASEL <= BACT && RAMCS;
|
|
|
|
RefCAS <= RS0toRef;
|
|
|
|
RASEN <= !RS0toRef;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= !RS0toRef;
|
2023-04-10 23:28:13 +00:00
|
|
|
end 1: begin // RAM access
|
2024-10-03 15:31:14 +00:00
|
|
|
if (!nDTACK || !BACT) RS <= 2; // Cycle ending
|
|
|
|
else RS <= 1; // Cycle not ending yet
|
2021-10-29 10:04:59 +00:00
|
|
|
RASEL <= 1;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
|
|
|
RASEN <= nDTACK;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 1;
|
2023-04-10 23:28:13 +00:00
|
|
|
end 2: begin // finish RAM access
|
2024-10-03 15:31:14 +00:00
|
|
|
RS <= 3;
|
2023-04-15 04:30:11 +00:00
|
|
|
RASEL <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-15 04:30:11 +00:00
|
|
|
RASEN <= 0;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 1;
|
2023-04-10 23:28:13 +00:00
|
|
|
end 3: begin //AS cycle complete
|
|
|
|
if (RefUrg) begin // Refresh RAS
|
|
|
|
RS <= 4;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 1;
|
2023-04-10 23:28:13 +00:00
|
|
|
RASEN <= 0;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
end else begin // Cycle ended so go back to idle/ready
|
2023-04-10 08:08:23 +00:00
|
|
|
RS <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-10 08:08:23 +00:00
|
|
|
RASEN <= 1;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 1;
|
2023-04-07 03:11:11 +00:00
|
|
|
end
|
2024-10-03 15:31:14 +00:00
|
|
|
RASEL <= 0;
|
|
|
|
end 4: begin // Refresh RAS I
|
2023-04-17 06:31:33 +00:00
|
|
|
RS <= 5;
|
|
|
|
RASEL <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-17 06:31:33 +00:00
|
|
|
RASEN <= 0;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
end 5: begin // Refresh RAS II
|
2023-04-10 23:28:13 +00:00
|
|
|
RS <= 6;
|
2021-10-29 10:04:59 +00:00
|
|
|
RASEL <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-15 04:30:11 +00:00
|
|
|
RASEN <= 0;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
end 6: begin // Refresh precharge I
|
2023-04-15 04:30:11 +00:00
|
|
|
RS <= 7;
|
|
|
|
RASEL <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-10 08:08:23 +00:00
|
|
|
RASEN <= 0;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 0;
|
2023-04-11 00:33:44 +00:00
|
|
|
end 7: begin // Reenable RAM and go to idle/ready
|
2023-04-10 08:08:23 +00:00
|
|
|
RS <= 0;
|
2021-10-29 10:04:59 +00:00
|
|
|
RASEL <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
RefCAS <= 0;
|
2023-04-10 08:08:23 +00:00
|
|
|
RASEN <= 1;
|
2024-10-07 05:30:52 +00:00
|
|
|
RAMReadyReg <= 1;
|
2021-10-29 10:04:59 +00:00
|
|
|
end
|
2023-04-07 03:11:11 +00:00
|
|
|
endcase
|
2021-10-29 10:04:59 +00:00
|
|
|
end
|
2024-10-03 15:31:14 +00:00
|
|
|
|
2023-04-10 23:28:13 +00:00
|
|
|
always @(negedge CLK) begin
|
|
|
|
case (RS[2:0])
|
2024-10-03 15:31:14 +00:00
|
|
|
0: begin
|
|
|
|
RASrf <= 0;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end 1: begin
|
|
|
|
RASrf <= 1;
|
|
|
|
CASEndEN <= 1;
|
|
|
|
end 2: begin
|
|
|
|
RASrf <= 0;
|
|
|
|
CASEndEN <= 1;
|
|
|
|
end 3: begin
|
|
|
|
RASrf <= 0;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end 4: begin
|
|
|
|
RASrf <= 1;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end 5: begin
|
|
|
|
RASrf <= 1;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end 6: begin
|
|
|
|
RASrf <= 0;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end 7: begin
|
|
|
|
RASrf <= 0;
|
|
|
|
CASEndEN <= 0;
|
|
|
|
end
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
wire CASEnd = CASEndEN && nAS;
|
|
|
|
always @(negedge CLK, posedge RefCAS, posedge CASEnd) begin
|
|
|
|
if (RefCAS) nCAS <= 0;
|
|
|
|
else if (CASEnd) nCAS <= 1;
|
|
|
|
else case (RS[2:0])
|
|
|
|
0: nCAS <= 1;
|
2023-04-10 23:28:13 +00:00
|
|
|
1: nCAS <= 0;
|
2024-10-03 15:31:14 +00:00
|
|
|
2: nCAS <= 0;
|
|
|
|
3: nCAS <= 1;
|
|
|
|
4: nCAS <= 0;
|
2023-04-10 23:28:13 +00:00
|
|
|
5: nCAS <= 1;
|
|
|
|
6: nCAS <= 1;
|
|
|
|
7: nCAS <= 1;
|
|
|
|
endcase
|
|
|
|
end
|
2021-10-29 10:04:59 +00:00
|
|
|
|
|
|
|
endmodule
|