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_stratix.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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