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

Subversion Repositories sdram_controller

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

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 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
                 en : in  std_logic;
62
                     reset : in  std_logic;
63
                        op : in  std_logic_vector(1 downto 0);        -- 00/11: NOP, 01: READ, 10: write
64
                      addr : in  std_logic_vector(25 downto 0);       -- address to read/write 
65
                    op_ack : out std_logic;                           -- op, addr and data_i should be captured when this goes high
66
                    busy_n : out std_logic;                           -- busy when LOW, ops will be ignored until busy goes high again
67
                    data_o : out std_logic_vector(7 downto 0);        -- data from read shows up here
68
                    data_i : in  std_logic_vector(7 downto 0);        -- data to write needs to be here
69 2 lynn0p
 
70
                -- SDRAM facing signals 
71
                          dram_clkp : out   std_logic;                         -- 0 deg phase 100mhz clock going out to SDRAM chip
72
                          dram_clkn : out   std_logic;                         -- 180 deg phase version of dram_clkp
73
                dram_clke : out   std_logic;                         -- clock enable, owned by the init module
74
                            dram_cs : out   std_logic;                         -- tied low upon powerup
75
                 dram_cmd : out   std_logic_vector(2 downto 0);      -- this is the command vector <we_n,cas_n,ras_n>
76
           dram_bank : out   std_logic_vector(1 downto 0);      -- bank address
77
                          dram_addr : out   std_logic_vector(12 downto 0);     -- row/col/mode register
78
                            dram_dm : out   std_logic_vector(1 downto 0);      -- masks used for writing
79
                           dram_dqs : inout std_logic_vector(1 downto 0);      -- strobes used for writing
80
                            dram_dq : inout std_logic_vector(15 downto 0);     -- data lines
81
 
82
                          -- debug signals (possibly could be repurposed later for wider data)
83
                          debug_reg : out   std_logic_vector(7 downto 0)
84
                                 );
85
end sdram_controller;
86
 
87
architecture impl of sdram_controller is
88
 
89
        -- component decls begin here
90
        component sdram_dcm is
91
                port(
92
                        reset      : in  std_logic;
93 8 lynn0p
                        clk100mhz  : in  std_logic;
94 2 lynn0p
                        locked     : out std_logic;
95
                        dram_clkp  : out std_logic;
96
                        dram_clkn  : out std_logic;
97
                        clk_000    : out std_logic;
98
                        clk_090    : out std_logic;
99
                        clk_180    : out std_logic;
100
                        clk_270    : out std_logic
101
                );
102
        end component;
103
 
104
        component oddr2_2 is
105
                port(
106
                        Q  : out std_logic_vector(1 downto 0);
107
                        C0 : in  std_logic;
108
                        C1 : in  std_logic;
109
                        CE : in  std_logic;
110
                        D0 : in  std_logic_vector(1 downto 0);
111
                        D1 : in  std_logic_vector(1 downto 0);
112
                        R  : in  std_logic;
113
                        S  : in  std_logic );
114
        end component;
115
 
116
        component oddr2_3 is
117
                port(
118
                        Q  : out std_logic_vector(2 downto 0);
119
                        C0 : in  std_logic;
120
                        C1 : in  std_logic;
121
                        CE : in  std_logic;
122
                        D0 : in  std_logic_vector(2 downto 0);
123
                        D1 : in  std_logic_vector(2 downto 0);
124
                        R  : in  std_logic;
125
                        S  : in  std_logic );
126
        end component;
127
 
128
        component oddr2_13 is
129
                port(
130
                        Q  : out std_logic_vector(12 downto 0);
131
                        C0 : in  std_logic;
132
                        C1 : in  std_logic;
133
                        CE : in  std_logic;
134
                        D0 : in  std_logic_vector(12 downto 0);
135
                        D1 : in  std_logic_vector(12 downto 0);
136
                        R  : in  std_logic;
137
                        S  : in  std_logic );
138
        end component;
139
 
140
        component inout_switch_2 is
141
                port (
142
                        ioport : inout std_logic_vector(1 downto 0);
143
                                dir : in    std_logic;
144
                        data_i : in    std_logic_vector(1 downto 0)
145
                );
146
        end component;
147
 
148
        component inout_switch_16 is
149
                port (
150
                        ioport : inout std_logic_vector(15 downto 0);
151
                                dir : in    std_logic;
152
                        data_o : out   std_logic_vector(15 downto 0);
153
                        data_i : in    std_logic_vector(15 downto 0)
154
                );
155
        end component;
156
 
157
        component sdram_reader is
158
                port(
159
                        clk270 : in  std_logic;
160
                        rst    : in  std_logic;
161
                        dq     : in  std_logic_vector(15 downto 0);
162
                        data0  : out std_logic_vector(7 downto 0);
163
                        data1  : out std_logic_vector(7 downto 0)
164
                );
165
        end component;
166
 
167
        component sdram_writer is
168
                port(
169
                        clk    : in  std_logic;
170
                        clk090 : in  std_logic;
171
                        clk180 : in  std_logic;
172
                        clk270 : in  std_logic;
173
                        rst    : in  std_logic;
174
                        addr   : in  std_logic;
175
                        data_o : in  std_logic_vector(7 downto 0);
176
                        dqs    : out std_logic_vector(1 downto 0);
177
                        dm     : out std_logic_vector(1 downto 0);
178 6 lynn0p
                        dq     : out std_logic_vector(15 downto 0)
179 2 lynn0p
                );
180
        end component;
181
 
182
        component wait_counter is
183
                generic(
184
                        BITS : integer;
185
                        CLKS : integer
186
                );
187
                port(
188
                         clk : in std_logic;
189
                         rst : in std_logic;
190
                        done : out std_logic
191
                );
192
        end component;
193
 
194
        component sdram_init
195
                port(
196
                        clk_000 : in std_logic;
197
                        reset   : in std_logic;
198
 
199
                        clke  : out std_logic;
200
                        cmd   : out std_logic_vector(2 downto 0);
201
                        bank  : out std_logic_vector(1 downto 0);
202
                        addr  : out std_logic_vector(12 downto 0);
203
                        done  : out std_logic
204
                );
205
        end component;
206
 
207
        component cmd_bank_addr_switch is
208
                port(
209
                        sel      : in std_logic;
210
                        cmd0_in  : in std_logic_vector(2 downto 0);
211
                        bank0_in : in std_logic_vector(1 downto 0);
212
                        addr0_in : in std_logic_vector(12 downto 0);
213
                        cmd1_in  : in std_logic_vector(2 downto 0);
214
                        bank1_in : in std_logic_vector(1 downto 0);
215
                        addr1_in : in std_logic_vector(12 downto 0);
216
                        cmd_out  : out std_logic_vector(2 downto 0);
217
                        bank_out : out std_logic_vector(1 downto 0);
218
                        addr_out : out std_logic_vector(12 downto 0)
219
                );
220
        end component;
221
        -- component decls end here
222
 
223 10 lynn0p
        -- DRAM commands - <we_n,cas_n,ras_n>
224 2 lynn0p
        constant CMD_NOP        : std_logic_vector(2 downto 0)  := "111";
225
        constant CMD_ACTIVE     : std_logic_vector(2 downto 0)  := "110"; -- opens a row within a bank
226
        constant CMD_READ       : std_logic_vector(2 downto 0)  := "101";
227
        constant CMD_WRITE      : std_logic_vector(2 downto 0)  := "001";
228
        constant CMD_BURST_TERM : std_logic_vector(2 downto 0)  := "011";
229
        constant CMD_PRECHARGE  : std_logic_vector(2 downto 0)  := "010"; -- closes a row within a bank
230
        constant CMD_AUTO_REFR  : std_logic_vector(2 downto 0)  := "100";
231
        constant CMD_LOAD_MR    : std_logic_vector(2 downto 0)  := "000";
232
 
233
        -- various wait counter values
234
        constant AUTO_REFRESH_CLKS  : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
235 12 lynn0p
        constant WRITE_RECOVER_CLKS : integer := 5;   -- these are fudged a bit, you *might* be able to shave a clock or two off
236 17 lynn0p
        constant READ_DONE_CLKS     : integer := 4;   --  or shave a clock or two off if your board timing is a bit wedgy
237 2 lynn0p
 
238 10 lynn0p
        type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH,
239
                             STATE_IDLE_CHECK_OP_PENDING, STATE_IDLE_WAIT_AR_CTR, STATE_IDLE_WAIT_AUTO_REFRESH,
240
                                                                STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD, STATE_WRITE_WAIT_RECOVER,
241
                                                                STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD, STATE_READ_WAIT_CAPTURE );
242 2 lynn0p
 
243
        signal cmd_state : CMD_STATES := STATE_START;
244
 
245
        signal cmd_oddr2_rising   : std_logic_vector(2 downto 0) := CMD_NOP;
246
        signal bank_oddr2_rising  : std_logic_vector(1 downto 0) := "00";
247
        signal addr_oddr2_rising  : std_logic_vector(12 downto 0) := "0000000000000";
248
 
249
        signal dqs_out : std_logic_vector(1 downto 0);
250
        signal dqs_dir : std_logic;
251
 
252
        signal dq_in : std_logic_vector(15 downto 0);
253
        signal dq_out : std_logic_vector(15 downto 0);
254
        signal dq_dir : std_logic;
255
 
256
        signal reader_rst : std_logic := '1';
257
        signal writer_rst : std_logic := '1';
258
 
259
        signal dcm_locked   : std_logic;
260
        signal clk_000      : std_logic;
261
        signal clk_090      : std_logic;
262
        signal clk_180      : std_logic;
263
        signal clk_270      : std_logic;
264
 
265
        -- init module stuff
266
        signal init_reset : std_logic;
267
        signal init_cmd   : std_logic_vector(2 downto 0);
268
        signal init_bank  : std_logic_vector(1 downto 0);
269
        signal init_addr  : std_logic_vector(12 downto 0);
270
        signal init_done  : std_logic;
271
 
272
        -- main module stuff
273
        signal main_sel  : std_logic;
274
        signal main_cmd  : std_logic_vector(2 downto 0);
275
        signal main_bank : std_logic_vector(1 downto 0);
276
        signal main_addr : std_logic_vector(12 downto 0);
277
 
278
        -- wait counter stuff
279
        signal need_ar_rst : std_logic;
280
        signal need_ar     : std_logic;
281
 
282
        signal wait_ar_rst  : std_logic;
283
        signal wait_ar_done : std_logic;
284
 
285
        signal write_reco_rst  : std_logic;
286
        signal write_reco_done : std_logic;
287
 
288
        signal read_wait_rst : std_logic;
289
        signal read_wait_done : std_logic;
290
 
291
        signal data0_o : std_logic_vector(7 downto 0);
292
        signal data1_o : std_logic_vector(7 downto 0);
293 8 lynn0p
 
294 10 lynn0p
        -- capture signals
295 8 lynn0p
        signal cap_en     : std_logic;
296 10 lynn0p
        signal op_save    : std_logic_vector(1 downto 0);
297 8 lynn0p
        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 17 lynn0p
--      process (clk_000)
462
--      begin
463
--              if (cap_en = '1') then
464
--                      if (rising_edge(clk_000)) then
465
--                              addr_save <= addr;
466
--                              datai_save <= data_i;
467
--                              op_save <= op;
468
--                      end if;
469
--              end if;
470
--      end process;
471
 
472
        -- this will probably make the synthesizer scream bloody murder
473
        -- over either a transparent latch or gated clock or both
474
        -- but i've got it working again with my SoC and I'll see about
475
        -- changing it back to something less icky later
476 11 lynn0p
        -- capture addr, data_i and op for the cmd fsm
477 12 lynn0p
        -- op needs to be captured during AR or it might get dropped
478 17 lynn0p
        addr_save  <= addr   when cap_en = '1' else addr_save;
479
        datai_save <= data_i when cap_en = '1' else datai_save;
480
        op_save    <= op     when cap_en = '1' else op_save;
481 10 lynn0p
 
482 2 lynn0p
        -- command state machine
483
        process (clk_000)
484
        begin
485
                if (rising_edge(clk_000)) then
486
                        if (dcm_locked = '1') then
487
                                case cmd_state is
488
                                        when STATE_START =>
489
                                                busy_n <= '0';
490
                                                op_ack <= '0';
491 8 lynn0p
                                                init_reset <= '1';
492
                                                cap_en <= '0';
493 2 lynn0p
                                                main_sel <= '0';
494
                                                main_cmd <= CMD_NOP;
495
                                                main_bank <= "00";
496
                                                main_addr <= "0000000000000";
497
                                                cmd_state <= STATE_INIT;
498
 
499
                                        when STATE_INIT =>
500
                                                init_reset <= '0';
501
                                                cmd_state <= STATE_WAIT_INIT;
502
 
503
                                        when STATE_WAIT_INIT =>
504
                                                need_ar_rst <= '1';
505
                                                if (init_done = '1') then
506
                                                        cmd_state <= STATE_IDLE;
507
                                                else
508
                                                        cmd_state <= cmd_state;
509
                                                end if;
510
 
511
                                        when STATE_IDLE =>
512
                                                -- this is the main hub state
513
                                                -- this is where reads and writes return to after being completed
514
                                                busy_n <= '1';
515 16 lynn0p
                                                op_ack <= '0';
516 8 lynn0p
                                                need_ar_rst <= '0';
517 2 lynn0p
                                                main_sel <= '1';
518
                                                writer_rst <= '1';
519
                                                reader_rst <= '1';
520 10 lynn0p
                                                cap_en <= '1';
521 8 lynn0p
                                                if (need_ar = '1') then
522
                                                        busy_n <= '0';
523 2 lynn0p
                                                        cmd_state <= STATE_IDLE_AUTO_REFRESH;
524 10 lynn0p
                                                elsif (op = "01") then
525 8 lynn0p
                                                        busy_n <= '0';
526 17 lynn0p
                                                        op_ack <= '1';
527
                                                        cap_en <= '0';
528 2 lynn0p
                                                        cmd_state <= STATE_READ_ROW_OPEN;
529 10 lynn0p
                                                elsif (op = "10") then
530 8 lynn0p
                                                        busy_n <= '0';
531 10 lynn0p
                                                        op_ack <= '1';
532 17 lynn0p
                                                        cap_en <= '0';
533 2 lynn0p
                                                        cmd_state <= STATE_WRITE_ROW_OPEN;
534
                                                else
535
                                                        cmd_state <= cmd_state;
536
                                                end if;
537
 
538 10 lynn0p
                                        when STATE_IDLE_AUTO_REFRESH =>
539
                                                if (op = "01" or op = "10") then
540
                                                        cap_en <= '0';
541
                                                end if;
542 2 lynn0p
                                                need_ar_rst <= '1';
543
                                                wait_ar_rst <= '1';
544
                                                main_cmd <= CMD_AUTO_REFR;
545
                                                main_bank <= "00";
546
                                                main_addr <= "0000000000000";
547
                                                cmd_state <= STATE_IDLE_WAIT_AR_CTR;
548
 
549
                                        when STATE_IDLE_WAIT_AR_CTR =>
550 10 lynn0p
                                                if (op = "01" or op = "10") then
551
                                                        cap_en <= '0';
552
                                                end if;
553 2 lynn0p
                                                wait_ar_rst <= '0';
554
                                                main_cmd <= CMD_NOP;
555
                                                main_bank <= "00";
556
                                                main_addr <= "0000000000000";
557
                                                cmd_state <= STATE_IDLE_WAIT_AUTO_REFRESH;
558
 
559
                                        when STATE_IDLE_WAIT_AUTO_REFRESH =>
560 10 lynn0p
                                                if (op = "01" or op = "10") then
561
                                                        cap_en <= '0';
562
                                                end if;
563 2 lynn0p
                                                main_cmd <= CMD_NOP;
564
                                                main_bank <= "00";
565
                                                main_addr <= "0000000000000";
566 10 lynn0p
                                                if (wait_ar_done = '1') then
567
                                                        cmd_state <= STATE_IDLE_CHECK_OP_PENDING;
568 2 lynn0p
                                                else
569
                                                        cmd_state <= cmd_state;
570 10 lynn0p
                                                end if;
571
 
572 17 lynn0p
                                        when STATE_IDLE_CHECK_OP_PENDING =>
573
                                                if ( cap_en = '0') then
574
                                                        if    (op_save = "01") then
575
                                                                op_ack <= '1';
576
                                                                cmd_state <= STATE_READ_ROW_OPEN;
577
                                                        elsif (op_save = "10") then
578
                                                                op_ack <= '1';
579
                                                                cmd_state <= STATE_WRITE_ROW_OPEN;
580
                                                        else
581
                                                                cmd_state <= STATE_IDLE;
582
                                                        end if;
583 10 lynn0p
                                                else
584
                                                        cmd_state <= STATE_IDLE;
585 2 lynn0p
                                                end if;
586
 
587 17 lynn0p
                                        when STATE_WRITE_ROW_OPEN =>
588 2 lynn0p
                                                dqs_dir <= '1';
589
                                                dq_dir <= '1';
590
                                                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_WRITE_WAIT_ROW_OPEN;
594
 
595
                                        when STATE_WRITE_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 in word
599 2 lynn0p
                                                cmd_state <= STATE_WRITE_ISSUE_CMD;
600
 
601
                                        when STATE_WRITE_ISSUE_CMD =>
602
                                                writer_rst <= '0';
603
                                                write_reco_rst <= '1';
604
                                                main_cmd <= CMD_WRITE;
605 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
606
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte in word
607 2 lynn0p
                                                cmd_state <= STATE_WRITE_WAIT_RECOVER;
608
 
609
                                        when STATE_WRITE_WAIT_RECOVER =>
610
                                                write_reco_rst <= '0';
611
                                                main_cmd <= CMD_NOP;
612
                                                main_bank <= "00";
613
                                                main_addr <= "0000000000000";
614
                                                if (write_reco_done = '1') then
615
                                                        cmd_state <= STATE_IDLE;
616
                                                else
617
                                                        cmd_state <= cmd_state;
618
                                                end if;
619
 
620 17 lynn0p
                                        when STATE_READ_ROW_OPEN =>
621 2 lynn0p
                                                dqs_dir <= '0';
622
                                                dq_dir <= '0';
623
                                                main_cmd <= CMD_ACTIVE;
624 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
625
                                                main_addr <= addr_save(23 downto 11);
626 2 lynn0p
                                                cmd_state <= STATE_READ_WAIT_ROW_OPEN;
627
 
628
                                        when STATE_READ_WAIT_ROW_OPEN =>
629
                                                main_cmd <= CMD_NOP;
630 8 lynn0p
                                                main_bank <= addr_save(25 downto 24); -- timing kludge
631
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
632 2 lynn0p
                                                cmd_state <= STATE_READ_ISSUE_CMD;
633
 
634
                                        when STATE_READ_ISSUE_CMD =>
635
                                                read_wait_rst <= '1';
636
                                                main_cmd <= CMD_READ;
637 8 lynn0p
                                                main_bank <= addr_save(25 downto 24);
638
                                                main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
639 2 lynn0p
                                                cmd_state <= STATE_READ_WAIT_CAPTURE;
640
 
641
                                        when STATE_READ_WAIT_CAPTURE =>
642
                                                read_wait_rst <= '0';
643
                                                reader_rst <= '0';
644
                                                main_cmd <= CMD_NOP;
645
                                                main_bank <= "00";
646
                                                main_addr <= "0000000000000";
647
                                                if (read_wait_done = '1') then
648
                                                        cmd_state <= STATE_IDLE;
649
                                                else
650
                                                        cmd_state <= cmd_state;
651
                                                end if;
652
                                end case;
653
                        end if;
654
                end if;
655
        end process;
656
 
657
end impl;
658
 
659
 

powered by: WebSVN 2.1.0

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