2021-03-19 18:23:33 +00:00
|
|
|
module GR8RAM(C25M, PHI0, nRES, nRESout,
|
2021-03-15 17:40:59 +00:00
|
|
|
nIOSEL, nDEVSEL, nIOSTRB,
|
2021-03-19 10:45:31 +00:00
|
|
|
RA, nWE, RAdir, RD, RDdir,
|
2021-03-15 17:40:59 +00:00
|
|
|
SBA, SA, nRCS, nRAS, nCAS, nSWE, DQML, DQMH, RCKE, SD,
|
|
|
|
nFCS, FCK, MISO, MOSI);
|
|
|
|
|
|
|
|
/* Clock signals */
|
|
|
|
/* Outputs: C25M, PHI0r1, PHI0r2, */
|
|
|
|
input C25M, PHI0;
|
|
|
|
reg PHI0r0, PHI0r1, PHI0r2;
|
|
|
|
always @(negedge C25M) begin PHI0r0 <= PHI0; end
|
|
|
|
always @(posedge C25M) begin PHI0r1 <= PHI0r0; PHI0r2 <= PHI0r1; end
|
|
|
|
|
|
|
|
/* Reset/brown-out detect synchronized inputs */
|
2021-03-19 18:23:33 +00:00
|
|
|
/* Outputs: nRESr */
|
|
|
|
input nRES;
|
2021-03-15 17:40:59 +00:00
|
|
|
reg nRESr0, nRESr;
|
2021-03-19 18:23:33 +00:00
|
|
|
always @(negedge C25M) begin nRESr0 <= nRES; end
|
|
|
|
always @(posedge C25M) begin nRESr <= nRESr0; end
|
2021-03-15 17:40:59 +00:00
|
|
|
|
2021-03-19 06:56:20 +00:00
|
|
|
/* Long state counter: counts from 0 to $3FFFF */
|
2021-03-19 10:45:31 +00:00
|
|
|
/* Outputs: LS */
|
2021-03-19 06:56:20 +00:00
|
|
|
reg [17:0] LS = 0;
|
2021-03-19 10:45:31 +00:00
|
|
|
always @(posedge C25M) begin LS <= LS+1; end
|
2021-03-15 17:40:59 +00:00
|
|
|
|
|
|
|
/* Init state */
|
|
|
|
output reg nRESout = 0;
|
|
|
|
always @(posedge C25M) begin
|
2021-03-19 18:23:33 +00:00
|
|
|
if (LS[17:0]==18'h30002) begin
|
|
|
|
nRESout <= 1'b1;
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
/* Apple IO area select signals */
|
|
|
|
/* Outputs: DEVSELr */
|
|
|
|
input nIOSEL, nDEVSEL, nIOSTRB;
|
|
|
|
reg DEVSELr0, DEVSELr;
|
2021-03-19 06:56:20 +00:00
|
|
|
reg IOSELr0, IOSELr;
|
|
|
|
reg IOSTRBr0, IOSTRBr;
|
|
|
|
always @(negedge C25M) begin
|
|
|
|
DEVSELr0 <= ~nDEVSEL; IOSELr0 <= ~nIOSEL; IOSTRBr0 <= ~nIOSTRB;
|
|
|
|
end
|
|
|
|
always @(posedge C25M) begin
|
|
|
|
DEVSELr <= DEVSELr0; IOSELr <= IOSELr0; IOSTRBr <= IOSTRBr0;
|
|
|
|
end
|
2021-03-15 17:40:59 +00:00
|
|
|
|
|
|
|
/* Apple address bus */
|
2021-03-19 06:56:20 +00:00
|
|
|
/* Outputs: RACr, RAcur, nWEcur, RAdir */
|
2021-03-15 17:40:59 +00:00
|
|
|
input [15:0] RA;
|
|
|
|
input nWE;
|
2021-03-19 06:56:20 +00:00
|
|
|
reg RACr;
|
|
|
|
reg [11:0] RAcur; reg nWEcur;
|
2021-03-15 17:40:59 +00:00
|
|
|
output RAdir = 1;
|
|
|
|
always @(posedge C25M) begin
|
2021-03-19 10:45:31 +00:00
|
|
|
if (PSStart) begin
|
2021-03-19 06:56:20 +00:00
|
|
|
RACr <= RA[15:12]==4'hC;
|
|
|
|
RAcur[11:0] <= RA[11:0];
|
|
|
|
nWEcur <= nWE;
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
/* Apple select signals */
|
2021-03-19 10:45:31 +00:00
|
|
|
/* Outputs: ROMSpecRD, RAMSpecSEL, RAMSpecRD, RAMSpecWR */
|
2021-03-19 06:56:20 +00:00
|
|
|
wire ROMSpecRD = RACr && RAcur[11:8]!=4'h0 && nWEcur;
|
2021-03-19 10:45:31 +00:00
|
|
|
wire RAMSpecSEL = RACr && RAcur[11:8]==4'h0 && RAcur[7] && RAcur[3:0]==4'h3;
|
2021-03-15 17:40:59 +00:00
|
|
|
wire RAMSpecRD = RAMSpecSEL && nWEcur;
|
|
|
|
wire RAMSpecWR = RAMSpecSEL && ~nWEcur;
|
2021-03-19 06:56:20 +00:00
|
|
|
|
|
|
|
/* IOROMEN and REGEN control */
|
|
|
|
reg IOROMEN = 0;
|
|
|
|
reg REGEN = 0;
|
|
|
|
always @(posedge C25M) begin
|
|
|
|
if (~nRESr) begin
|
|
|
|
IOROMEN <= 0;
|
|
|
|
REGEN <= 0;
|
2021-03-19 10:45:31 +00:00
|
|
|
end else if (PS==7 && IOSTRBr && RAcur[10:0]==11'h7FF) begin
|
2021-03-19 06:56:20 +00:00
|
|
|
IOROMEN <= 0;
|
2021-03-19 10:45:31 +00:00
|
|
|
end else if (PS==7 && IOSELr) begin
|
2021-03-19 06:56:20 +00:00
|
|
|
IOROMEN <= 1;
|
|
|
|
REGEN <= 1;
|
|
|
|
end
|
|
|
|
end
|
2021-03-15 17:40:59 +00:00
|
|
|
|
|
|
|
/* Apple data bus */
|
|
|
|
inout [7:0] RD = RDdir ? 8'bZ : RDout[7:0];
|
|
|
|
reg [7:0] RDout;
|
2021-03-19 18:23:33 +00:00
|
|
|
output RDdir = ~(PHI0 && PHI0r2 && nWE &&
|
2021-03-19 10:45:31 +00:00
|
|
|
((~nDEVSEL && REGEN) || ~nIOSEL || (~nIOSTRB && IOROMEN)));
|
2021-03-15 17:40:59 +00:00
|
|
|
|
|
|
|
/* Slinky address registers */
|
2021-03-19 06:56:20 +00:00
|
|
|
reg [23:0] Addr = 0;
|
2021-03-15 17:40:59 +00:00
|
|
|
wire AddrHSpecSEL = RAcur[3:0]==4'h2;
|
|
|
|
wire AddrMSpecSEL = RAcur[3:0]==4'h1;
|
|
|
|
wire AddrLSpecSEL = RAcur[3:0]==4'h0;
|
|
|
|
always @(posedge C25M) begin
|
|
|
|
if (~nRESr) begin
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[23:0] <= 24'h000000;
|
2021-03-19 10:45:31 +00:00
|
|
|
end else if (PS==7 && REGEN && DEVSELr) begin
|
|
|
|
if (RAMSpecSEL) begin
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[23:0] <= Addr[23:0]+1;
|
2021-03-19 10:45:31 +00:00
|
|
|
end else if (AddrLSpecSEL && ~nWEcur) begin
|
2021-03-15 17:40:59 +00:00
|
|
|
Addr[7:0] <= RD[7:0];
|
2021-03-19 10:45:31 +00:00
|
|
|
if (~RD[7] && Addr[7]) begin
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[23:8] <= Addr[23:8]+1;
|
2021-03-19 10:45:31 +00:00
|
|
|
end
|
|
|
|
end else if (AddrMSpecSEL && ~nWEcur) begin
|
|
|
|
Addr[15:8] <= RD[7:0];
|
|
|
|
if (~RD[7] && Addr[15]) begin
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[23:16] <= Addr[23:16]+1;
|
2021-03-19 10:45:31 +00:00
|
|
|
end
|
|
|
|
end else if (AddrHSpecSEL && ~nWEcur) begin
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[23:16] <= RD[7:0];
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-19 06:56:20 +00:00
|
|
|
/* ROM bank register */
|
|
|
|
reg [1:0] Bank = 0;
|
|
|
|
wire BankSpecSEL = RAcur[3:0]==4'hF;
|
|
|
|
always @(posedge C25M) begin
|
2021-03-19 10:45:31 +00:00
|
|
|
if (~nRESr) Bank <= 0;
|
|
|
|
else if (PS==7 && DEVSELr && BankSpecSEL && ~nWEcur) begin
|
2021-03-19 06:56:20 +00:00
|
|
|
Bank[1:0] <= RD[1:0];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-15 17:40:59 +00:00
|
|
|
/* SPI flash */
|
2021-03-19 06:56:20 +00:00
|
|
|
output nFCS = ~FCS;
|
|
|
|
reg FCS = 0;
|
2021-03-15 17:40:59 +00:00
|
|
|
output reg FCK = 0;
|
2021-03-19 06:56:20 +00:00
|
|
|
reg FCKEN = 0;
|
|
|
|
output MOSI = MOSIOE ? MOSIout : 1'bZ;
|
2021-03-15 17:40:59 +00:00
|
|
|
reg MOSIOE = 0;
|
|
|
|
reg MOSIout;
|
|
|
|
input MISO;
|
|
|
|
|
|
|
|
/* SPI flash control */
|
2021-03-19 06:56:20 +00:00
|
|
|
always @(posedge C25M) begin
|
2021-03-19 18:23:33 +00:00
|
|
|
FCK <= ~nRESout && FCKEN && LS[0];
|
2021-03-19 06:56:20 +00:00
|
|
|
end
|
2021-03-15 17:40:59 +00:00
|
|
|
always @(posedge C25M) begin
|
2021-03-19 18:23:33 +00:00
|
|
|
if (~nRESout) begin
|
2021-03-19 06:56:20 +00:00
|
|
|
// Flash /CS enabled from init states $0FFB0 to $2FFFF
|
2021-03-19 10:45:31 +00:00
|
|
|
if (LS[17:0]==18'h0FF90) FCS <= 1'b0;
|
|
|
|
else if (LS[17:0]==18'h0FFA0) FCS <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h30000) FCS <= 1'b0;
|
2021-03-15 17:40:59 +00:00
|
|
|
|
2021-03-19 10:45:31 +00:00
|
|
|
// Pulse clock from init states $0FFC0 to $2FFFF
|
|
|
|
if (LS[17:0]==18'h0FF90) FCKEN <= 1'b0;
|
|
|
|
else if (LS[17:0]==18'h0FFB0) FCKEN <= 1'b1;
|
|
|
|
else if (LS[17:0]==18'h30000) FCKEN <= 1'b0;
|
|
|
|
|
2021-03-15 17:40:59 +00:00
|
|
|
// Send command $3B (read) (MSB first)
|
2021-03-19 10:45:31 +00:00
|
|
|
if (LS[17:0]==18'h0FFB0 || LS[17:0]==18'h0FFB1) MOSIout <= 0;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h0FFB2 || LS[17:0]==18'h0FFB3) MOSIout <= 0;
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (LS[17:0]==18'h0FFB4 || LS[17:0]==18'h0FFB5) MOSIout <= 1;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h0FFB6 || LS[17:0]==18'h0FFB7) MOSIout <= 1;
|
|
|
|
else if (LS[17:0]==18'h0FFB8 || LS[17:0]==18'h0FFB9) MOSIout <= 1;
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (LS[17:0]==18'h0FFBA || LS[17:0]==18'h0FFBB) MOSIout <= 0;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h0FFBC || LS[17:0]==18'h0FFBD) MOSIout <= 1;
|
|
|
|
else if (LS[17:0]==18'h0FFBE || LS[17:0]==18'h0FFBF) MOSIout <= 1;
|
2021-03-15 17:40:59 +00:00
|
|
|
// Send 24-bit address (MSB first)
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (LS[17:0]==18'h0FFC0 || LS[17:0]==18'h0FFC1) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFC2 || LS[17:0]==18'h0FFC3) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFC4 || LS[17:0]==18'h0FFC5) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFC6 || LS[17:0]==18'h0FFC7) MOSIout <= SetFW;
|
|
|
|
else if (LS[17:0]==18'h0FFC8 || LS[17:0]==18'h0FFC9) MOSIout <= 0;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h0FFCA || LS[17:0]==18'h0FFCB) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFCC || LS[17:0]==18'h0FFCD) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFCE || LS[17:0]==18'h0FFCF) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFD0 || LS[17:0]==18'h0FFD1) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFD2 || LS[17:0]==18'h0FFD3) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFD4 || LS[17:0]==18'h0FFD5) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFD6 || LS[17:0]==18'h0FFD7) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFD8 || LS[17:0]==18'h0FFD9) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFDA || LS[17:0]==18'h0FFDB) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFDC || LS[17:0]==18'h0FFDD) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFDE || LS[17:0]==18'h0FFDF) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFE0 || LS[17:0]==18'h0FFE1) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFE2 || LS[17:0]==18'h0FFE3) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFE4 || LS[17:0]==18'h0FFE5) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFE6 || LS[17:0]==18'h0FFE7) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFE8 || LS[17:0]==18'h0FFE9) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFEA || LS[17:0]==18'h0FFEB) MOSIout <= 0;
|
|
|
|
else if (LS[17:0]==18'h0FFEC || LS[17:0]==18'h0FFED) MOSIout <= 0;
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (LS[17:0]==18'h0FFEE || LS[17:0]==18'h0FFEF) MOSIout <= 0;
|
2021-03-15 17:40:59 +00:00
|
|
|
else MOSIout <= 0;
|
|
|
|
|
2021-03-19 10:45:31 +00:00
|
|
|
if (LS[17:0]==18'h0FF90) MOSIOE <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
else if (LS[17:0]==18'h0FFF0) MOSIOE <= 1'b0;
|
2021-03-19 18:23:33 +00:00
|
|
|
end else begin
|
2021-03-15 17:40:59 +00:00
|
|
|
//TODO: control these with Apple II
|
2021-03-19 06:56:20 +00:00
|
|
|
FCS <= 0;
|
|
|
|
FCKEN <= 0;
|
2021-03-15 17:40:59 +00:00
|
|
|
MOSIout <= 0;
|
|
|
|
MOSIOE <= 0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-19 06:56:20 +00:00
|
|
|
/* UFM control */
|
|
|
|
reg ARCLK = 0; // UFM address register clock
|
|
|
|
reg ARShift = 0; // 1 to Shift UFM address in, 0 to increment
|
|
|
|
reg DRCLK = 0; // UFM data register clock
|
|
|
|
reg DRDIn = 0; // UFM data register input
|
|
|
|
reg DRShift = 0; // 1 to shift UFM out, 0 to load from current address
|
|
|
|
reg UFMErase = 0; // Rising edge starts erase. UFM+RTP must not be busy
|
|
|
|
reg UFMProgram = 0; // Rising edge starts program. UFM+RTP must not be busy
|
|
|
|
wire UFMBusy; // 1 if UFM is doing user operation. Asynchronous
|
|
|
|
wire RTPBusy; // 1 if real-time programming in progress. Asynchronous
|
|
|
|
wire DRDOut; // UFM data output
|
|
|
|
// UFM oscillator always enabled
|
|
|
|
wire UFMOsc; // UFM oscillator output (3.3-5.5 MHz)
|
|
|
|
UFM UFM_inst ( // UFM IP block (for Altera MAX II and MAX V)
|
|
|
|
.arclk (ARCLK),
|
|
|
|
.ardin (1'b0),
|
|
|
|
.arshft (ARShift),
|
|
|
|
.drclk (DRCLK),
|
|
|
|
.drdin (DRDIn),
|
|
|
|
.drshft (DRShift),
|
|
|
|
.erase (UFMErase),
|
|
|
|
.oscena (1'b1),
|
|
|
|
.program (UFMProgram),
|
|
|
|
.busy (UFMB),
|
|
|
|
.drdout (DRDOut),
|
|
|
|
.osc (UFMOsc),
|
|
|
|
.rtpbusy (RTPB));
|
|
|
|
reg UFMBr0 = 0; // UFMBusy registered to sync with C25M
|
|
|
|
reg UFMBr = 0; // UFMBusy registered to sync with C25M
|
|
|
|
reg RTPBr0 = 0; // RTPBusy registered to sync with C25M
|
|
|
|
reg RTPBr = 0; // RTPBusy registered to sync with C25M
|
2021-03-19 10:45:31 +00:00
|
|
|
always @(negedge C25M) begin UFMBr0 <= UFMB; RTPBr0 <= RTPB; end
|
|
|
|
always @(posedge C25M) begin UFMBr <= UFMBr0; RTPBr <= RTPBr0; end
|
2021-03-19 20:38:48 +00:00
|
|
|
reg [1:0] SS = 0;
|
2021-03-19 10:59:22 +00:00
|
|
|
reg SetFW;
|
2021-03-19 06:56:20 +00:00
|
|
|
reg SetLim8M;
|
|
|
|
always @(posedge C25M) begin
|
2021-03-19 20:38:48 +00:00
|
|
|
if (SS[1:0]!=2'b11) begin
|
|
|
|
if (SS[1:0]==2'b10 && LS[3:0]==4'h2 && DRDOut) SS[1:0] <= 2'b11;
|
|
|
|
else if (LS[15:0]==16'h0FB0) SS[1:0] <= 2'b01;
|
|
|
|
else if (LS[15:0]==16'h0FFF) SS[1:0] <= 2'b10;
|
|
|
|
else if (LS[15:0]==16'h1FFF) SS[1:0] <= 2'b11;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
always @(posedge C25M) begin
|
|
|
|
if (SS[1:0]==2'b00 /* LS[15:0]<=16'h0FB0 */) begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 1;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 0;
|
|
|
|
end else if (SS[1:0]==2'b01 /* LS[15:0]<=16'h0FFF */) begin
|
|
|
|
ARCLK <= ~LS[1];
|
|
|
|
ARShift <= 1;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 0;
|
|
|
|
SetFW <= 1'b1;
|
|
|
|
SetLim8M <= 1'b1;
|
|
|
|
end else if (SS[1:0]==2'b10 /* LS[15:0]<=16'h1FFF */) begin
|
|
|
|
case (LS[3:1])
|
|
|
|
3'h0: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 1;
|
|
|
|
DRShift <= 0;
|
|
|
|
end 3'h1: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 1;
|
|
|
|
end 3'h2: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 1;
|
|
|
|
DRShift <= 1;
|
|
|
|
end 3'h3: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 1;
|
|
|
|
end 3'h4: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 1;
|
|
|
|
DRShift <= 1;
|
|
|
|
if (LS[3:0]==4'h4) SetFW <= DRDOut;
|
|
|
|
end 3'h5: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 1;
|
|
|
|
end 3'h6: begin
|
|
|
|
ARCLK <= 1;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 1;
|
|
|
|
if (LS[3:0]==4'h6) SetLim8M <= DRDOut;
|
|
|
|
end 3'h7: begin
|
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRShift <= 0;
|
|
|
|
end
|
|
|
|
endcase
|
2021-03-19 06:56:20 +00:00
|
|
|
DRDIn <= 0;
|
2021-03-19 20:38:48 +00:00
|
|
|
end else begin
|
2021-03-19 06:56:20 +00:00
|
|
|
ARCLK <= 0;
|
|
|
|
ARShift <= 0;
|
|
|
|
DRShift <= 1;
|
|
|
|
DRCLK <= 0;
|
|
|
|
DRDIn <= 0;
|
|
|
|
end
|
|
|
|
end
|
2021-03-15 17:40:59 +00:00
|
|
|
|
|
|
|
/* SDRAM data bus */
|
|
|
|
inout [7:0] SD = SDOE ? WRD[7:0] : 8'bZ;
|
|
|
|
reg [7:0] WRD;
|
|
|
|
reg SDOE = 0;
|
|
|
|
always @(posedge C25M) begin
|
|
|
|
// Shift { MISO, MOSI } in when InitActv. When ready, synchronize RD
|
2021-03-19 18:23:33 +00:00
|
|
|
if (~nRESout && LS[1]) WRD[7:0] <= { MISO, MOSI, WRD[5:0] };
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (PS==8) WRD[7:0] <= RD[7:0];
|
2021-03-15 17:40:59 +00:00
|
|
|
// Output data on SDRAM data bus only during init and when writing
|
2021-03-19 18:23:33 +00:00
|
|
|
SDOE <= ~nRESout || (RAMSpecWR && PS==8);
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
|
2021-03-19 10:45:31 +00:00
|
|
|
reg [2:0] PS = 0;
|
2021-03-19 18:23:33 +00:00
|
|
|
wire PSStart = nRESr && PS==0 && PHI0r1 && ~PHI0r2;
|
2021-03-15 17:40:59 +00:00
|
|
|
always @(posedge C25M) begin
|
2021-03-19 10:45:31 +00:00
|
|
|
if (PSStart) PS <= 1;
|
|
|
|
else if (PS==0) PS <= 0;
|
|
|
|
else PS <= PS+1;
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
|
2021-03-19 10:45:31 +00:00
|
|
|
/* Refresh state */
|
|
|
|
reg RefReqd = 0;
|
|
|
|
reg RefReady = 0;
|
|
|
|
always @(posedge C25M) begin
|
2021-03-19 18:23:33 +00:00
|
|
|
if (LS[6:0]==7'h00) RefReqd <= 1; // Reset RefDone every 128 C25M cycles (5.12 us)
|
2021-03-19 10:45:31 +00:00
|
|
|
else if (PS==0 && ~RefReqd) RefReqd <= 0;
|
|
|
|
end
|
|
|
|
|
2021-03-19 06:56:20 +00:00
|
|
|
/* SDRAM address/command */
|
2021-03-19 10:45:31 +00:00
|
|
|
output [1:0] SBA; assign SBA[1:0] =
|
2021-03-19 20:38:48 +00:00
|
|
|
Amux[2:1]==2'h0 ? 2'b00 : // mode register / "all"
|
|
|
|
Amux[2:1]==2'h1 ? 2'b00 : // FIXME: init row / col
|
|
|
|
Amux[2:1]==2'h2 ? 2'b10 : // ROM row / col
|
|
|
|
/* 2'h3 */ { 1'b0, Addr[23] & SetFW & ~SetLim8M }; // RAM row/col
|
|
|
|
output [12:0] SA;
|
|
|
|
assign SA[12] = Amux[2:0]==3'h6 && Addr[22] && SetFW;
|
|
|
|
/*assign SA[12:0] =
|
|
|
|
Amux[2:0]==3'h0 ? 13'b0001000100000 : // mode register
|
|
|
|
Amux[2:0]==3'h1 ? 13'b0011000100000 : // "all"
|
|
|
|
Amux[2:0]==3'h2 ? { 9'b001100010, LS[16:13] } : // init row
|
|
|
|
Amux[2:0]==3'h3 ? { 4'b0011, LS[12:4] } : // init col
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux[2:0]==3'h4 ? { 9'b000000000, Bank[1:0], RAcur[11:10] } : // ROM row
|
|
|
|
Amux[2:0]==3'h5 ? { 4'b0000, RAcur[9:1]} : // ROM col
|
2021-03-19 20:38:48 +00:00
|
|
|
Amux[2:0]==3'h6 ? { Addr[22] & SetFW,
|
|
|
|
Addr[21] & SetFW,
|
2021-03-19 10:59:22 +00:00
|
|
|
Addr[20] & SetFW,
|
|
|
|
Addr[19:10] } : // RAM row
|
2021-03-19 20:38:48 +00:00
|
|
|
{ 4'b0000, Addr[9:1] }; // RAM col
|
|
|
|
*/
|
2021-03-19 10:45:31 +00:00
|
|
|
output DQML; assign DQML =
|
|
|
|
Amux[2:0]==3'h0 ? 1'b1 : // mode register
|
|
|
|
Amux[2:0]==3'h1 ? 1'b1 : // "all"
|
|
|
|
Amux[2:0]==3'h2 ? 1'b1 : // FIXME: init row
|
|
|
|
Amux[2:0]==3'h3 ? LS[3] : // FIXME: init col
|
|
|
|
Amux[2:0]==3'h4 ? 1'b1 : // ROM row
|
|
|
|
Amux[2:0]==3'h5 ? RAcur[0]: // ROM col
|
|
|
|
Amux[2:0]==3'h6 ? 1'b1 : // RAM row
|
|
|
|
/* 3'h7 */ Addr[0]; // RAM col
|
2021-03-19 20:38:48 +00:00
|
|
|
output DQMH; assign DQMH =
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux[2:0]==3'h0 ? 1'b1 : // mode register
|
|
|
|
Amux[2:0]==3'h1 ? 1'b1 : // "all"
|
|
|
|
Amux[2:0]==3'h2 ? 1'b1 : // FIXME: init row
|
|
|
|
Amux[2:0]==3'h3 ? ~LS[3] : // FIXME: init col
|
|
|
|
Amux[2:0]==3'h4 ? 1'b1 : // ROM row
|
|
|
|
Amux[2:0]==3'h5 ? ~RAcur[0]: // ROM col
|
|
|
|
Amux[2:0]==3'h6 ? 1'b1 : // RAM row
|
|
|
|
/* 3'h7 */ ~Addr[0]; // RAM col
|
|
|
|
reg [2:0] Amux = 0;
|
2021-03-19 06:56:20 +00:00
|
|
|
output reg RCKE = 1;
|
|
|
|
output reg nRCS = 1;
|
|
|
|
output reg nRAS = 1;
|
|
|
|
output reg nCAS = 1;
|
|
|
|
output reg nSWE = 1;
|
2021-03-15 17:40:59 +00:00
|
|
|
always @(posedge C25M) begin
|
2021-03-19 10:45:31 +00:00
|
|
|
case (PS[2:0])
|
|
|
|
0: begin
|
2021-03-19 10:59:22 +00:00
|
|
|
if (PSStart) begin
|
2021-03-19 10:45:31 +00:00
|
|
|
// NOP CKE
|
2021-03-19 06:56:20 +00:00
|
|
|
RCKE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
nCAS <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
nSWE <= 1'b1;
|
|
|
|
Amux <= 3'b001;
|
|
|
|
end else if (RefReqd) begin
|
|
|
|
if (RCKE) begin
|
|
|
|
// AREF
|
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b0;
|
|
|
|
nRAS <= 1'b0;
|
|
|
|
nCAS <= 1'b0;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
Amux <= 3'b001;
|
|
|
|
end else begin
|
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
Amux <= 3'b001;
|
|
|
|
end
|
|
|
|
end else begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
Amux <= 3'b001;
|
|
|
|
end
|
|
|
|
end 1: begin
|
|
|
|
if (ROMSpecRD || RAMSpecSEL) begin
|
|
|
|
// ACT
|
2021-03-19 06:56:20 +00:00
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b0;
|
|
|
|
nRAS <= 1'b0;
|
2021-03-19 10:45:31 +00:00
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
end else begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
end
|
2021-03-19 10:45:31 +00:00
|
|
|
if (ROMSpecRD) Amux <= 3'b100;
|
|
|
|
else Amux <= 3'b110;
|
|
|
|
end 2: begin
|
|
|
|
if (ROMSpecRD || RAMSpecRD) begin
|
|
|
|
// RD
|
2021-03-19 06:56:20 +00:00
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b0;
|
|
|
|
nRAS <= 1'b0;
|
2021-03-19 10:45:31 +00:00
|
|
|
nCAS <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
nSWE <= 1'b1;
|
|
|
|
end else begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (ROMSpecRD) Amux <= 3'b101;
|
|
|
|
else Amux <= 3'b111;
|
|
|
|
end 3: begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b0;
|
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux <= 3'b001;
|
|
|
|
end 4: begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b0;
|
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux <= 3'b001;
|
|
|
|
end 5: begin
|
|
|
|
if (RAMSpecWR && DEVSELr) begin
|
|
|
|
// WR AP
|
2021-03-19 06:56:20 +00:00
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b0;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b0;
|
|
|
|
nSWE <= 1'b0;
|
|
|
|
end else begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// NOP CKE
|
|
|
|
RCKE <= 1'b1;
|
2021-03-19 06:56:20 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
|
|
|
end
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux <= 3'b111;
|
|
|
|
end 6: begin
|
2021-03-19 18:23:33 +00:00
|
|
|
RCKE <= 1'b1;
|
2021-03-15 17:40:59 +00:00
|
|
|
nRCS <= 1'b1;
|
|
|
|
nRAS <= 1'b1;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b1;
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux <= 3'b001;
|
|
|
|
end 7: begin
|
2021-03-19 18:23:33 +00:00
|
|
|
// PC all
|
|
|
|
RCKE <= 1'b1;
|
|
|
|
nRCS <= 1'b0;
|
|
|
|
nRAS <= 1'b0;
|
|
|
|
nCAS <= 1'b1;
|
|
|
|
nSWE <= 1'b0;
|
2021-03-19 10:45:31 +00:00
|
|
|
Amux <= 3'b001;
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
2021-03-19 10:45:31 +00:00
|
|
|
endcase
|
2021-03-15 17:40:59 +00:00
|
|
|
end
|
|
|
|
endmodule
|