1 ---------------------------------------------------------------------
2 -- TITLE: DDR SDRAM Interface
3 -- AUTHORS: Steve Rhoads (rhoadss@yahoo.com)
4 -- DATE CREATED: 7/26/07
5 -- FILENAME: ddr_ctrl.vhd
6 -- PROJECT: Plasma CPU core
7 -- COPYRIGHT: Software placed into the public domain by the author.
8 -- Software 'as is' without warranty. Author liable for nothing.
10 -- Double Data Rate Sychronous Dynamic Random Access Memory Interface
12 -- For: 64 MB = MT46V32M16, 512Mb, 32Mb x 16 (default)
13 -- ROW = address(25 downto 13)
14 -- BANK = address(12 downto 11)
15 -- COL = address(10 downto 2)
17 -- Changes are needed for 32 MB = MT46V16M16, 256Mb, 16Mb x 16
18 -- ROW = address(24 downto 12) -- 25 ignored
19 -- BANK = address(11 downto 10)
20 -- COL = address(9 downto 2) --also change ddr_init.c
22 -- Changes are needed for 128 MB = MT46V64M16, 1Gb, 64Mb x 16
23 -- ROW = address(26 downto 14)
24 -- BANK = address(13 downto 12)
25 -- COL = address(11 downto 2) --also change ddr_init.c
27 -- Requires CAS latency=2; burst size=2.
28 -- Requires clk changes on rising_edge(clk_2x).
29 -- Requires active, address, byte_we, data_w stable throughout transfer.
30 -- DLL mode requires 77MHz. Non-DLL mode runs at 25 MHz.
32 -- cycle_cnt 777777770000111122223333444455556666777777777777
33 -- clk_2x --__--__--__--__--__--__--__--__--__--__--__--__
34 -- clk ____----____----____----____----____----____----
35 -- SD_CLK ----____----____----____----____----____----____
36 -- cmd ____write+++WRITE+++____________________________
37 -- SD_DQ ~~~~~~~~~~~~~~uuuullllUUUULLLL~~~~~~~~~~~~~~~~~~
39 -- cycle_cnt 777777770000111122223333444455556666777777777777
40 -- clk_2x --__--__--__--__--__--__--__--__--__--__--__--__
41 -- clk ____----____----____----____----____----____----
42 -- SD_CLK ----____----____----____----____----____----____
43 -- cmd ____read++++________________________read++++____
44 -- SD_DQ ~~~~~~~~~~~~~~~~~~~~~~~~uuuullll~~~~~~~~~~~~~~~~
45 -- SD_DQnDLL ~~~~~~~~~~~~~~~~~~~~~~~~~~uuuullll~~~~~~~~~~~~~~
46 -- pause ____------------------------________------------
48 -- Must run DdrInit() to initialize DDR chip.
49 -- Read Micron DDR SDRAM MT46V32M16 data sheet for more details.
50 ---------------------------------------------------------------------
52 use ieee.std_logic_1164.all;
53 use ieee.std_logic_unsigned.all;
54 use ieee.std_logic_arith.all;
55 use work.mlite_pack.all;
60 clk_2x : in std_logic;
61 reset_in : in std_logic;
63 address : in std_logic_vector(25 downto 2);
64 byte_we : in std_logic_vector(3 downto 0);
65 data_w : in std_logic_vector(31 downto 0);
66 data_r : out std_logic_vector(31 downto 0);
67 active : in std_logic;
68 no_start : in std_logic;
69 no_stop : in std_logic;
70 pause : out std_logic;
72 SD_CK_P : out std_logic; --clock_positive
73 SD_CK_N : out std_logic; --clock_negative
74 SD_CKE : out std_logic; --clock_enable
76 SD_BA : out std_logic_vector(1 downto 0); --bank_address
77 SD_A : out std_logic_vector(12 downto 0); --address(row or col)
78 SD_CS : out std_logic; --chip_select
79 SD_RAS : out std_logic; --row_address_strobe
80 SD_CAS : out std_logic; --column_address_strobe
81 SD_WE : out std_logic; --write_enable
83 SD_DQ : inout std_logic_vector(15 downto 0); --data
84 SD_UDM : out std_logic; --upper_byte_enable
85 SD_UDQS : inout std_logic; --upper_data_strobe
86 SD_LDM : out std_logic; --low_byte_enable
87 SD_LDQS : inout std_logic); --low_data_strobe
90 architecture logic of ddr_ctrl is
92 --Commands for bits RAS & CAS & WE
93 subtype command_type is std_logic_vector(2 downto 0);
94 constant COMMAND_LMR : command_type := "000";
95 constant COMMAND_AUTO_REFRESH : command_type := "001";
96 constant COMMAND_PRECHARGE : command_type := "010";
97 constant COMMAND_ACTIVE : command_type := "011";
98 constant COMMAND_WRITE : command_type := "100";
99 constant COMMAND_READ : command_type := "101";
100 constant COMMAND_TERMINATE : command_type := "110";
101 constant COMMAND_NOP : command_type := "111";
103 subtype ddr_state_type is std_logic_vector(3 downto 0);
104 constant STATE_POWER_ON : ddr_state_type := "0000";
105 constant STATE_IDLE : ddr_state_type := "0001";
106 constant STATE_ROW_ACTIVATE : ddr_state_type := "0010";
107 constant STATE_ROW_ACTIVE : ddr_state_type := "0011";
108 constant STATE_READ : ddr_state_type := "0100";
109 constant STATE_READ2 : ddr_state_type := "0101";
110 constant STATE_READ3 : ddr_state_type := "0110";
111 constant STATE_PRECHARGE : ddr_state_type := "0111";
112 constant STATE_PRECHARGE2 : ddr_state_type := "1000";
114 signal state_prev : ddr_state_type;
115 signal refresh_cnt : std_logic_vector(7 downto 0);
116 signal data_write2 : std_logic_vector(47 downto 0); --write pipeline
117 signal byte_we_reg2 : std_logic_vector(5 downto 0); --write pipeline
118 signal write_active : std_logic;
119 signal write_prev : std_logic;
120 signal cycle_count : std_logic_vector(2 downto 0); --half clocks since op
121 signal cycle_count2 : std_logic_vector(2 downto 0); --delayed by quarter clock
122 signal cke_reg : std_logic;
123 signal clk_p : std_logic;
124 signal bank_open : std_logic_vector(3 downto 0);
125 signal data_read : std_logic_vector(31 downto 0);
128 ddr_proc: process(clk, clk_p, clk_2x, reset_in,
129 address, byte_we, data_w, active, no_start, no_stop,
130 SD_DQ, SD_UDQS, SD_LDQS,
131 state_prev, refresh_cnt,
132 byte_we_reg2, data_write2,
133 cycle_count, cycle_count2, write_prev,
134 write_active, cke_reg, bank_open,
136 type address_array_type is array(3 downto 0) of std_logic_vector(12 downto 0);
137 variable address_row : address_array_type;
138 variable command : std_logic_vector(2 downto 0); --RAS & CAS & WE
139 variable bank_index : integer;
140 variable state_current : ddr_state_type;
144 command := COMMAND_NOP;
145 bank_index := conv_integer(address(12 downto 11));
146 state_current := state_prev;
148 --DDR state machine to determine state_current and command
150 when STATE_POWER_ON =>
152 if byte_we /= "0000" then
153 command := address(6 downto 4); --LMR="000"
155 state_current := STATE_IDLE; --read transistions to STATE_IDLE
160 if refresh_cnt(7) = '1' then
161 state_current := STATE_PRECHARGE;
162 command := COMMAND_AUTO_REFRESH;
163 elsif active = '1' and no_start = '0' then
164 state_current := STATE_ROW_ACTIVATE;
165 command := COMMAND_ACTIVE;
168 when STATE_ROW_ACTIVATE =>
169 state_current := STATE_ROW_ACTIVE;
171 when STATE_ROW_ACTIVE =>
172 if refresh_cnt(7) = '1' then
173 if write_prev = '0' then
174 state_current := STATE_PRECHARGE;
175 command := COMMAND_PRECHARGE;
177 elsif active = '1' and no_start = '0' then
178 if bank_open(bank_index) = '0' then
179 state_current := STATE_ROW_ACTIVATE;
180 command := COMMAND_ACTIVE;
181 elsif address(25 downto 13) /= address_row(bank_index) then
182 if write_prev = '0' then
183 state_current := STATE_PRECHARGE;
184 command := COMMAND_PRECHARGE;
187 if byte_we /= "0000" then
188 command := COMMAND_WRITE;
189 elsif write_prev = '0' then
190 state_current := STATE_READ;
191 command := COMMAND_READ;
197 state_current := STATE_READ2;
200 state_current := STATE_READ3;
203 if no_stop = '0' then
204 state_current := STATE_ROW_ACTIVE;
207 when STATE_PRECHARGE =>
208 state_current := STATE_PRECHARGE2;
210 when STATE_PRECHARGE2 =>
211 state_current := STATE_IDLE;
214 state_current := STATE_IDLE;
215 end case; --state_prev
217 --rising_edge(clk) domain registers
218 if reset_in = '1' then
219 state_prev <= STATE_POWER_ON;
221 refresh_cnt <= ZERO(7 downto 0);
225 elsif rising_edge(clk) then
231 if command = COMMAND_WRITE then
233 elsif cycle_count2(2 downto 1) = "11" then
237 if command = COMMAND_WRITE then
239 elsif cycle_count2 = "100" then
243 if command = COMMAND_ACTIVE then
244 bank_open(bank_index) <= '1';
245 address_row(bank_index) := address(25 downto 13);
248 if command = COMMAND_PRECHARGE then
252 if command = COMMAND_AUTO_REFRESH then
253 refresh_cnt <= ZERO(7 downto 0);
255 refresh_cnt <= refresh_cnt + 1;
258 state_prev <= state_current;
260 end if; --rising_edge(clk)
262 --rising_edge(clk_2x) domain registers
263 if reset_in = '1' then
264 cycle_count <= "000";
265 elsif rising_edge(clk_2x) then
267 if (command = COMMAND_READ or command = COMMAND_WRITE) and clk = '1' then
268 cycle_count <= "000";
269 elsif cycle_count /= "111" then
270 cycle_count <= cycle_count + 1;
273 clk_p <= clk; --earlier version of not clk
275 --Read data (DLL disabled)
276 if cycle_count = "100" then
277 data_read(31 downto 16) <= SD_DQ; --data
278 elsif cycle_count = "101" then
279 data_read(15 downto 0) <= SD_DQ;
283 --falling_edge(clk_2x) domain registers
284 if reset_in = '1' then
285 cycle_count2 <= "000";
286 data_write2 <= ZERO(15 downto 0) & ZERO;
287 byte_we_reg2 <= "000000";
288 elsif falling_edge(clk_2x) then
289 cycle_count2 <= cycle_count;
293 data_write2 <= data_write2(31 downto 16) & data_w;
294 byte_we_reg2 <= byte_we_reg2(3 downto 2) & byte_we;
296 data_write2(47 downto 16) <= data_write2(31 downto 0);
297 byte_we_reg2(5 downto 2) <= byte_we_reg2(3 downto 0);
300 --Read data (DLL enabled)
301 --if cycle_count = "100" then
302 -- data_read(31 downto 16) <= SD_DQ; --data
303 --elsif cycle_count = "101" then
304 -- data_read(15 downto 0) <= SD_DQ;
311 if write_active = '1' then
312 SD_UDQS <= clk_p; --upper_data_strobe
313 SD_LDQS <= clk_p; --low_data_strobe
314 SD_DQ <= data_write2(47 downto 32); --data
315 SD_UDM <= not byte_we_reg2(5); --upper_byte_enable
316 SD_LDM <= not byte_we_reg2(4); --low_byte_enable
318 SD_UDQS <= 'Z'; --upper_data_strobe
319 SD_LDQS <= 'Z'; --low_data_strobe
320 SD_DQ <= "ZZZZZZZZZZZZZZZZ"; --data
325 --DDR control signals
326 SD_CK_P <= clk_p; --clock_positive
327 SD_CK_N <= not clk_p; --clock_negative
328 SD_CKE <= cke_reg; --clock_enable
330 SD_BA <= address(12 downto 11); --bank_address
331 if command = COMMAND_ACTIVE or state_current = STATE_POWER_ON then
332 SD_A <= address(25 downto 13); --address row
333 elsif command = COMMAND_READ or command = COMMAND_WRITE then
334 SD_A <= "000" & address(10 downto 2) & "0"; --address col
336 SD_A <= "0010000000000"; --PERCHARGE all banks
339 SD_CS <= not cke_reg; --chip_select
340 SD_RAS <= command(2); --row_address_strobe
341 SD_CAS <= command(1); --column_address_strobe
342 SD_WE <= command(0); --write_enable
344 if active = '1' and state_current /= STATE_POWER_ON and
345 command /= COMMAND_WRITE and state_prev /= STATE_READ3 then
351 end process; --ddr_proc
353 end; --architecture logic