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

Subversion Repositories sdram_controller

[/] [sdram_controller/] [trunk/] [sdram.vhd] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 lynn0p
----------------------------------------------------------------------------------
2
-- Company: OPL Aerospatiale AG
3
-- Engineer: Owen Lynn <lynn0p@hotmail.com>
4
-- 
5
-- Create Date:    14:25:41 08/20/2009 
6
-- Design Name:    DDR SDRAM Controller
7
-- Module Name:    sdram_controller - impl 
8
-- Project Name: 
9
-- Target Devices: Spartan3e Starter Board
10
-- Tool versions:  ISE 11.2
11 7 lynn0p
-- Description: This is the main controller module. This is where the signals 
12
--  to/from the DDR SDRAM chip happen.
13 2 lynn0p
--  
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created
18
-- Additional Comments: 
19
--  Copyright (c) 2009 Owen Lynn <lynn0p@hotmail.com>
20
--  Released under the GNU Lesser General Public License, Version 3
21
--
22
----------------------------------------------------------------------------------
23
library IEEE;
24
use IEEE.STD_LOGIC_1164.ALL;
25
use IEEE.STD_LOGIC_ARITH.ALL;
26
use IEEE.STD_LOGIC_UNSIGNED.ALL;
27
 
28
---- Uncomment the following library declaration if instantiating
29
---- any Xilinx primitives in this code.
30 7 lynn0p
--library UNISIM;
31
--use UNISIM.VComponents.all;
32 2 lynn0p
 
33 7 lynn0p
-- This is not meant to be a high performance controller. No fancy command
34
--  scheduling, does the bare minimum to work without screwing up timing.
35
-- Do NOT put this controller in something mission critical! This is the creation
36
--  of a guy in his bedroom, learning digital circuits.
37
-- Intended to be used exclusively with the Spartan3e Starter Board and targets
38
--  the mt46v32m16 chip. Dunno if it will work anywhere else.
39
-- Uses the ODDR2 and DCM Xilinx primitives, for other FPGAs, you'll need to
40
--  patch in equivalents. See sdram_support for the details.
41
-- I'd strongly recommend running it through a post-PAR simulation if you're
42
--  porting to any other FPGA, as the timings will probably change on you.
43
-- Consumes two DCMs, runs off of the main 50mhz board clock. Could possibly
44
--  consume one DCM if you want to feed it the 100mhz clock directly.
45
-- Has an 8bit wide datapath, moderate changes could support 16bits, 32 bits
46
--  you'll have to work some. You want more than that, you'll be doing brain
47
--  surgery on the FSMs - good luck.
48 2 lynn0p
 
49 7 lynn0p
-- This design has been tested with the testbench only. There may be glitches
50
--  hidden in here somewhere still. Consider this to be an alpha release.
51 2 lynn0p
-- Did I mention that you shouldn't put this in anything mission critical? 
52
 
53 7 lynn0p
-- Be careful with the synthesizer settings too. Do not let the FSM extractor
54
--  choose something other than one-hot. Be careful with equivalent register
55
--  removal. I've rolled all synthesizer settings back to default and things
56
--  seem to be OK, but pay attention to the synthesizer reports!
57 2 lynn0p
 
58
-- TODO: implement reset signal
59
entity sdram_controller is
60
        port(      -- user facing signals 
61 8 lynn0p
                 clk100mhz : in  std_logic;
62
                 en : in  std_logic;
63
                     reset : in  std_logic;
64
                        op : in  std_logic_vector(1 downto 0);        -- 00/11: NOP, 01: READ, 10: write
65
                      addr : in  std_logic_vector(25 downto 0);       -- address to read/write 
66
                    op_ack : out std_logic;                           -- op, addr and data_i should be captured when this goes high
67
                    busy_n : out std_logic;                           -- busy when LOW, ops will be ignored until busy goes high again
68
                    data_o : out std_logic_vector(7 downto 0);        -- data from read shows up here
69
                    data_i : in  std_logic_vector(7 downto 0);        -- data to write needs to be here
70 2 lynn0p
 
71
                -- SDRAM facing signals 
72
                          dram_clkp : out   std_logic;                         -- 0 deg phase 100mhz clock going out to SDRAM chip
73
                          dram_clkn : out   std_logic;                         -- 180 deg phase version of dram_clkp
74
                dram_clke : out   std_logic;                         -- clock enable, owned by the init module
75
                            dram_cs : out   std_logic;                         -- tied low upon powerup
76
                 dram_cmd : out   std_logic_vector(2 downto 0);      -- this is the command vector <we_n,cas_n,ras_n>
77
           dram_bank : out   std_logic_vector(1 downto 0);      -- bank address
78
                          dram_addr : out   std_logic_vector(12 downto 0);     -- row/col/mode register
79
                            dram_dm : out   std_logic_vector(1 downto 0);      -- masks used for writing
80
                           dram_dqs : inout std_logic_vector(1 downto 0);      -- strobes used for writing
81
                            dram_dq : inout std_logic_vector(15 downto 0);     -- data lines
82
 
83
                          -- debug signals (possibly could be repurposed later for wider data)
84
                          debug_reg : out   std_logic_vector(7 downto 0)
85
                                 );
86
end sdram_controller;
87
 
88
architecture impl of sdram_controller is
89
 
90
        -- component decls begin here
91
        component sdram_dcm is
92
                port(
93
                        reset      : in  std_logic;
94 8 lynn0p
                        clk100mhz  : in  std_logic;
95 2 lynn0p
                        locked     : out std_logic;
96
                        dram_clkp  : out std_logic;
97
                        dram_clkn  : out std_logic;
98
                        clk_000    : out std_logic;
99
                        clk_090    : out std_logic;
100
                        clk_180    : out std_logic;
101
                        clk_270    : out std_logic
102
                );
103
        end component;
104
 
105
        component oddr2_2 is
106
                port(
107
                        Q  : out std_logic_vector(1 downto 0);
108
                        C0 : in  std_logic;
109
                        C1 : in  std_logic;
110
                        CE : in  std_logic;
111
                        D0 : in  std_logic_vector(1 downto 0);
112
                        D1 : in  std_logic_vector(1 downto 0);
113
                        R  : in  std_logic;
114
                        S  : in  std_logic );
115
        end component;
116
 
117
        component oddr2_3 is
118
                port(
119
                        Q  : out std_logic_vector(2 downto 0);
120
                        C0 : in  std_logic;
121
                        C1 : in  std_logic;
122
                        CE : in  std_logic;
123
                        D0 : in  std_logic_vector(2 downto 0);
124
                        D1 : in  std_logic_vector(2 downto 0);
125
                        R  : in  std_logic;
126
                        S  : in  std_logic );
127
        end component;
128
 
129
        component oddr2_13 is
130
                port(
131
                        Q  : out std_logic_vector(12 downto 0);
132
                        C0 : in  std_logic;
133
                        C1 : in  std_logic;
134
                        CE : in  std_logic;
135
                        D0 : in  std_logic_vector(12 downto 0);
136
                        D1 : in  std_logic_vector(12 downto 0);
137
                        R  : in  std_logic;
138
                        S  : in  std_logic );
139
        end component;
140
 
141
        component inout_switch_2 is
142
                port (
143
                        ioport : inout std_logic_vector(1 downto 0);
144
                                dir : in    std_logic;
145
                        data_i : in    std_logic_vector(1 downto 0)
146
                );
147
        end component;
148
 
149
        component inout_switch_16 is
150
                port (
151
                        ioport : inout std_logic_vector(15 downto 0);
152
                                dir : in    std_logic;
153
                        data_o : out   std_logic_vector(15 downto 0);
154
                        data_i : in    std_logic_vector(15 downto 0)
155
                );
156
        end component;
157
 
158
        component sdram_reader is
159
                port(
160
                        clk270 : in  std_logic;
161
                        rst    : in  std_logic;
162
                        dq     : in  std_logic_vector(15 downto 0);
163
                        data0  : out std_logic_vector(7 downto 0);
164
                        data1  : out std_logic_vector(7 downto 0)
165
                );
166
        end component;
167
 
168
        component sdram_writer is
169
                port(
170
                        clk    : in  std_logic;
171
                        clk090 : in  std_logic;
172
                        clk180 : in  std_logic;
173
                        clk270 : in  std_logic;
174
                        rst    : in  std_logic;
175
                        addr   : in  std_logic;
176
                        data_o : in  std_logic_vector(7 downto 0);
177
                        dqs    : out std_logic_vector(1 downto 0);
178
                        dm     : out std_logic_vector(1 downto 0);
179 6 lynn0p
                        dq     : out std_logic_vector(15 downto 0)
180 2 lynn0p
                );
181
        end component;
182
 
183
        component wait_counter is
184
                generic(
185
                        BITS : integer;
186
                        CLKS : integer
187
                );
188
                port(
189
                         clk : in std_logic;
190
                         rst : in std_logic;
191
                        done : out std_logic
192
                );
193
        end component;
194
 
195
        component sdram_init
196
                port(
197
                        clk_000 : in std_logic;
198
                        reset   : in std_logic;
199
 
200
                        clke  : out std_logic;
201
                        cmd   : out std_logic_vector(2 downto 0);
202
                        bank  : out std_logic_vector(1 downto 0);
203
                        addr  : out std_logic_vector(12 downto 0);
204
                        done  : out std_logic
205
                );
206
        end component;
207
 
208
        component cmd_bank_addr_switch is
209
                port(
210
                        sel      : in std_logic;
211
                        cmd0_in  : in std_logic_vector(2 downto 0);
212
                        bank0_in : in std_logic_vector(1 downto 0);
213
                        addr0_in : in std_logic_vector(12 downto 0);
214
                        cmd1_in  : in std_logic_vector(2 downto 0);
215
                        bank1_in : in std_logic_vector(1 downto 0);
216
                        addr1_in : in std_logic_vector(12 downto 0);
217
                        cmd_out  : out std_logic_vector(2 downto 0);
218
                        bank_out : out std_logic_vector(1 downto 0);
219
                        addr_out : out std_logic_vector(12 downto 0)
220
                );
221
        end component;
222
        -- component decls end here
223
 
224
        -- DRAM commands - <we,cas,ras>
225
        constant CMD_NOP        : std_logic_vector(2 downto 0)  := "111";
226
        constant CMD_ACTIVE     : std_logic_vector(2 downto 0)  := "110"; -- opens a row within a bank
227
        constant CMD_READ       : std_logic_vector(2 downto 0)  := "101";
228
        constant CMD_WRITE      : std_logic_vector(2 downto 0)  := "001";
229
        constant CMD_BURST_TERM : std_logic_vector(2 downto 0)  := "011";
230
        constant CMD_PRECHARGE  : std_logic_vector(2 downto 0)  := "010"; -- closes a row within a bank
231
        constant CMD_AUTO_REFR  : std_logic_vector(2 downto 0)  := "100";
232
        constant CMD_LOAD_MR    : std_logic_vector(2 downto 0)  := "000";
233
 
234
        -- various wait counter values
235
        constant AUTO_REFRESH_CLKS  : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
236
        constant WRITE_RECOVER_CLKS : integer := 5;   -- these are fudged a bit, you *might* be able to shave a clock or two off
237
        constant READ_DONE_CLKS     : integer := 5;
238
 
239
        type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH, STATE_IDLE_WAIT_AR_CTR,
240
                                                                STATE_IDLE_WAIT_AUTO_REFRESH, STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD,
241
                                                                STATE_WRITE_WAIT_RECOVER, STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD,
242
                                                                STATE_READ_WAIT_CAPTURE );
243
 
244
        signal cmd_state : CMD_STATES := STATE_START;
245
 
246
        signal cmd_oddr2_rising   : std_logic_vector(2 downto 0) := CMD_NOP;
247
        signal bank_oddr2_rising  : std_logic_vector(1 downto 0) := "00";
248
        signal addr_oddr2_rising  : std_logic_vector(12 downto 0) := "0000000000000";
249
 
250
        signal dqs_out : std_logic_vector(1 downto 0);
251
        signal dqs_dir : std_logic;
252
 
253
        signal dq_in : std_logic_vector(15 downto 0);
254
        signal dq_out : std_logic_vector(15 downto 0);
255
        signal dq_dir : std_logic;
256
 
257
        signal reader_rst : std_logic := '1';
258
        signal writer_rst : std_logic := '1';
259
 
260
        signal dcm_locked   : std_logic;
261
        signal clk_000      : std_logic;
262
        signal clk_090      : std_logic;
263
        signal clk_180      : std_logic;
264
        signal clk_270      : std_logic;
265
 
266
        -- init module stuff
267
        signal init_reset : std_logic;
268
        signal init_cmd   : std_logic_vector(2 downto 0);
269
        signal init_bank  : std_logic_vector(1 downto 0);
270
        signal init_addr  : std_logic_vector(12 downto 0);
271
        signal init_done  : std_logic;
272
 
273
        -- main module stuff
274
        signal main_sel  : std_logic;
275
        signal main_cmd  : std_logic_vector(2 downto 0);
276
        signal main_bank : std_logic_vector(1 downto 0);
277
        signal main_addr : std_logic_vector(12 downto 0);
278
 
279
        -- wait counter stuff
280
        signal need_ar_rst : std_logic;
281
        signal need_ar     : std_logic;
282
 
283
        signal wait_ar_rst  : std_logic;
284
        signal wait_ar_done : std_logic;
285
 
286
        signal write_reco_rst  : std_logic;
287
        signal write_reco_done : std_logic;
288
 
289
        signal read_wait_rst : std_logic;
290
        signal read_wait_done : std_logic;
291
 
292
        signal data0_o : std_logic_vector(7 downto 0);
293
        signal data1_o : std_logic_vector(7 downto 0);
294 8 lynn0p
 
295
        --
296
        signal cap_en     : std_logic;
297
        signal addr_save  : std_logic_vector(25 downto 0);
298
        signal datai_save : std_logic_vector(7 downto 0);
299 2 lynn0p
 
300
begin
301
 
302
        -- component instantiations begin here
303
        DRAM_DCM: sdram_dcm
304
        port map(
305
                reset           => reset,
306 8 lynn0p
                clk100mhz       => clk100mhz,
307 2 lynn0p
                locked          => dcm_locked,
308
                dram_clkp       => dram_clkp,
309
                dram_clkn       => dram_clkn,
310
                clk_000         => clk_000,
311
                clk_090         => clk_090,
312
                clk_180         => clk_180,
313
                clk_270         => clk_270
314
        );
315
 
316
        DRAM_INIT: sdram_init
317
        port map(
318
                clk_000 => clk_000,
319
                reset   => init_reset,
320
                clke    => dram_clke,
321
                cmd     => init_cmd,
322
                bank    => init_bank,
323
                addr    => init_addr,
324
                done    => init_done
325
        );
326
 
327
        CMD_BANK_ADDR_SEL: cmd_bank_addr_switch
328
        port map(
329
                sel      => main_sel,
330
                cmd0_in  => init_cmd,
331
                bank0_in => init_bank,
332
                addr0_in => init_addr,
333
                cmd1_in  => main_cmd,
334
                bank1_in => main_bank,
335
                addr1_in => main_addr,
336
                cmd_out  => cmd_oddr2_rising,
337
                bank_out => bank_oddr2_rising,
338
                addr_out => addr_oddr2_rising
339
        );
340
 
341
        DRAM_BANK_ODDR2: oddr2_2
342
        port map(
343
                Q  => dram_bank,
344
                C0 => clk_270,
345
                C1 => clk_090,
346
                CE => '1',
347
                D0 => bank_oddr2_rising,
348
                D1 => "00",
349
                R  => '0',
350
                S  => '0' );
351
 
352
        DRAM_CMD_ODDR2: oddr2_3
353
        port map(
354
                Q  => dram_cmd,
355
                C0 => clk_270,
356
                C1 => clk_090,
357
                CE => '1',
358
                D0 => cmd_oddr2_rising,
359
                D1 => CMD_NOP,
360
                R  => '0',
361
                S  => '0' );
362
 
363
        DRAM_ADDR_ODDR2: oddr2_13
364
        port map(
365
                Q  => dram_addr,
366
                C0 => clk_270,
367
                C1 => clk_090,
368
                CE => '1',
369
                D0 => addr_oddr2_rising,
370
                D1 => "0000000000000",
371
                R  => '0',
372
                S  => '0' );
373
 
374
        DQS_SWITCH: inout_switch_2
375
        port map(
376
                ioport => dram_dqs,
377
                dir    => dqs_dir,
378
                data_i => dqs_out
379
        );
380
 
381
        DQ_SWITCH: inout_switch_16
382
        port map(
383
                ioport => dram_dq,
384
                dir    => dq_dir,
385
                data_o => dq_in,
386
                data_i => dq_out
387
        );
388
 
389
        AR_NEEDED_CTR: wait_counter
390
        generic map(
391
                BITS => 10,
392
                CLKS => AUTO_REFRESH_CLKS
393
        )
394
        port map (
395
          clk => clk_000,
396
          rst => need_ar_rst,
397
         done => need_ar
398
        );
399
 
400
        WAIT_AR_CTR: wait_counter
401
        generic map(
402
                BITS => 4,
403
                CLKS => 11
404
        )
405
        port map(
406
                clk => clk_000,
407
                rst => wait_ar_rst,
408
                done => wait_ar_done
409
        );
410
 
411
        WRITE_RECOVER_CTR: wait_counter
412
        generic map(
413
                BITS => 2,
414
                CLKS => WRITE_RECOVER_CLKS
415
        )
416
        port map(
417
          clk => clk_000,
418
          rst => write_reco_rst,
419
         done => write_reco_done
420
        );
421
 
422
        READ_DONE_CTR: wait_counter
423
        generic map(
424
                BITS => 2,
425
                CLKS => READ_DONE_CLKS
426
        )
427
        port map(
428
          clk => clk_000,
429
          rst => read_wait_rst,
430
         done => read_wait_done
431
        );
432
 
433
        READER: sdram_reader
434
        port map(
435
      clk270 => clk_270,
436
      rst    => reader_rst,
437
      dq     => dq_in,
438
                data0  => data0_o,
439
                data1  => data1_o
440
        );
441
 
442
        WRITER: sdram_writer
443
        port map(
444
                clk    => clk_000,
445
                clk090 => clk_090,
446
                clk180 => clk_180,
447
                clk270 => clk_270,
448
                rst    => writer_rst,
449 8 lynn0p
                addr   => addr_save(0),
450
                data_o => datai_save,
451 2 lynn0p
                dqs    => dqs_out,
452
                dm     => dram_dm,
453 6 lynn0p
                dq     => dq_out
454 2 lynn0p
        );
455
        -- end component allocs
456 6 lynn0p
 
457
        debug_reg <= x"00";
458 2 lynn0p
        dram_cs <= '0';
459 8 lynn0p
        data_o <= data1_o when addr_save(0) = '1' else data0_o;
460
 
461
        process (clk_000)
462
        begin
463
                if (rising_edge(clk_000)) then
464
                        if (cap_en = '1') then
465
                                addr_save <= addr;
466
                                datai_save <= data_i;
467
                        end if;
468
                end if;
469
        end process;
470 2 lynn0p
 
471
        -- command state machine
472
        process (clk_000)
473
        begin
474
                if (rising_edge(clk_000)) then
475
                        if (dcm_locked = '1') then
476
                                case cmd_state is
477
                                        when STATE_START =>
478
                                                busy_n <= '0';
479
                                                op_ack <= '0';
480 8 lynn0p
                                                init_reset <= '1';
481
                                                cap_en <= '0';
482 2 lynn0p
                                                main_sel <= '0';
483
                                                main_cmd <= CMD_NOP;
484
                                                main_bank <= "00";
485
                                                main_addr <= "0000000000000";
486
                                                cmd_state <= STATE_INIT;
487
 
488
                                        when STATE_INIT =>
489
                                                init_reset <= '0';
490
                                                cmd_state <= STATE_WAIT_INIT;
491
 
492
                                        when STATE_WAIT_INIT =>
493
                                                need_ar_rst <= '1';
494
                                                if (init_done = '1') then
495
                                                        cmd_state <= STATE_IDLE;
496
                                                else
497
                                                        cmd_state <= cmd_state;
498
                                                end if;
499
 
500
                                        when STATE_IDLE =>
501
                                                -- this is the main hub state
502
                                                -- this is where reads and writes return to after being completed
503
                                                busy_n <= '1';
504
                                                op_ack <= '0';
505 8 lynn0p
                                                need_ar_rst <= '0';
506
                                                cap_en <= '1';
507 2 lynn0p
                                                main_sel <= '1';
508
                                                writer_rst <= '1';
509
                                                reader_rst <= '1';
510 8 lynn0p
                                                if (need_ar = '1') then
511
                                                        busy_n <= '0';
512 2 lynn0p
                                                        cmd_state <= STATE_IDLE_AUTO_REFRESH;
513 6 lynn0p
                                                elsif (op = "01" and en = '1') then
514 8 lynn0p
                                                        busy_n <= '0';
515 2 lynn0p
                                                        cmd_state <= STATE_READ_ROW_OPEN;
516 6 lynn0p
                                                elsif (op = "10" and en = '1') then
517 8 lynn0p
                                                        busy_n <= '0';
518 2 lynn0p
                                                        cmd_state <= STATE_WRITE_ROW_OPEN;
519
                                                else
520
                                                        cmd_state <= cmd_state;
521
                                                end if;
522
 
523
                                        when STATE_IDLE_AUTO_REFRESH =>
524
                                                need_ar_rst <= '1';
525
                                                wait_ar_rst <= '1';
526
                                                main_cmd <= CMD_AUTO_REFR;
527
                                                main_bank <= "00";
528
                                                main_addr <= "0000000000000";
529
                                                cmd_state <= STATE_IDLE_WAIT_AR_CTR;
530
 
531
                                        when STATE_IDLE_WAIT_AR_CTR =>
532
                                                wait_ar_rst <= '0';
533
                                                main_cmd <= CMD_NOP;
534
                                                main_bank <= "00";
535
                                                main_addr <= "0000000000000";
536
                                                cmd_state <= STATE_IDLE_WAIT_AUTO_REFRESH;
537
 
538
                                        when STATE_IDLE_WAIT_AUTO_REFRESH =>
539
                                                main_cmd <= CMD_NOP;
540
                                                main_bank <= "00";
541
                                                main_addr <= "0000000000000";
542
                                                if (wait_ar_done = '1') then
543
                                                        cmd_state <= STATE_IDLE;
544
                                                else
545
                                                        cmd_state <= cmd_state;
546
                                                end if;
547
 
548
                                        when STATE_WRITE_ROW_OPEN =>
549 8 lynn0p
                                                op_ack <= '1';
550 2 lynn0p
                                                busy_n <= '0';
551
                                                dqs_dir <= '1';
552
                                                dq_dir <= '1';
553 8 lynn0p
                                                cap_en <= '0';
554 2 lynn0p
                                                main_cmd <= CMD_ACTIVE;
555 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
556
                                                main_addr <= addr_save(23 downto 11);
557 2 lynn0p
                                                cmd_state <= STATE_WRITE_WAIT_ROW_OPEN;
558
 
559
                                        when STATE_WRITE_WAIT_ROW_OPEN =>
560
                                                main_cmd <= CMD_NOP;
561 8 lynn0p
                                                main_bank <= addr_save(25 downto 24); -- timing kludge
562
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte in word
563 2 lynn0p
                                                cmd_state <= STATE_WRITE_ISSUE_CMD;
564
 
565
                                        when STATE_WRITE_ISSUE_CMD =>
566
                                                writer_rst <= '0';
567
                                                write_reco_rst <= '1';
568
                                                main_cmd <= CMD_WRITE;
569 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
570
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte in word
571 2 lynn0p
                                                cmd_state <= STATE_WRITE_WAIT_RECOVER;
572
 
573
                                        when STATE_WRITE_WAIT_RECOVER =>
574
                                                write_reco_rst <= '0';
575
                                                main_cmd <= CMD_NOP;
576
                                                main_bank <= "00";
577
                                                main_addr <= "0000000000000";
578
                                                if (write_reco_done = '1') then
579
                                                        cmd_state <= STATE_IDLE;
580
                                                else
581
                                                        cmd_state <= cmd_state;
582
                                                end if;
583
 
584
                                        when STATE_READ_ROW_OPEN =>
585 8 lynn0p
                                                op_ack <= '1';
586 2 lynn0p
                                                busy_n <= '0';
587
                                                dqs_dir <= '0';
588
                                                dq_dir <= '0';
589 8 lynn0p
                                                cap_en <= '0';
590 2 lynn0p
                                                main_cmd <= CMD_ACTIVE;
591 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
592
                                                main_addr <= addr_save(23 downto 11);
593 2 lynn0p
                                                cmd_state <= STATE_READ_WAIT_ROW_OPEN;
594
 
595
                                        when STATE_READ_WAIT_ROW_OPEN =>
596
                                                main_cmd <= CMD_NOP;
597 8 lynn0p
                                                main_bank <= addr_save(25 downto 24); -- timing kludge
598
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
599 2 lynn0p
                                                cmd_state <= STATE_READ_ISSUE_CMD;
600
 
601
                                        when STATE_READ_ISSUE_CMD =>
602
                                                read_wait_rst <= '1';
603
                                                main_cmd <= CMD_READ;
604 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
605
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
606 2 lynn0p
                                                cmd_state <= STATE_READ_WAIT_CAPTURE;
607
 
608
                                        when STATE_READ_WAIT_CAPTURE =>
609
                                                read_wait_rst <= '0';
610
                                                reader_rst <= '0';
611
                                                main_cmd <= CMD_NOP;
612
                                                main_bank <= "00";
613
                                                main_addr <= "0000000000000";
614
                                                if (read_wait_done = '1') then
615
                                                        cmd_state <= STATE_IDLE;
616
                                                else
617
                                                        cmd_state <= cmd_state;
618
                                                end if;
619
                                end case;
620
                        end if;
621
                end if;
622
        end process;
623
 
624
end impl;
625
 
626
 

powered by: WebSVN 2.1.0

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