Files
TSConf_MiST/rtl/dram/sdram.v
Eugene Lozovoy 66bfce85d5 add gs support
2024-09-14 16:41:57 +03:00

233 lines
8.4 KiB
Verilog

// 25 26 27 28 29 30 31 20 21 22 23 24 25
// cpu_strobe ________________________________________________________________/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\_______________________________________________________________
// cyc ‾‾‾‾\_____________________________________________________________________________________________________________/‾‾‾‾‾‾‾‾‾\____
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// 5.95ns
//
// REFRESH RASCAS
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// clk_ram ‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____
// REFRSH
//
// READ+NOP RAS CAS latch set do
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// clk_ram ‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____
// ACT READ DQDQDQDQD
//
// WRITE+NOP RAS CASWEDQ
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// clk_ram ‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____
// ACT WRITE
//
// NOP+READ RAS CAS latch set do
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// clk_ram ‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____
// ACT READ DQDQDQDQD
//
// NOP+WRITE RAS CASWEDQ
// clk_sys ____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾
// clk_ram ‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____/‾‾‾‾\____
// ACT WRITE
//
module sdram
(
input clk,
input cyc,
// Memory port 1
input port1_curr_cpu,
input [1:0] port1_bsel,
input [23:0] port1_a,
input [15:0] port1_di,
output reg [15:0] port1_do,
output reg [15:0] port1_do_cpu,
input port1_req,
input port1_rnw,
// Memory port 2
input [1:0] port2_bsel,
input [23:0] port2_a,
input [15:0] port2_di,
output reg [15:0] port2_do,
input port2_req,
input port2_rnw,
output reg port2_ack = 0,
// SDRAM Pin
inout reg [15:0] SDRAM_DQ,
output reg [12:0] SDRAM_A = 0,
output reg [1:0] SDRAM_BA = 0,
output SDRAM_DQML,
output SDRAM_DQMH,
output SDRAM_nCS,
output SDRAM_nCAS,
output SDRAM_nRAS,
output SDRAM_nWE,
output SDRAM_CKE,
output SDRAM_CLK
);
reg [2:0] sdr_cmd;
localparam SdrCmd_xx = 3'b111; // no operation
localparam SdrCmd_ac = 3'b011; // activate
localparam SdrCmd_rd = 3'b101; // read
localparam SdrCmd_wr = 3'b100; // write
localparam SdrCmd_pr = 3'b010; // precharge all
localparam SdrCmd_re = 3'b001; // refresh
localparam SdrCmd_ms = 3'b000; // mode regiser set
reg [5:0] state = 0;
reg [15:0] data;
reg [8:0] col;
reg [23:0] Ar1, Ar2;
reg [1:0] dqm1, dqm2;
reg rq1, rq2;
reg rd1, rd2 = 0;
always @(posedge clk) begin
sdr_cmd <= SdrCmd_xx;
data <= SDRAM_DQ;
SDRAM_DQ <= 16'bZ;
state <= state + 1'd1;
port2_ack <= 1'b0;
case (state)
// Init
0: begin
sdr_cmd <= SdrCmd_pr; // PRECHARGE
end
// REFRESH
3,10: begin
sdr_cmd <= SdrCmd_re;
end
// LOAD MODE REGISTER
17: begin
sdr_cmd <= SdrCmd_ms;
SDRAM_A <= {3'b000, 1'b1, 2'b00, 3'b010, 1'b0, 3'b000};
end
// Idle
24: begin
state <= state;
Ar1 <= port1_a;
Ar2 <= port2_a;
dqm1 <= port1_rnw ? 2'b00 : ~port1_bsel;
dqm2 <= port2_rnw ? 2'b00 : ~port2_bsel;
rq1 <= port1_req;
rd1 <= port1_req & port1_rnw;
rq2 <= port2_req;
rd2 <= port2_req & port2_rnw;
if (cyc)
state <= state + 1'd1;
end
// Start - activate (port1) or refresh
25: begin
if (rq1) begin
{SDRAM_BA,SDRAM_A,col} <= Ar1;
sdr_cmd <= SdrCmd_ac;
end
else if (rq2) begin
// start at state 28
end
else begin
sdr_cmd <= SdrCmd_re;
state <= 19;
end
end
// Single read/write (port1) - with auto precharge
27: begin
SDRAM_A <= {dqm1, 2'b1x, col};
if (rq1) begin
if (rd1) begin
sdr_cmd <= SdrCmd_rd;
end
else begin
sdr_cmd <= SdrCmd_wr;
SDRAM_DQ <= port1_di;
end
end
end
// Start - activate (port2) or refresh
28: begin
if (rq2) begin
{SDRAM_BA,SDRAM_A,col} <= Ar2;
sdr_cmd <= SdrCmd_ac;
end
end
// Latch read (port 1) and Single read/write (port2) - with auto precharge
31: begin
if (rd1) begin
port1_do <= data;
if (port1_curr_cpu) port1_do_cpu <= data;
end
SDRAM_A <= {dqm2, 2'b1x, col};
if (rq2) begin
if (rd2) begin
sdr_cmd <= SdrCmd_rd;
end
else begin
sdr_cmd <= SdrCmd_wr;
SDRAM_DQ <= port2_di;
port2_ack <= 1'b1;
end
end
state <= 20;
end
// Latch read (port 2)
23: begin
if (rd2) begin
port2_do <= data;
port2_ack <= 1'b1;
end
end
endcase
end
assign SDRAM_CKE = 1;
assign SDRAM_nCS = 0;
assign SDRAM_nRAS = sdr_cmd[2];
assign SDRAM_nCAS = sdr_cmd[1];
assign SDRAM_nWE = sdr_cmd[0];
assign SDRAM_DQML = SDRAM_A[11];
assign SDRAM_DQMH = SDRAM_A[12];
altddio_out
#(
.extend_oe_disable("OFF"),
.intended_device_family("Cyclone III"),
.invert_output("OFF"),
.lpm_hint("UNUSED"),
.lpm_type("altddio_out"),
.oe_reg("UNREGISTERED"),
.power_up_high("OFF"),
.width(1)
)
sdramclk_ddr
(
.datain_h(1'b0),
.datain_l(1'b1),
.outclock(clk),
.dataout(SDRAM_CLK),
.aclr(1'b0),
.aset(1'b0),
.oe(1'b1),
.outclocken(1'b1),
.sclr(1'b0),
.sset(1'b0)
);
endmodule