]> rtime.felk.cvut.cz Git - fpga/plasma.git/blob - vhdl/ddr_ctrl.vhd
Local copy of Plasma MIPS project.
[fpga/plasma.git] / vhdl / ddr_ctrl.vhd
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.
9 -- DESCRIPTION:
10 --    Double Data Rate Sychronous Dynamic Random Access Memory Interface
11 --
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)
16 --
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
21 --
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
26 --
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.
31 --
32 -- cycle_cnt 777777770000111122223333444455556666777777777777
33 -- clk_2x    --__--__--__--__--__--__--__--__--__--__--__--__
34 -- clk       ____----____----____----____----____----____----
35 -- SD_CLK    ----____----____----____----____----____----____
36 -- cmd       ____write+++WRITE+++____________________________
37 -- SD_DQ     ~~~~~~~~~~~~~~uuuullllUUUULLLL~~~~~~~~~~~~~~~~~~
38 --
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     ____------------------------________------------
47 --
48 -- Must run DdrInit() to initialize DDR chip.
49 -- Read Micron DDR SDRAM MT46V32M16 data sheet for more details.
50 ---------------------------------------------------------------------
51 library ieee;
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;
56
57 entity ddr_ctrl is
58    port(
59       clk      : in std_logic;
60       clk_2x   : in std_logic;
61       reset_in : in std_logic;
62
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;
71
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
75
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
82
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
88 end; --entity ddr
89
90 architecture logic of ddr_ctrl is
91
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";
102
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";
113
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);
126
127 begin
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,
135                      data_read)
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;
141
142    begin
143    
144       command := COMMAND_NOP;
145       bank_index := conv_integer(address(12 downto 11));
146       state_current := state_prev;
147       
148       --DDR state machine to determine state_current and command
149       case state_prev is
150          when STATE_POWER_ON =>
151             if active = '1' then
152                if byte_we /= "0000" then
153                   command := address(6 downto 4); --LMR="000"
154                else
155                   state_current := STATE_IDLE;  --read transistions to STATE_IDLE
156                end if;
157             end if;
158
159          when 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;
166             end if;
167             
168          when STATE_ROW_ACTIVATE =>
169             state_current := STATE_ROW_ACTIVE;
170
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;
176                end if;
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;
185                   end if;
186                else
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;
192                   end if;
193                end if;
194             end if;
195
196          when STATE_READ =>
197             state_current := STATE_READ2;
198
199          when STATE_READ2 =>
200             state_current := STATE_READ3;
201
202          when STATE_READ3 =>
203             if no_stop = '0' then
204                state_current := STATE_ROW_ACTIVE;
205             end if;
206
207          when STATE_PRECHARGE =>
208             state_current := STATE_PRECHARGE2;
209
210          when STATE_PRECHARGE2 =>
211             state_current := STATE_IDLE;
212
213          when others =>
214             state_current := STATE_IDLE;
215       end case; --state_prev
216       
217       --rising_edge(clk) domain registers
218       if reset_in = '1' then
219          state_prev   <= STATE_POWER_ON;
220          cke_reg      <= '0';
221          refresh_cnt  <= ZERO(7 downto 0);
222          write_prev   <= '0';
223          write_active <= '0';
224          bank_open    <= "0000";
225       elsif rising_edge(clk) then
226
227          if active = '1' then
228             cke_reg <= '1';
229          end if;
230
231          if command = COMMAND_WRITE then
232             write_prev <= '1';
233          elsif cycle_count2(2 downto 1) = "11" then
234             write_prev <= '0';
235          end if;
236
237          if command = COMMAND_WRITE then
238             write_active <= '1';
239          elsif cycle_count2 = "100" then
240             write_active <= '0';
241          end if;
242
243          if command = COMMAND_ACTIVE then
244             bank_open(bank_index) <= '1';
245             address_row(bank_index) := address(25 downto 13);
246          end if;
247          
248          if command = COMMAND_PRECHARGE then
249             bank_open <= "0000";
250          end if;
251          
252          if command = COMMAND_AUTO_REFRESH then
253             refresh_cnt <= ZERO(7 downto 0);
254          else
255             refresh_cnt <= refresh_cnt + 1;
256          end if;
257          
258          state_prev <= state_current;
259
260       end if; --rising_edge(clk)
261
262       --rising_edge(clk_2x) domain registers
263       if reset_in = '1' then
264          cycle_count <= "000";
265       elsif rising_edge(clk_2x) then
266          --Cycle_count
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;
271          end if;
272          
273          clk_p <= clk;  --earlier version of not clk         
274          
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;
280          end if;
281       end if;
282
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;
290
291          --Write pipeline
292          if clk = '0' then
293             data_write2 <= data_write2(31 downto 16) & data_w;
294             byte_we_reg2 <= byte_we_reg2(3 downto 2) & byte_we;
295          else
296             data_write2(47 downto 16) <= data_write2(31 downto 0);
297             byte_we_reg2(5 downto 2) <= byte_we_reg2(3 downto 0);
298          end if;
299
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;
305          --end if;
306       end if;
307       
308       data_r <= data_read;
309
310       --Write data
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
317       else
318          SD_UDQS <= 'Z';               --upper_data_strobe 
319          SD_LDQS <= 'Z';               --low_data_strobe
320          SD_DQ <= "ZZZZZZZZZZZZZZZZ";  --data
321          SD_UDM <= 'Z';
322          SD_LDM <= 'Z';
323       end if;
324
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
329
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
335       else
336          SD_A <= "0010000000000";      --PERCHARGE all banks
337       end if;
338
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
343
344       if active = '1' and state_current /= STATE_POWER_ON and
345          command /= COMMAND_WRITE and state_prev /= STATE_READ3 then
346          pause <= '1';
347       else
348          pause <= '0';
349       end if;
350
351    end process; --ddr_proc
352    
353 end; --architecture logic
354