GottaGoFaZt3r/RTL/sdram.v
Matt Harlum 15ff8132f5 Tweak DTACK
On reads, DTACK will now come out 3 clocks after the READ command to the RAM
With a CAS latency of 2, the read data will be valid at READ+2

The A4091 latches data as soon as DTACK is seen, so this delay was needed to make sure the A4091 correctly latches data from GottaGoFaZt3r
2024-09-28 11:13:16 +12:00

299 lines
7.7 KiB
Verilog

/*
GottaGoFaZt3r
Copyright 2022 Matthew Harlum
GottaGoFaZt3r is licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License.
You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.
*/
`timescale 1ns / 1ps
module SDRAM(
input [27:2] ADDR,
input [3:0] DS_n,
input ram_cycle,
input RESET_n,
input RW,
input CLK,
input ECLK,
input configured,
input [1:0] z3_state,
output reg [1:0] BA,
output reg [12:0] MADDR,
output reg CAS_n,
output reg RAS_n,
output reg [1:0] CS_n,
output reg WE_n,
output reg CKE,
output reg [3:0] DQM_n,
output reg dtack
);
`include "globalparams.vh"
`define cmd(ARG) \
{RAS_n, CAS_n, WE_n} <= ARG;
localparam tRP = 2;
localparam tRCD = 2;
localparam tRFC = 4;
localparam CAS_LATENCY = 3'd2;
// RAS CAS WE
localparam cmd_nop = 3'b111,
cmd_active = 3'b011,
cmd_read = 3'b101,
cmd_write = 3'b100,
cmd_burst_terminate = 3'b110,
cmd_precharge = 3'b010,
cmd_auto_refresh = 3'b001,
cmd_load_mode_reg = 3'b000;
localparam mode_register = {
3'b0, // M10-12 - Reserved
1'b1, // M9 - No burst mode, Single access
2'b0, // M8-7 - Standard operation
CAS_LATENCY, // M6-4 - CAS Latency
1'b0, // M3 - Burst type
3'b0 // M2-0 - Burst length
};
reg [3:0] refresh_timer;
reg [1:0] refresh_request;
reg refreshing;
wire refreshreset = !refreshing & RESET_n;
// Refresh roughly every 7.1uS / 8192 refreshes in 58ms
always @(posedge ECLK or negedge refreshreset) begin
if (!refreshreset) begin
refresh_timer <= 4'h4;
end else begin
if (refresh_timer > 0) begin
refresh_timer <= refresh_timer - 1;
end
end
end
always @(posedge CLK or negedge RESET_n) begin
if (!RESET_n) begin
refresh_request <= 0;
end else begin
refresh_request <= {refresh_request[0], refresh_timer == 0};
end
end
localparam init_poweron = 4'b0000,
init_precharge = init_poweron + 1,
init_precharge_wait = init_precharge + 1,
init_load_mode = init_precharge_wait + 1,
start_refresh = init_load_mode + 1,
refresh_wait = start_refresh + 1,
idle = refresh_wait + 1,
active = idle + 1,
active_wait = active + 1,
data_read = active_wait + 1,
data_write = data_read + 1,
data_hold = data_write + 1,
precharge_wait = data_hold + 1;
(* fsm_encoding = "compact" *) reg [3:0] ram_state;
reg init_refreshed;
reg init_done;
reg [1:0] timer_tRFC;
always @(posedge CLK or negedge RESET_n) begin
if (!RESET_n) begin
ram_state <= init_poweron;
init_refreshed <= 0;
init_done <= 0;
dtack <= 0;
CS_n <= 2'b11;
CKE <= 1;
DQM_n <= 4'b1111;
end else begin
case (ram_state)
// Showtime!
//
init_poweron:
begin
`cmd(cmd_nop)
CS_n[1:0] <= 2'b00;
ram_state <= init_precharge;
end
// Init precharge
//
init_precharge:
begin
`cmd(cmd_precharge)
MADDR[10] <= 1'b1; // Precharge all banks
ram_state <= init_precharge_wait;
end
// Init precharge wait
//
// Wait for precharge to complete
init_precharge_wait:
begin
`cmd(cmd_nop)
ram_state <= start_refresh;
end
// Load mode register
//
init_load_mode:
begin
`cmd(cmd_load_mode_reg)
init_done <= 1;
MADDR[12:0] <= mode_register;
ram_state <= precharge_wait;
end
// Refresh
//
// Start auto-refresh
start_refresh:
begin
`cmd(cmd_auto_refresh)
timer_tRFC <= 2'b11;
refreshing <= 1;
CS_n <= 2'b00; // Refresh all chips
ram_state <= refresh_wait;
end
// Refresh wait
//
// Wait for refresh to finish
// During RAM initialization it will refresh twice then go to load the mode register
refresh_wait:
begin
`cmd(cmd_nop)
if (timer_tRFC > 0) begin
timer_tRFC <= timer_tRFC - 1;
ram_state <= refresh_wait;
end else begin
if (!init_done) begin
if (init_refreshed) begin
// If we just finished the second init refresh go load the mode register
ram_state <= init_load_mode;
end else begin
// Do a second init refresh
ram_state <= start_refresh;
init_refreshed <= 1;
end
end else begin
ram_state <= idle;
end
end
end
// Idle
//
// Refresh has priority over memory access
idle:
begin
`cmd(cmd_nop)
refreshing <= 0;
DQM_n <= 4'b1111;
CS_n <= 2'b11;
if (refresh_request[1]) begin
ram_state <= start_refresh;
end else if (ram_cycle && (z3_state == Z3_START || z3_state == Z3_DATA)) begin
ram_state <= active;
end else begin
ram_state <= idle;
end
end
// Active
//
// Activate the row/bank
active:
begin
`cmd(cmd_active)
ram_state <= active_wait;
MADDR[12:0] <= ADDR[23:11];
BA[1:0] <= ADDR[25:24];
CS_n[1:0] <= {ADDR[26],~ADDR[26]};
end
// Wait
//
// Wait for tRCD and also wait until we see data strobes before committing writes
active_wait:
begin
`cmd(cmd_nop)
if (z3_state == Z3_DATA) begin
// dtack <= 1;
if (RW) begin
ram_state <= data_read;
end else begin
dtack <= 1;
ram_state <= data_write;
end
end else begin
ram_state <= active_wait;
end
end
// Read
//
data_read:
begin
`cmd(cmd_read)
// Uses A27 as MA9 so that memory is mirrored above 128MB when using 4x32MB chips
// Kickstart will detect the mirror and add 128MB to the free pool rather than 256MB
// This allows for the board to be assembled with 128MB or 256MB without needing separate firmware.
MADDR[12:0] <= {3'b001,ADDR[27], ADDR[10:2]};
// Reads must return a full long regardless of DS (Zorro III Bus Specifications pg 3-3)
DQM_n[3:0] <= 4'b0000;
ram_state <= data_hold;
end
// Write
//
// Commit the write then go back to idle state
data_write:
begin
`cmd(cmd_write)
MADDR[12:0] <= {3'b001,ADDR[27], ADDR[10:2]};
DQM_n[3:0] <= DS_n[3:0];
ram_state <= precharge_wait;
end
// Hold
//
// On read cycles, take CKE low until the end of the Zorro cycle in order to hold the output
data_hold:
begin
`cmd(cmd_nop)
dtack <= 1;
if (z3_state != Z3_IDLE) begin
CKE <= 0;
ram_state <= data_hold;
end else begin
CKE <= 1;
ram_state <= precharge_wait;
end
end
// Wait for auto-precharge to complete
precharge_wait:
begin
`cmd(cmd_nop)
dtack <= 0;
ram_state <= idle;
end
endcase
end
end
endmodule