OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [sdram2hibi/] [1.0/] [vhd/] [sdram_controller_de2.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : sdram_controller, modified for DE2 by A.Alhonen.
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : sdram_controller.vhd
6
-- Author     : 
7
-- Company    : 
8
-- Created    : 2005-06-08
9
-- Platform   : 
10
-- Standard   : VHDL'87
11
-------------------------------------------------------------------------------
12
-- Description: Altera DE2 uses A2V64S40TCP SDRAM.
13
-------------------------------------------------------------------------------
14
-- Copyright (c) 2005 
15
-------------------------------------------------------------------------------
16
-- Revisions  :
17
-- Date        Version  Author  Description
18
-- 2005-06-08  1.0      penttin5        Created
19
--
20
-- 2005-07-12  1.1      penttin5        Split command_in port to command_in,
21
--                                        address_in, data_amount_in and
22
--                                        byte_select_in.
23
--                                      Changed behavior
24
--                                        If output fifo is full in read
25
--                                        operation or input fifo is empty in
26
--                                        write operation, stop operation and
27
--                                        go to idle to have a new command.
28
--                               AA 2012: Why?! I decided not to fix it here
29
--                                        because apparently there is some
30
--                                        reason to this.
31
--                                      Data_amount_in width is now generic
32
-- 19.04.2007           penttin5        Added generic sim_ena_g to make
33
--                                        simulation easier. When sim_ena_g is
34
--                                        1, the long init wait is skipped
35
-- 12.08.2009           alhonena        Started modifying for DE2: 16-bit data,
36
--                                      different timing.
37
-- 16.07.2011           alhonena        Continued modifying for DE2
38
-------------------------------------------------------------------------------
39
--
40
-- NOTE!!! The following assignments must be used in Quartus to
41
--         ensure correct operation:
42
--
43
--         In Assignment Editor: Logic options
44
--
45
-- from    to                     Assignment name              Value Enabled
46
--         sdram_data_out_r     : fast output register         On    Yes
47
--         write_on_r           : fast output enable register  On    Yes
48
--         data_out             : fast input register          On    Yes
49
--
50
-- Use node finder to find these nodes.
51
--
52
-------------------------------------------------------------------------------
53
library ieee;
54
use ieee.std_logic_1164.all;
55
use ieee.std_logic_arith.all;
56
use ieee.std_logic_unsigned.all;
57
 
58
entity sdram_controller is
59
  generic (
60
    clk_freq_mhz_g      : integer := 143;  -- clock frequency in MHz
61
    mem_addr_width_g    : integer := 22;
62
    amountw_g           : integer := 22;
63
    block_read_length_g : integer := 640;
64
    sim_ena_g           : integer := 0  -- skips the init wait phase
65
    );
66
 
67
  port (
68
    clk   : in std_logic;
69
    rst_n : in std_logic;
70
 
71
    command_in             : in    std_logic_vector(1 downto 0);
72
    address_in             : in    std_logic_vector(mem_addr_width_g-1 downto 0);
73
    data_amount_in         : in    std_logic_vector(amountw_g - 1
74
                                                    downto 0);
75
    byte_select_in         : in    std_logic_vector(1 downto 0);  -- ACTIVE LOW!
76
    input_empty_in         : in    std_logic;
77
    input_one_d_in         : in    std_logic;
78
    output_full_in         : in    std_logic;
79
    data_in                : in    std_logic_vector(15 downto 0);
80
    write_on_out           : out   std_logic;
81
    busy_out               : out   std_logic;
82
    output_we_out          : out   std_logic;  -- this is combinational
83
    input_re_out           : out   std_logic;
84
    data_out               : out   std_logic_vector(15 downto 0);
85
    sdram_data_inout       : inout std_logic_vector(15 downto 0);
86
    sdram_cke_out          : out   std_logic;
87
    sdram_cs_n_out         : out   std_logic;
88
    sdram_we_n_out         : out   std_logic;
89
    sdram_ras_n_out        : out   std_logic;
90
    sdram_cas_n_out        : out   std_logic;
91
    sdram_dqm_out          : out   std_logic_vector(1 downto 0);
92
    sdram_ba_out           : out   std_logic_vector(1 downto 0);
93
    sdram_address_out      : out   std_logic_vector(11 downto 0)
94
    );
95
 
96
  attribute useioff : boolean;
97
  attribute useioff of data_out : signal is true;
98
  attribute useioff of sdram_data_inout : signal is true;
99
 
100
end;
101
 
102
architecture rtl of sdram_controller is
103
 
104
  -- purpose: counts the needed delays in clock cycles from clock frequency
105
  --          and nanoseconds
106
  function calculate_cycles (clk_freq_mhz : integer;
107
                             time_ns      : integer;
108
                             round        : string)
109
    return integer is
110
    variable result_cycles : integer;
111
  begin  -- calculate_cycles
112
    assert round = "down" or round = "up"
113
      report
114
      "Error in calling function calculate_cycles: unknown rounding parameter!"
115
      severity failure;
116
    result_cycles := (clk_freq_mhz * time_ns);
117
    if result_cycles rem 1000 /= 0 then
118
      if round = "up" then
119
        result_cycles := result_cycles + 1000;
120
      end if;
121
    end if;
122
    return result_cycles/1000;
123
  end calculate_cycles;
124
 
125
  -- purpose: sets correct cas latency according to clock frequency and
126
  --          checks that clock frequency isn't higher than 143MHz
127
  function set_cas_latency (
128
    clk_freq_mhz_g : integer)
129
    return integer is
130
    variable cas_result : integer;
131
  begin  -- set_cas_latency
132
    if clk_freq_mhz_g <= 50 then
133
      cas_result := 2;
134
    elsif clk_freq_mhz_g <= 100 then
135
      cas_result := 2;
136
    elsif clk_freq_mhz_g <= 143 then
137
      cas_result := 3;
138
    else
139
      assert false report "Clock frequency too high (>143MHz) for SDRAM"
140
        severity warning;
141
    end if;
142
    return cas_result;
143
  end set_cas_latency;
144
 
145
  -- ACTIVE to ACTIVE in the same bank
146
  -- tRC = 63ns
147
  constant t_rc_c      : integer := calculate_cycles(clk_freq_mhz_g, 63, "up");
148
  -- ACTIVE to READ/WRITE
149
  -- tRCD = 21ns
150
  constant t_rcd_c     : integer := calculate_cycles(clk_freq_mhz_g, 21, "up");
151
  -- ACTIVE to PRECHARGE
152
  -- tRAS(min) = 42ns
153
  constant t_ras_min_c : integer := calculate_cycles(clk_freq_mhz_g, 42, "up");
154
  -- ACTIVE to PRECHARGE
155
  -- tRAS(max) = 100 000ns
156
  constant t_ras_max_c :
157
    integer := calculate_cycles(clk_freq_mhz_g, 100000, "up") - 2;
158
  -- Auto refresh period
159
  -- tRFC = 70ns = tRC
160
  constant t_rfc_c : integer := calculate_cycles(clk_freq_mhz_g, 70, "up");
161
  -- Precharge period
162
  -- tRP = 21ns
163
  constant t_rp_c :
164
    integer := calculate_cycles(clk_freq_mhz_g, 21, "up");
165
  -- ACTIVE to ACTIVE, different banks
166
  -- tRRD = 14ns
167
  constant t_rrd_c : integer := calculate_cycles(clk_freq_mhz_g, 14, "up");
168
  -- Write recovery time -- Tätä ei jostain syystä löydy datalehdestä, jätin ennalleen.
169
  -- tWR = 14ns wo/autoprecharge = 1clk + 7ns w/autoprecharge
170
  constant t_wr_c  : integer := calculate_cycles(clk_freq_mhz_g, 14, "up");
171
  -- CAS latency +1(registered output causes 1 extra cycle latency)
172
  constant t_cas_c : integer := set_cas_latency(clk_freq_mhz_g) + 1;
173
  -- LOAD MODE REGISTER command period
174
  -- tMRD = 2 cycles
175
  constant t_mrd_c : integer := 2;
176
 
177
  -- Evenly distributed refresh commands
178
  -- 1 autorefresh cycle per 15,625us = 15625ns
179
  -- 1 cycle removed to compensate clock uncertainty
180
 
181
  constant refresh_period_c : integer :=
182
    calculate_cycles(clk_freq_mhz_g, 15625, "down") - 1; --30;
183
 
184
  constant refresh_latency_write_c : integer :=
185
    t_wr_c + t_rp_c + t_rfc_c + 3;
186
--    t_ras_min_c + t_rp_c;
187
  constant refresh_latency_read_c : integer :=
188
    t_cas_c + t_rp_c + t_rfc_c + 2;
189
--    t_cas_c + t_ras_min_c + t_rp_c + 2;
190
  constant refresh_latency_idle_c : integer :=
191
    t_rcd_c + t_rp_c + t_rfc_c + 8;
192
 
193
  -- after reset 200us = 200000ns of NOPs
194
  constant init_wait_cycles_c : integer :=
195
    calculate_cycles(clk_freq_mhz_g, 200000, "up");
196
 
197
  -- commands
198
  constant command_nop_c   : std_logic_vector(1 downto 0) := "00";
199
  constant command_read_c  : std_logic_vector(1 downto 0) := "01";
200
  constant command_write_c : std_logic_vector(1 downto 0) := "10";
201
 
202
  -- SDRAM commands
203
  constant sdram_nop_c          : std_logic_vector(3 downto 0) := "0111";
204
  constant sdram_active_c       : std_logic_vector(3 downto 0) := "0011";
205
  constant sdram_read_c         : std_logic_vector(3 downto 0) := "0101";
206
  constant sdram_write_c        : std_logic_vector(3 downto 0) := "0100";
207
  constant sdram_precharge_c    : std_logic_vector(3 downto 0) := "0010";
208
  constant sdram_auto_refresh_c : std_logic_vector(3 downto 0) := "0001";
209
  constant sdram_load_mode_c    : std_logic_vector(3 downto 0) := "0000";
210
 
211
  -- SDRAM default mode = burst length 1
212
  constant default_mode_c : std_logic_vector(11 downto 0) :=
213
    "00000" & conv_std_logic_vector(t_cas_c - 1, 3) & "0000";
214
  -- Write Burst Lengthiksi vaihdettu "single bit".
215
  -- Vaihdettu takas nollaks (= burst). Se on toi keskimmäinen noista viidestä.
216
 
217
  -- SDRAM command register
218
  signal sdram_command_r : std_logic_vector(3 downto 0);
219
 
220
  -- SDRAM address register
221
  signal sdram_address_r : std_logic_vector(mem_addr_width_g - 1 downto 0);
222
 
223
  -- registers for operations longer than one word
224
  signal data_counter_r : std_logic_vector(data_amount_in'length - 1
225
                                           downto 0);
226
  signal succesful_reads_r : std_logic_vector(data_amount_in'length - 1
227
                                              downto 0);
228
 
229
  signal data_amount_r : std_logic_vector(data_amount_in'length - 1
230
                                          downto 0);
231
 
232
  signal read_on_r   : std_logic;
233
  signal output_we_r : std_logic;
234
 
235
  -- state machine signals
236
  type state_vector is (init_wait,
237
                        init_precharge,
238
                        init_auto_refresh1,
239
                        init_auto_refresh2,
240
                        init_load_mode_register,
241
                        idle,
242
                        idle_auto_refresh,
243
 
244
                        start_read,
245
                        continue_read,
246
                        read_refresh_precharge,
247
                        read_refresh,
248
                        read_refresh_wait,
249
                        read_finished,
250
                        read_finished_precharge,
251
 
252
                        start_write,
253
                        wait_write_active_to_active,
254
                        continue_write,
255
                        write_refresh_precharge,
256
                        write_refresh,
257
                        write_refresh_wait,
258
                        write_change_row_precharge,
259
                        write_finished,
260
                        write_finished_precharge
261
                        );
262
 
263
  signal current_state_r : state_vector;
264
 
265
  -- signals for timing
266
  signal t_cas_r         : integer range 0 to t_cas_c - 1;
267
  signal t_end_cas_r     : integer range 0 to t_cas_c - 1;
268
  signal t_rfc_r         : integer range 0 to t_rfc_c - 1;
269
  signal t_rp_r          : integer range 0 to t_rp_c - 1;
270
  signal t_from_active_r : integer range 0 to t_ras_max_c - 2;
271
 
272
  signal t_wr_r               : integer range 0 to t_wr_c - 1;
273
  signal t_mrd_r              : integer range 0 to t_mrd_c - 1;
274
  signal t_from_refresh_r     : integer range 0 to init_wait_cycles_c - 1;
275
  signal refresh_period_clr_r : std_logic;
276
  signal row_active_r         : std_logic;
277
  signal input_re_out_r       : std_logic;
278
 
279
  signal sdram_data_out_r : std_logic_vector(15 downto 0);
280
  signal input_one_d_in_r   : std_logic;
281
  signal input_empty_in_r   : std_logic;
282
 
283
  signal write_on_r : std_logic;
284
 
285
  signal data_to_sdram2hibi_r : std_logic_vector(15 downto 0);
286
 
287
begin  -- rtl
288
 
289
  write_on_out <= write_on_r;
290
 
291
  data_out <= data_to_sdram2hibi_r;
292
 
293
  output_we_out <= output_we_r and not(output_full_in);
294
 
295
  input_re_out <= input_re_out_r;
296
 
297
  sdram_data_inout <= sdram_data_out_r when write_on_r = '1'
298
                      else (others => 'Z');
299
  -- assign commands to sdram control lines
300
  sdram_cs_n_out  <= sdram_command_r(3);
301
  sdram_ras_n_out <= sdram_command_r(2);
302
  sdram_cas_n_out <= sdram_command_r(1);
303
  sdram_we_n_out  <= sdram_command_r(0);
304
 
305
  -- sdram clock is always enabled
306
  sdram_cke_out <= '1';
307
 
308
  register_inouts : process (clk, rst_n)
309
  begin  -- process register_inouts
310
 
311
    if rst_n = '0' then                 -- asynchronous reset (active low)
312
      sdram_data_out_r   <= (others => '0');
313
      input_empty_in_r     <= '0';
314
      input_one_d_in_r     <= '0';
315
      data_to_sdram2hibi_r <= (others => '0');
316
 
317
    elsif clk'event and clk = '1' then  -- rising clock edge
318
      sdram_data_out_r   <= data_in;
319
      input_empty_in_r     <= input_empty_in;
320
      input_one_d_in_r     <= input_one_d_in;
321
      data_to_sdram2hibi_r <= sdram_data_inout;
322
    end if;
323
  end process register_inouts;
324
 
325
  -- purpose: State machine
326
  state_machine_proc : process (clk, rst_n)
327
  begin  -- process state_machine_proc
328
    if rst_n = '0' then                 -- asynchronous reset (active low)
329
      row_active_r         <= '0';
330
      sdram_dqm_out        <= (others => '0');
331
      t_wr_r               <= 0;
332
      data_counter_r       <= (others => '0');
333
      data_amount_r        <= (others => '0');
334
      sdram_ba_out         <= (others => '0');
335
      sdram_address_out    <= (others => '0');
336
      t_rp_r               <= 0;
337
      t_rfc_r              <= 0;
338
      t_mrd_r              <= 0;
339
      t_end_cas_r          <= 0;
340
      refresh_period_clr_r <= '0';
341
      input_re_out_r       <= '0';
342
      sdram_command_r      <= sdram_nop_c;
343
      sdram_address_r      <= (others => '0');
344
      current_state_r      <= init_wait;
345
      busy_out             <= '1';
346
      read_on_r            <= '0';
347
      write_on_r           <= '0';
348
    elsif clk'event and clk = '1' then  -- rising clock edge
349
 
350
      case current_state_r is
351
 
352
-------------------------------------------------------------------------------
353
-- start initialization sequence
354
-------------------------------------------------------------------------------
355
        -- after reset NOP commands for 100us
356
        when init_wait =>
357
          refresh_period_clr_r <= '0';
358
          if t_from_refresh_r = init_wait_cycles_c - 1
359
            or sim_ena_g = 1 then
360
            t_rp_r                <= 0;
361
            sdram_address_out(10) <= '1';
362
            sdram_command_r       <= sdram_precharge_c;
363
            current_state_r       <= init_precharge;
364
          else
365
            sdram_command_r <= sdram_nop_c;
366
            current_state_r <= init_wait;
367
          end if;
368
 
369
          -- after 100us of NOPs precharge all banks
370
        when init_precharge =>
371
          if t_rp_r = t_rp_c - 1 or t_rp_c <= 1 then
372
            sdram_command_r <= sdram_auto_refresh_c;
373
            current_state_r <= init_auto_refresh1;
374
          else
375
            t_rp_r          <= t_rp_r + 1;
376
            sdram_command_r <= sdram_nop_c;
377
            current_state_r <= init_precharge;
378
          end if;
379
 
380
          -- after precharge two auto refreshes
381
        when init_auto_refresh1 =>
382
          if t_rfc_r = t_rfc_c - 1 or t_rfc_c <= 1 then
383
            refresh_period_clr_r <= '1';
384
            t_rfc_r              <= 0;
385
            sdram_command_r      <= sdram_auto_refresh_c;
386
            current_state_r      <= init_auto_refresh2;
387
          else
388
            refresh_period_clr_r <= '0';
389
            t_rfc_r              <= t_rfc_r + 1;
390
            sdram_command_r      <= sdram_nop_c;
391
            current_state_r      <= init_auto_refresh1;
392
          end if;
393
 
394
        when init_auto_refresh2 =>
395
          refresh_period_clr_r                <= '0';
396
          if t_rfc_r = t_rfc_c - 1 or t_rfc_c <= 1 then
397
            t_rfc_r           <= 0;
398
            sdram_address_out <= default_mode_c;
399
            sdram_command_r   <= sdram_load_mode_c;
400
            current_state_r   <= init_load_mode_register;
401
          else
402
            t_rfc_r         <= t_rfc_r + 1;
403
            sdram_command_r <= sdram_nop_c;
404
            current_state_r <= init_auto_refresh2;
405
          end if;
406
 
407
          -- load default mode
408
        when init_load_mode_register =>
409
          sdram_command_r                     <= sdram_nop_c;
410
          if t_mrd_r = t_mrd_c - 1 or t_mrd_c <= 1 then
411
            t_mrd_r         <= 0;
412
            busy_out        <= '0';
413
            current_state_r <= idle;
414
          else
415
            t_mrd_r         <= t_mrd_r + 1;
416
            current_state_r <= init_load_mode_register;
417
          end if;
418
-------------------------------------------------------------------------------
419
-- end initialization and start normal operation
420
-------------------------------------------------------------------------------
421
 
422
        when idle =>
423
 
424
          data_counter_r <= (others => '0');
425
          -- precharge is always done before returning to idle state
426
          -- so we don't have to worry about t_ras_min_c or t_rp_c
427
          -- (2*t_ras_min),t_rc_c and t_rp_c subracted from refresh_period to prevent
428
          -- situations where refresh is done right next to active command.
429
          -- (which is waste of time)
430
          -- This way when we start executing reads or writes we can do
431
          -- at least one operation before refreshing.
432
          if t_from_refresh_r
433
            >= refresh_period_c - refresh_latency_idle_c then
434
--             >= refresh_period_c - t_ras_min_c - t_rp_c - 20  -- - 2
435
--            - (2 * t_ras_min_c) - t_rc_c - t_rp_c - 1 then
436
            sdram_command_r      <= sdram_auto_refresh_c;
437
            refresh_period_clr_r <= '1';
438
            current_state_r      <= idle_auto_refresh;
439
            busy_out             <= '0';
440
          else
441
 
442
            -- If there is a valid command in the command_in port
443
            -- we start to process it immediately and tell it to
444
            -- others by setting busy_out to '1'
445
            case command_in is
446
 
447
              -- if time from active to active is met, activate
448
              -- row and proceed to reading. Otherwise go to
449
              -- wait_read_active_to_active state. And wait
450
              -- for t_rc_c or t_rrd
451
              when command_read_c =>
452
 
453
                sdram_dqm_out <= (others => '0');
454
                if data_amount_in >
455
                  conv_std_logic_vector(block_read_length_g,
456
                                        data_amount_r'length) then
457
                  data_amount_r <=
458
                    conv_std_logic_vector(block_read_length_g,
459
                                          data_amount_r'length);
460
                else
461
                  data_amount_r <= data_amount_in;
462
                end if;
463
                sdram_address_r   <= address_in;
464
                sdram_ba_out      <= address_in(21 downto 20);
465
                sdram_address_out <= address_in(19 downto 8);
466
 
467
                -- read operation to bank that was activated in previous operation
468
                if address_in(21 downto 20)
469
                   = sdram_address_r(21 downto 20) then
470
 
471
                  if (t_from_active_r >= t_rc_c - 1 or t_rc_c <= 1)
472
                    and sdram_command_r /= sdram_active_c
473
                    and output_full_in = '0' then
474
 
475
                    busy_out        <= '1';
476
                    read_on_r <= '1';
477
                    sdram_command_r <= sdram_active_c;
478
                    current_state_r <= start_read;
479
                  else
480
                    busy_out        <= '0';
481
                    sdram_command_r <= sdram_nop_c;
482
                    current_state_r <= idle;
483
                  end if;
484
 
485
                  -- read operation to different bank than previously
486
                else
487
 
488
                  if (t_from_active_r >= t_rrd_c - 1 or t_rrd_c <= 1)
489
                    and sdram_command_r /= sdram_active_c
490
                    and output_full_in = '0' then
491
                    busy_out        <= '1';
492
                    read_on_r <= '1';
493
                    sdram_command_r <= sdram_active_c;
494
                    current_state_r <= start_read;
495
                  else
496
                    busy_out        <= '0';
497
                    sdram_command_r <= sdram_nop_c;
498
                    current_state_r <= idle;
499
                  end if;
500
 
501
                end if;
502
 
503
              when command_write_c =>
504
 
505
                sdram_dqm_out     <= byte_select_in;
506
                data_amount_r     <= data_amount_in;
507
                sdram_address_r   <= address_in;
508
                sdram_ba_out      <= address_in(21 downto 20);
509
                sdram_address_out <= address_in(19 downto 8);
510
 
511
                -- write operation to bank that was activated in
512
                -- the previous operation
513
                if address_in(21 downto 20)
514
                   = sdram_address_r(21 downto 20) then
515
 
516
                  if (t_from_active_r >= t_rc_c - 1 or t_rc_c <= 1)
517
                    and sdram_command_r /= sdram_active_c
518
                    and input_empty_in = '0' then
519
 
520
                    busy_out        <= '1';
521
                    sdram_command_r <= sdram_active_c;
522
                    current_state_r <= start_write;
523
                  else
524
                    busy_out        <= '0';
525
                    sdram_command_r <= sdram_nop_c;
526
                    current_state_r <= idle;
527
                  end if;
528
 
529
                  -- write operation to different bank than previously
530
                else
531
 
532
                  if (t_from_active_r >= t_rrd_c - 1 or t_rrd_c <= 1)
533
                    and sdram_command_r /= sdram_active_c
534
                    and input_empty_in = '0' then
535
                    busy_out        <= '1';
536
                    sdram_command_r <= sdram_active_c;
537
                    current_state_r <= start_write;
538
                  else
539
                    busy_out        <= '0';
540
                    sdram_command_r <= sdram_nop_c;
541
                    current_state_r <= idle;
542
                  end if;
543
 
544
                end if;
545
 
546
                -- NOP or unknown command, don't do anything
547
              when others =>
548
                busy_out        <= '0';
549
                sdram_command_r <= sdram_nop_c;
550
                current_state_r <= idle;
551
            end case;
552
          end if;
553
 
554
 
555
        -- wait until time minimum time from active to active is met
556
        -- and precharge command period is met
557
        -- go to start write
558
        when wait_write_active_to_active =>
559
          sdram_ba_out      <= sdram_address_r(21 downto 20);
560
          sdram_address_out <= sdram_address_r(19 downto 8);
561
 
562
          if t_rp_r >= t_rp_c - 1 or t_rp_c <= 1 then
563
            t_rp_r <= t_rp_r;
564
          else
565
            t_rp_r <= t_rp_r + 1;
566
          end if;
567
 
568
          -- operation to bank that was activated in previous operation
569
          if address_in(21 downto 20)
570
             = sdram_address_r(21 downto 20) then
571
 
572
            if (t_from_active_r >= t_rc_c - 2 or t_rc_c <= 2)
573
              and sdram_command_r /= sdram_active_c
574
              and t_rp_r >= t_rp_c - 1 then
575
 
576
              sdram_command_r <= sdram_active_c;
577
              current_state_r <= start_write;
578
            else
579
              sdram_command_r <= sdram_nop_c;
580
              current_state_r <= wait_write_active_to_active;
581
            end if;
582
 
583
            -- operation to different bank than previously
584
          else
585
 
586
            if (t_from_active_r >= t_rrd_c - 2 or t_rrd_c <= 2)
587
              and sdram_command_r /= sdram_active_c
588
              and t_rp_r >= t_rp_c - 1 then
589
 
590
              sdram_command_r <= sdram_active_c;
591
              current_state_r <= start_write;
592
            else
593
              sdram_command_r <= sdram_nop_c;
594
              current_state_r <= wait_write_active_to_active;
595
            end if;
596
 
597
          end if;
598
 
599
          -- Wait for data to be written.
600
          -- Since we don't know when input data is available
601
          -- we must check refreshing and t_ras_max(maximum
602
          -- time that row can be open).
603
          -- When input data arrives, read data(input_re_out = '1')
604
          -- and go to continue write state.
605
        when start_write =>
606
 
607
          sdram_command_r <= sdram_nop_c;
608
 
609
          -- Worst case in refreshing is that we go to
610
          -- write_change_row_precharge state then
611
          -- the next possibility to make refresh is after:
612
          --   t_ras_min_c in write_change_row_precharge +
613
          --   t_rc_c in wait_write_active_to_active +
614
          --   t_ras_min_c in write_refresh_precharge +
615
          --   t_rp_c in write_refresh
616
          --     = 2*t_ras_min_c + t_rc_c + t_rp
617
          if t_from_refresh_r
618
             >= refresh_period_c - refresh_latency_write_c - 1
619
            or (t_from_active_r >= t_ras_max_c - t_wr_c - 3
620
                and sdram_command_r /= sdram_active_c) then
621
 
622
            input_re_out_r  <= '0';
623
            current_state_r <= write_refresh_precharge;
624
 
625
          else
626
            -- is t_rcd_c (minimum time from active to read/write) met?
627
            if t_rcd_c <= 2
628
                          or (t_from_active_r >= t_rcd_c - 3
629
                              and sdram_command_r /= sdram_active_c) then
630
 
631
              sdram_ba_out      <= sdram_address_r(21 downto 20);
632
              sdram_address_out <= "0000" & sdram_address_r(7 downto 0);
633
 
634
              -- We must change row if address is first column in row and
635
              -- this is not the first write of this operation.
636
              if input_empty_in = '0' and not(input_one_d_in = '1' and
637
                                              input_re_out_r = '1') then
638
 
639
                if sdram_address_r(7 downto 0) = 0 and data_counter_r /= 0
640
                  and row_active_r = '0' then
641
                  input_re_out_r  <= '0';
642
                  row_active_r    <= '1';
643
                  current_state_r <= write_change_row_precharge;
644
                else
645
                  input_re_out_r  <= '1';
646
                  current_state_r <= continue_write;
647
                end if;
648
              else
649
                input_re_out_r  <= '0';
650
                current_state_r <= write_finished;
651
              end if;
652
            else
653
              input_re_out_r  <= '0';
654
              current_state_r <= start_write;
655
            end if;
656
          end if;
657
 
658
          -- Write until operation is completed. Change row,
659
          -- precharge and refresh if necessary
660
        when continue_write =>
661
 
662
          sdram_ba_out      <= sdram_address_r(21 downto 20);
663
          sdram_address_out <= "0000" & sdram_address_r(7 downto 0);
664
 
665
          -- write finished or terminated
666
          if data_counter_r = data_amount_r
667
            or (sdram_address_r
668
                 = conv_std_logic_vector(0, sdram_address_r'length)
669
                and data_counter_r /= 0) then
670
            row_active_r <= '0';
671
 
672
            input_re_out_r  <= '0';
673
            data_counter_r  <= (others => '0');
674
            sdram_command_r <= sdram_nop_c;
675
            current_state_r <= write_finished;
676
            write_on_r      <= '0';
677
 
678
            -- refresh. refresh_latency_write takes care of possible
679
            -- delays before refresh can be done (precharge command period
680
            -- and changing row.
681
          elsif t_from_refresh_r >= refresh_period_c - refresh_latency_write_c
682
            or (t_from_active_r >= t_ras_max_c - t_wr_c - 2
683
                and sdram_command_r /= sdram_active_c) then
684
            input_re_out_r  <= '0';
685
            sdram_command_r <= sdram_nop_c;
686
            current_state_r <= write_refresh_precharge;
687
            write_on_r      <= '0';
688
 
689
 
690
            -- change row
691
          elsif sdram_address_r(7 downto 0) = 0 and data_counter_r /= 0
692
            and row_active_r = '0' then
693
            input_re_out_r  <= '0';
694
            row_active_r    <= '1';
695
            sdram_command_r <= sdram_nop_c;
696
            current_state_r <= write_change_row_precharge;
697
            write_on_r      <= '0';
698
 
699
            -- normal write
700
          else
701
            row_active_r <= '0';
702
 
703
            if (input_empty_in_r = '0' and not(input_one_d_in_r = '1'
704
                                               and input_re_out_r = '1'))
705
              or data_counter_r = 0 then
706
 
707
              data_counter_r  <= data_counter_r + 1;
708
              sdram_address_r <= sdram_address_r + 1;
709
 
710
              -- don't load new data if write finishes or row changes
711
              -- or refresh or t_ras_max_c is met.
712
              -- In t_from_refresh_r >= refresh_period - x the x
713
              -- must be one larger than in the previous if(refresh)
714
              -- otherwise the data_counter_r goes wrong
715
 
716
              if sdram_address_r(7 downto 0) = "11111111"
717
                or t_from_refresh_r
718
                 >= refresh_period_c - refresh_latency_write_c - 1
719
                or (t_from_active_r >= t_ras_max_c - t_wr_c - 2 - 1
720
                    and sdram_command_r /= sdram_active_c)
721
                or data_counter_r = data_amount_r - 1
722
                or (input_empty_in = '1' or (input_one_d_in = '1'
723
                                             and input_re_out_r = '1')) then
724
                input_re_out_r  <= '0';
725
                current_state_r <= write_finished;
726
 
727
              else
728
                input_re_out_r  <= '1';
729
                current_state_r <= continue_write;
730
              end if;
731
              write_on_r      <= '1';
732
              sdram_command_r <= sdram_write_c;
733
              t_wr_r          <= 0;
734
 
735
              -- no input data available, terminate write
736
            else
737
              write_on_r      <= '0';
738
              data_counter_r  <= data_counter_r;
739
              sdram_address_r <= sdram_address_r;
740
              input_re_out_r  <= '0';
741
              sdram_command_r <= sdram_nop_c;
742
              current_state_r <= write_finished;
743
            end if;
744
          end if;
745
 
746
          -- Refresh during write operation.
747
          -- First we must wait for t_wr(write recovery time) and
748
          -- t_ras_min(minimum time from active to precharge)
749
          -- Then we must precharge all banks before refresh.
750
        when write_refresh_precharge =>
751
          if t_wr_c <= 2 or (t_wr_r >= t_wr_c - 2) then
752
            if (t_from_active_r >= t_ras_min_c - 2
753
                and sdram_command_r /= sdram_active_c) then
754
              t_rp_r                <= 0;
755
              sdram_address_out(10) <= '1';
756
              sdram_command_r       <= sdram_precharge_c;
757
              current_state_r       <= write_refresh;
758
            else
759
              t_wr_r          <= t_wr_r;
760
              sdram_command_r <= sdram_nop_c;
761
              current_state_r <= write_refresh_precharge;
762
            end if;
763
 
764
          else
765
            t_wr_r          <= t_wr_r + 1;
766
            sdram_command_r <= sdram_nop_c;
767
            current_state_r <= write_refresh_precharge;
768
          end if;
769
 
770
          -- Wait for t_rp(precharge command period)
771
          -- after that refresh
772
        when write_refresh =>
773
          if t_rp_r = t_rp_c - 1 or t_rp_c <= 1 then
774
            refresh_period_clr_r <= '1';
775
            t_rp_r               <= 0;
776
            sdram_command_r      <= sdram_auto_refresh_c;
777
            current_state_r      <= write_refresh_wait;
778
          else
779
            sdram_command_r <= sdram_nop_c;
780
            t_rp_r          <= t_rp_r + 1;
781
            current_state_r <= write_refresh;
782
          end if;
783
 
784
          -- wait for refresh command period and
785
          -- proceed write operation
786
        when write_refresh_wait =>
787
          refresh_period_clr_r                <= '0';
788
          if t_rfc_r = t_rfc_c - 1 or t_rfc_c <= 1 then
789
            t_rfc_r         <= 0;
790
            sdram_command_r <= sdram_nop_c;
791
            if data_counter_r = data_amount_r then
792
              row_active_r    <= '0';
793
              busy_out        <= '0';
794
              current_state_r <= idle;
795
            else
796
              busy_out        <= '1';
797
              current_state_r <= wait_write_active_to_active;
798
            end if;
799
          else
800
            t_rfc_r         <= t_rfc_r + 1;
801
            sdram_command_r <= sdram_nop_c;
802
            current_state_r <= write_refresh_wait;
803
          end if;
804
 
805
          -- Change row in write operation.
806
          -- Wait for write recovery time and precharge
807
          -- all banks. Then go to wait_write_active_to_active
808
          -- state that handles activating the new row/bank
809
          -- and proceeds writing.
810
        when write_change_row_precharge =>
811
          if t_wr_c <= 2 or (t_wr_r = t_wr_c - 2) then
812
            if (t_from_active_r >= t_ras_min_c - 2 or t_ras_min_c <= 2)
813
              and sdram_command_r /= sdram_active_c then
814
              t_rp_r                <= 0;
815
              sdram_address_out(10) <= '1';
816
              sdram_command_r       <= sdram_precharge_c;
817
 
818
              if data_counter_r = data_amount_r then
819
                busy_out        <= '1';
820
                row_active_r    <= '0';
821
                current_state_r <= write_finished_precharge;
822
              else
823
                current_state_r <= wait_write_active_to_active;
824
              end if;
825
            else
826
              t_wr_r          <= t_wr_r;
827
              sdram_command_r <= sdram_nop_c;
828
              current_state_r <= write_change_row_precharge;
829
            end if;
830
          else
831
            t_wr_r          <= t_wr_r + 1;
832
            sdram_command_r <= sdram_nop_c;
833
            current_state_r <= write_change_row_precharge;
834
          end if;
835
 
836
          -- write finished, so wait for wait_recovery time
837
          -- and minimum time from active to precharge and
838
          -- precharge all banks
839
        when write_finished =>
840
          write_on_r   <= '0';
841
          row_active_r <= '0';
842
 
843
          if write_on_r = '0' then
844
 
845
            if (t_wr_c <= 2 or (t_wr_r >= t_wr_c - 2)) then
846
              if (t_from_active_r >= t_ras_min_c - 2 or t_ras_min_c <= 2)
847
                and sdram_command_r /= sdram_active_c then
848
                sdram_address_out(10) <= '1';
849
                t_rp_r                <= 0;
850
                busy_out              <= '1';
851
                sdram_command_r       <= sdram_precharge_c;
852
                current_state_r       <= write_finished_precharge;
853
              else
854
                t_wr_r          <= t_wr_r;
855
                sdram_command_r <= sdram_nop_c;
856
                current_state_r <= write_finished;
857
              end if;
858
            else
859
              t_wr_r          <= t_wr_r + 1;
860
              sdram_command_r <= sdram_nop_c;
861
              current_state_r <= write_finished;
862
            end if;
863
          else
864
            sdram_command_r <= sdram_nop_c;
865
            current_state_r <= write_finished;
866
          end if;
867
 
868
          -- wait for precharge command period and
869
          -- go to idle state.
870
        when write_finished_precharge =>
871
          sdram_command_r <= sdram_nop_c;
872
          if t_rp_c       <= 2 or (t_rp_r = t_rp_c - 1 - 1) then
873
            t_rp_r          <= t_rp_c - 1;
874
            busy_out        <= '0';
875
            current_state_r <= idle;
876
          else
877
            t_rp_r          <= t_rp_r + 1;
878
            current_state_r <= write_finished_precharge;
879
          end if;
880
 
881
          -- refresh during idle state
882
        when idle_auto_refresh =>
883
          refresh_period_clr_r                <= '0';
884
          sdram_command_r                     <= sdram_nop_c;
885
          if t_rfc_r = t_rfc_c - 1 or t_rfc_c <= 1 then
886
            t_rfc_r         <= 0;
887
            busy_out        <= '0';
888
            current_state_r <= idle;
889
          else
890
            t_rfc_r         <= t_rfc_r + 1;
891
            current_state_r <= idle_auto_refresh;
892
          end if;
893
 
894
          -- Start read state
895
          -- Check t_rcd(minimum time between active and read/write command).
896
          -- If timings are met the go to continue read state where
897
          -- the actual read happens.
898
        when start_read =>
899
          sdram_command_r <= sdram_nop_c;
900
 
901
          if t_rcd_c <= 2
902
                        or (t_from_active_r >= t_rcd_c - 3
903
                            and sdram_command_r /= sdram_active_c) then
904
            current_state_r <= continue_read;
905
          else
906
            current_state_r <= start_read;
907
          end if;
908
 
909
          -- continue read state:
910
          -- Check refreshing and t_ras_max.
911
          -- If output fifo is full or
912
          -- row changes, terminate read
913
        when continue_read =>
914
 
915
          -- refresh
916
          if t_from_refresh_r >= refresh_period_c - refresh_latency_read_c
917
            or (t_from_active_r >= t_ras_max_c - 2
918
                and sdram_command_r /= sdram_active_c) then
919
 
920
            if output_full_in = '1' then
921
              data_counter_r <= succesful_reads_r;
922
            else
923
              data_counter_r  <= data_counter_r;
924
              sdram_address_r <= sdram_address_r;
925
            end if;
926
 
927
            sdram_command_r <= sdram_nop_c;
928
            current_state_r <= read_refresh_precharge;
929
 
930
          else
931
 
932
            if output_full_in = '0' then
933
 
934
              -- read finished
935
              if data_counter_r = data_amount_r then
936
                sdram_address_r <= sdram_address_r;
937
                data_counter_r  <= data_counter_r;
938
                sdram_command_r <= sdram_nop_c;
939
                current_state_r <= read_finished;
940
 
941
                -- address overflow, read the last address until operation
942
                -- is finished
943
              elsif sdram_address_r
944
                 = conv_std_logic_vector(0, sdram_address_r'length)
945
                and data_counter_r /= 0 then
946
 
947
                sdram_address_r   <= (others => '1');
948
                sdram_ba_out      <= sdram_address_r(21 downto 20);
949
                sdram_address_out <= "0000" & sdram_address_r(7 downto 0);
950
 
951
                data_counter_r    <= data_counter_r + 1;
952
                sdram_command_r   <= sdram_read_c;
953
                current_state_r   <= continue_read;
954
 
955
                -- row changes so terminate read
956
              elsif sdram_address_r(7 downto 0) = "00000000"
957
                and data_counter_r /= 0 then
958
 
959
                sdram_command_r <= sdram_nop_c;
960
                current_state_r <= read_finished;
961
 
962
                -- normal read
963
              else
964
                data_counter_r    <= data_counter_r + 1;
965
                sdram_address_r   <= sdram_address_r + 1;
966
                sdram_ba_out      <= sdram_address_r(21 downto 20);
967
                sdram_address_out <= "0000" & sdram_address_r(7 downto 0);
968
                sdram_command_r   <= sdram_read_c;
969
                current_state_r   <= continue_read;
970
              end if;
971
 
972
              -- output full, terminate read
973
            else
974
              sdram_command_r <= sdram_nop_c;
975
              data_counter_r  <= succesful_reads_r;
976
 
977
              current_state_r <= read_finished;
978
 
979
            end if;
980
          end if;
981
 
982
          -- wait for timings to be met and precharge
983
        when read_refresh_precharge =>
984
 
985
          if t_end_cas_r = t_cas_c - 1 or output_full_in = '1' then
986
 
987
            data_counter_r <= succesful_reads_r;
988
 
989
            if (t_from_active_r >= t_ras_min_c - 2 or t_ras_min_c <= 2)
990
              and sdram_command_r /= sdram_active_c then
991
              t_end_cas_r           <= 0;
992
              t_rp_r                <= 0;
993
              data_counter_r        <= (others => '0');
994
              read_on_r             <= '0';
995
              sdram_address_out(10) <= '1';
996
              sdram_command_r       <= sdram_precharge_c;
997
              current_state_r       <= read_refresh;
998
 
999
            else
1000
              sdram_command_r <= sdram_nop_c;
1001
              t_end_cas_r     <= t_end_cas_r;
1002
              current_state_r <= read_refresh_precharge;
1003
            end if;
1004
 
1005
          else
1006
            t_end_cas_r     <= t_end_cas_r + 1;
1007
            sdram_command_r <= sdram_nop_c;
1008
            current_state_r <= read_refresh_precharge;
1009
          end if;
1010
 
1011
          -- wait for precharge command period and refresh
1012
        when read_refresh =>
1013
          if t_rp_r = t_rp_c - 1 or t_rp_c <= 1 then
1014
            refresh_period_clr_r <= '1';
1015
            sdram_command_r      <= sdram_auto_refresh_c;
1016
            current_state_r      <= read_refresh_wait;
1017
          else
1018
            sdram_command_r <= sdram_nop_c;
1019
            t_rp_r          <= t_rp_r + 1;
1020
            current_state_r <= read_refresh;
1021
          end if;
1022
 
1023
          -- wait for refresh command period and proceed reading.
1024
        when read_refresh_wait =>
1025
          refresh_period_clr_r                <= '0';
1026
          if t_rfc_r = t_rfc_c - 1 or t_rfc_c <= 1 then
1027
            t_rfc_r         <= 0;
1028
            sdram_command_r <= sdram_nop_c;
1029
            busy_out        <= '0';
1030
            read_on_r       <= '0';
1031
            current_state_r <= idle;
1032
          else
1033
            t_rfc_r         <= t_rfc_r + 1;
1034
            sdram_command_r <= sdram_nop_c;
1035
            current_state_r <= read_refresh_wait;
1036
          end if;
1037
 
1038
          -- All read commands are send to sdram.
1039
          -- Wait for cas latency and check that all read data fits
1040
          -- to output fifo. If fifo gets full then terminate read.
1041
          -- Precharge all banks.
1042
        when read_finished =>
1043
 
1044
          if t_end_cas_r = t_cas_c - 1 or output_full_in = '1' then
1045
 
1046
            data_counter_r <= succesful_reads_r;
1047
 
1048
            if (t_from_active_r >= t_ras_min_c - 2 or t_ras_min_c <= 2)
1049
              and sdram_command_r /= sdram_active_c then
1050
              data_counter_r        <= (others => '0');
1051
              t_end_cas_r           <= 0;
1052
              t_rp_r                <= 0;
1053
              sdram_address_out(10) <= '1';
1054
              busy_out              <= '1';
1055
              read_on_r             <= '0';
1056
              sdram_command_r       <= sdram_precharge_c;
1057
              current_state_r       <= read_finished_precharge;
1058
            else
1059
              sdram_command_r <= sdram_nop_c;
1060
              t_end_cas_r     <= t_end_cas_r;
1061
              current_state_r <= read_finished;
1062
            end if;
1063
          else
1064
            sdram_command_r <= sdram_nop_c;
1065
            t_end_cas_r     <= t_end_cas_r + 1;
1066
            current_state_r <= read_finished;
1067
          end if;
1068
 
1069
          -- Read operation is finished, all read data is
1070
          -- put to output fifo and precharge is done.
1071
          -- Now wait for precharge command period and
1072
          -- go to idle state.
1073
        when read_finished_precharge =>
1074
          sdram_command_r <= sdram_nop_c;
1075
          if t_rp_c       <= 2 or (t_rp_r = t_rp_c - 1 - 1) then
1076
            t_rp_r          <= t_rp_c - 1;
1077
            busy_out        <= '0';
1078
            read_on_r       <= '0';
1079
            current_state_r <= idle;
1080
          else
1081
            t_rp_r          <= t_rp_r + 1;
1082
            current_state_r <= read_finished_precharge;
1083
          end if;
1084
 
1085
        when others =>
1086
          sdram_command_r <= sdram_nop_c;
1087
          current_state_r <= idle;
1088
      end case;
1089
    end if;
1090
 
1091
  end process state_machine_proc;
1092
 
1093
  -- This process writes read data from sdram data bus to
1094
  -- output fifo.
1095
  write_read_data_to_output : process (clk, rst_n)
1096
 
1097
  begin  -- process write_read_data_to_output
1098
    if rst_n = '0' then                 -- asynchronous reset (active low)
1099
      t_cas_r           <= 0;
1100
      succesful_reads_r <= (others => '0');
1101
      output_we_r       <= '0';
1102
 
1103
    elsif clk'event and clk = '1' then  -- rising clock edge
1104
 
1105
      -- first check that current operation is read
1106
      if read_on_r = '1' then
1107
 
1108
        -- if output fifo gets full. Clear cas latency counter
1109
        -- and don't write read data to output
1110
        if output_full_in = '1' then
1111
 
1112
          t_cas_r <= 0;
1113
          output_we_r <= '0';
1114
 
1115
        else
1116
 
1117
          -- if read succeeds(output is not full) then proceed
1118
          -- writing data to output buffer until the operation
1119
          -- is complete
1120
          if data_counter_r > succesful_reads_r then
1121
 
1122
            -- if cas latency is met(data from sdram is on the data bus),
1123
            -- then write data to output fifo and update succesful read
1124
            -- count and succesful read and store their previous values.
1125
            -- address.
1126
            if t_cas_r = t_cas_c - 1 then
1127
              t_cas_r           <= t_cas_r;
1128
              succesful_reads_r <= succesful_reads_r + 1;
1129
              output_we_r       <= '1';
1130
 
1131
              -- wait for data from sdram(cas latency)
1132
            else
1133
              t_cas_r           <= t_cas_r + 1;
1134
              succesful_reads_r <= succesful_reads_r;
1135
              output_we_r       <= '0';
1136
            end if;
1137
 
1138
            -- read is finished, clear cas and don't write to output fifo
1139
          else
1140
            t_cas_r     <= 0;
1141
            output_we_r <= '0';
1142
          end if;
1143
        end if;
1144
 
1145
        -- if current operation is not read then reset this process
1146
      else
1147
        t_cas_r           <= 0;
1148
        succesful_reads_r <= (others => '0');
1149
        output_we_r       <= '0';
1150
      end if;
1151
    end if;
1152
 
1153
  end process write_read_data_to_output;
1154
 
1155
  -- purpose: keeps count of time from active command
1156
  --          handles t_rc, t_rcd, t_rrd, t_ras_min, t_ras_max
1157
  t_from_active_counter : process (clk, rst_n)
1158
 
1159
  begin  -- process t_from_active_counter
1160
 
1161
    if rst_n = '0' then                 -- asynchronous reset (active low)
1162
      t_from_active_r <= 0;
1163
    elsif clk'event and clk = '1' then  -- rising clock edge
1164
 
1165
      if sdram_command_r = sdram_active_c then
1166
        t_from_active_r <= 0;
1167
      else
1168
        if t_from_active_r = t_ras_max_c - 2 then
1169
          t_from_active_r <= t_from_active_r;
1170
        else
1171
          t_from_active_r <= t_from_active_r + 1;
1172
        end if;
1173
      end if;
1174
 
1175
    end if;
1176
 
1177
  end process t_from_active_counter;
1178
 
1179
  -- purpose: keeps count of refresh periods
1180
  refresh_period_counter : process (clk, rst_n)
1181
 
1182
  begin  -- process refresh_period_counter
1183
 
1184
    if rst_n = '0' then                 -- asynchronous reset (active low)
1185
      t_from_refresh_r <= 0;
1186
 
1187
    elsif clk'event and clk = '1' then  -- rising clock edge
1188
 
1189
      if refresh_period_clr_r = '1' then
1190
        t_from_refresh_r <= 0;
1191
      else
1192
 
1193
        if t_from_refresh_r = init_wait_cycles_c - 1 then
1194
          t_from_refresh_r <= t_from_refresh_r;
1195
        else
1196
          t_from_refresh_r <= t_from_refresh_r + 1;
1197
        end if;
1198
      end if;
1199
 
1200
    end if;
1201
 
1202
  end process refresh_period_counter;
1203
 
1204
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.