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

Subversion Repositories sdram_controller

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

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

powered by: WebSVN 2.1.0

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