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

Subversion Repositories ddr2_sdram

[/] [ddr2_sdram/] [trunk/] [DDR2_Control_VHDL.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 john_fpga
---------------------------------------------------------------------
2
-- File :                       DDR2_Control_VHDL.vhd
3
-- Projekt :            Prj_12_DDR2
4
-- Zweck :                      DDR2-Verwaltung (Init,Read,Write)
5
-- Datum :        19.08.2011
6
-- Version :      2.0
7
-- Plattform :    XILINX Spartan-3A
8
-- FPGA :         XC3S700A-FGG484
9
-- Sprache :      VHDL
10
-- ISE :                                ISE-Design-Suite V:13.1
11
-- Autor :        UB
12
-- Mail :         Becker_U(at)gmx.de
13
---------------------------------------------------------------------
14
library IEEE;
15
use IEEE.STD_LOGIC_1164.ALL;
16
use IEEE.STD_LOGIC_ARITH.ALL;
17
use IEEE.STD_LOGIC_UNSIGNED.ALL;
18
 
19
        --------------------------------------------
20
        -- Beschreibung :
21
        --
22
        -- das DDR2-RAM hat 512 MBit (64MByte) Speicherplatz
23
        -- organisiert in 16Bit Woertern
24
        --
25
        -- es werden immer Datenworte von 64Bit ausgelesen
26
        -- oder geschrieben (weil der Burst-Mode auf 4 steht)
27
        -- aus dem Grund ist der Daten-Vektor für Read/Write
28
        -- 64Bit breit
29
        --
30
        -- das RAM ist ein 4 Blöcke unterteilt (zu je 16Mbyte)
31
        -- Bank "00" bis Bank "11" : 2Bit
32
        --
33
        -- jeder Block ist in 8192 Reihen zu je 1024 Spalten organisiert
34
        -- ROW "0000000000000" bis "1111111111111" : 13Bit
35
        -- COL "0000000000" bis "1111111111" : 10Bit
36
        --
37
        -- die übergebene Adresse an die FIFO Komponente
38
        -- mit 25 Bit setzt sich dann so zusammen
39
        --
40
        -- input_adress =  ROW & COL & BANK
41
        --    (25Bit)     13Bit 10Bit  2Bit
42
        -- pro Adresse stehen 16bit Daten
43
        -- 
44
        -- in diesem Demo-Programm wird nur Bank=0
45
        -- COL=0 und ROW= 0 bis 15 benutzt
46
        ---------------------------------------------
47
        --
48
        -- das CONTROL steuert die READ und WRITE funktion
49
        -- je nachdem welcher Button gedrückt wurde
50
        --
51
        --------------------------------------------
52
        -- Vorsicht !! zur Adressierung :
53
        -- Der Burst-Mode steht FIX auf "4"
54
        -- damit werden IMMER 4 (16bit) Zellen gelesen
55
        -- und beschrieben (also imer 64Bit)
56
        --
57
        -- wenn also das 64bit Wort "123456789ABCDEF0" in Adr 0
58
        -- geschrieben wird, sieht der Speicher danach so aus :
59
        -- Row 0 Col 0 = "1234"
60
        -- Row 0 Col 1 = "5678"
61
        -- Row 0 Col 2 = "9ABC"
62
        -- Row 0 Col 3 = "DEF0"
63
        --
64
        -- Der Col-Counter muss also immer um 4 Adressen
65
        -- incrementiert / decrementiert werden
66
        --
67
        -- in der Demo hier wird nur der ROW-Counter verändert
68
        -- 
69
        --------------------------------------------
70
 
71
 
72
 
73
entity DDR2_Control_VHDL is
74
 
75
        --------------------------------------------
76
        -- Port Deklerationen
77
        --------------------------------------------
78
        port (
79
                reset_in : in std_logic;
80
                clk_in : in std_logic;
81
                clk90_in : in std_logic;
82
                init_done : in std_logic;
83
                command_register : out std_logic_vector(2 downto 0);
84
                input_adress : out std_logic_vector(24 downto 0);
85
                input_data : out std_logic_vector(31 downto 0);
86
                output_data : in std_logic_vector(31 downto 0);
87
                cmd_ack : in std_logic;
88
                data_valid : in std_logic;
89
                burst_done : out std_logic;
90
                auto_ref_req : in std_logic;
91
                debounce_in : in std_logic_vector(7 downto 0);
92
                risingedge_in : in std_logic_vector(3 downto 0);
93
                data_out : out std_logic_vector(7 downto 0)
94
        );
95
 
96
end DDR2_Control_VHDL;
97
 
98
architecture Verhalten of DDR2_Control_VHDL is
99
 
100
        --------------------------------------------
101
        -- Einbinden einer Componente
102
        -- zum schreiben eines 64Bit Wertes
103
        --------------------------------------------
104
        COMPONENT DDR2_Write_VHDL
105
        PORT (
106
                reset_in : in std_logic;
107
                clk_in : in std_logic;
108
                clk90_in : in std_logic;
109
                w_command_register : out std_logic_vector(2 downto 0);
110
                w_cmd_ack : in std_logic;
111
                w_burst_done : out std_logic;
112
                write_en : in std_logic;
113
                write_busy : out std_logic;
114
                input_data : out std_logic_vector(31 downto 0);
115
                write_data : in std_logic_vector(63 downto 0)
116
        );
117
        END COMPONENT DDR2_Write_VHDL;
118
 
119
        --------------------------------------------
120
        -- Einbinden einer Componente
121
        -- zum lesen eines 64Bit Wertes
122
        --------------------------------------------
123
        COMPONENT DDR2_Read_VHDL
124
        PORT (
125
                reset_in : in std_logic;
126
                clk_in : in std_logic;
127
                clk90_in : in std_logic;
128
                r_command_register : out std_logic_vector(2 downto 0);
129
                r_cmd_ack : in std_logic;
130
                r_burst_done : out std_logic;
131
                r_data_valid : in std_logic;
132
                read_en : in std_logic;
133
                read_busy : out std_logic;
134
                output_data : in std_logic_vector(31 downto 0);
135
                read_data : out std_logic_vector(63 downto 0)
136
        );
137
        END COMPONENT DDR2_Read_VHDL;
138
 
139
        --------------------------------------------
140
        -- Interne Signale
141
        --------------------------------------------
142
 
143
        constant INIT_PAUSE : integer := 133000; -- pause 1ms (Wichtig !!)
144
        signal v_counter :  natural range 0 to INIT_PAUSE := INIT_PAUSE;
145
 
146
        --------------------------------------------
147
        -- 16 Konstante Werte erzeugen, die beim INIT
148
        -- (Auto-Write) ins RAM geschrieben werden
149
        -- ein Wert ist 64Bit = 8 Byte breit
150
        --------------------------------------------
151
        constant MAX_ADR : integer := 15; -- 0 bis 15 = 16 Werte
152
        type RAM_DATA_TYP is array (0 to MAX_ADR) of std_logic_vector(63 downto 0);
153
        constant RAM_DATA : RAM_DATA_TYP :=
154
        (
155
                x"0123456789ABCDEF", x"123456789ABCDEF0", x"23456789ABCDEF01", x"3456789ABCDEF012",
156
                x"456789ABCDEF0123", x"56789ABCDEF01234", others => (x"639CC6398C7318E7")
157
        );
158
        signal v_array_pos :  natural range 0 to MAX_ADR+1 := 0;
159
 
160
        --------------------------------------------
161
        -- Definition der ROW,COL,BANK adressen
162
        --------------------------------------------
163
        signal v_ROW : std_logic_vector(12 downto 0):= (others => '0'); -- 13Bit
164
        signal v_COL : std_logic_vector(9 downto 0):= (others => '0');  -- 10Bit
165
        signal v_BANK : std_logic_vector(1 downto 0):= (others => '0'); -- 2Bit
166
 
167
        -- zwischenspeicher fuer daten
168
        signal v_write_data : std_logic_vector(63 downto 0):= (others => '0');
169
        signal v_read_data : std_logic_vector(63 downto 0):= (others => '0');
170
 
171
        --------------------------------------------
172
        -- Ein Konstanter Wert, der mit WRITE-Button
173
        -- ins RAM geschrieben wird
174
        --------------------------------------------    
175
        constant CONST_DATA : std_logic_vector(63 downto 0):= x"31CE629DC43B8877";
176
 
177
        --------------------------------------------
178
        -- State-Machine-Typen
179
        --------------------------------------------    
180
        type STATE_M_TYPE is (
181
                M1_START_UP,
182
                M2_WAIT_4_DONE,
183
                M3_AUTO_WRITE_START,
184
                M4_AUTO_WRITE_INIT,
185
                M5_AUTO_WRITING,
186
                M6_AUTO_READ_INIT,
187
                M7_AUTO_READING,
188
                M8_NOP,
189
                M9_WRITE_INIT,
190
                M10_WRITING,
191
                M11_READ_INIT,
192
                M12_READING
193
        );
194
        signal STATE_M : STATE_M_TYPE := M1_START_UP;
195
 
196
        --------------------------------------------
197
        -- sonstige Signale
198
        --------------------------------------------            
199
        signal v_write_en : std_logic:='0'; -- '1'=chip-select
200
        signal v_read_en : std_logic:='0'; -- '1'=chip-select
201
        signal v_write_busy : std_logic; -- '1'=belegt, '0'=frei
202
        signal v_read_busy : std_logic; -- '1'=belegt, '0'=frei
203
        signal v_main_command_register : std_logic_vector(2 downto 0):= (others => '0');
204
        signal v_write_command_register : std_logic_vector(2 downto 0):= (others => '0');
205
        signal v_read_command_register : std_logic_vector(2 downto 0):= (others => '0');
206
        signal v_write_burst_done : std_logic;
207
        signal v_read_burst_done : std_logic;
208
 
209
begin
210
 
211
        --------------------------------------------------
212
        -- Instantz einer Componente erzeugen und verbinden
213
        -- zum schreiben eines 64Bit Wertes
214
        --------------------------------------------------
215
        INST_DDR2_Write_VHDL : DDR2_Write_VHDL
216
        PORT MAP (
217
                reset_in => reset_in,
218
                clk_in => clk_in,
219
                clk90_in => clk90_in,
220
                w_command_register => v_write_command_register,
221
                w_cmd_ack => cmd_ack,
222
                w_burst_done => v_write_burst_done,
223
                write_en => v_write_en,
224
                write_busy => v_write_busy,
225
                input_data => input_data,
226
                write_data => v_write_data
227
        );
228
 
229
        --------------------------------------------------
230
        -- Instantz einer Componente erzeugen und verbinden
231
        -- zum lesen eines 64Bit Wertes
232
        --------------------------------------------------
233
        INST_DDR2_Read_VHDL : DDR2_Read_VHDL
234
        PORT MAP (
235
                reset_in => reset_in,
236
                clk_in => clk_in,
237
                clk90_in => clk90_in,
238
                r_command_register => v_read_command_register,
239
                r_cmd_ack => cmd_ack,
240
                r_burst_done => v_read_burst_done,
241
                r_data_valid => data_valid,
242
                read_en => v_read_en,
243
                read_busy => v_read_busy,
244
                output_data => output_data,
245
                read_data => v_read_data
246
        );
247
 
248
        -----------------------------------------
249
        -- State-Machine :
250
        --   1. wartet nach Reset 1ms
251
        --   2. sendet das INIT-Kommando an das RAM
252
        --   3. Wartet auf das INIT_DONE vom RAM
253
        --   4. Schreiben von 16 Datenwerten ins RAM
254
        --   5. Auslesen von Adr0
255
        --   6. Warte auf Tastendrück
256
        --
257
        --     7a. North/South = ändern der Adresse (ROW)
258
        --     7b. East = auslesen eines Wertes
259
        --     7c. West = schreiben eines Wertes
260
        --   8. Sprung zu Punkt 6
261
        -----------------------------------------       
262
        P_State_Main : process(clk_in,reset_in)
263
        begin
264
                if reset_in = '1' then
265
                        -- reset button ist gedrueckt
266
                        STATE_M <= M1_START_UP;
267
                        v_write_en <= '0';
268
                        v_read_en <= '0';
269
                        v_main_command_register <= "000"; -- NOP
270
                        v_counter <= INIT_PAUSE;
271
                        v_ROW <= (others => '0');
272
                        v_COL <= (others => '0');
273
                        v_BANK <= (others => '0');
274
                        v_array_pos     <= 0;
275
                elsif falling_edge(clk_in) then
276
                        case STATE_M is
277
                           -----------------------------------------------------
278
                                -- INITIALISIERUNG vom RAM : WICHTIG !! :
279
                                -- nach dem Reset wird 1ms gewartet und danach
280
                                -- wird das INIT-Kommando an das RAM gesendet
281
                                -- und auf das Init-Done-Signal vom RAM gewartet
282
                                -----------------------------------------------------
283
                                when M1_START_UP =>
284
                                        -- warte 1ms nach Reset bis RAM bereit
285
                                        -- WICHTIG !! das steht so im Datasheet
286
                                        if v_counter = 0 then
287
                                                -- nach 1ms INIT-Kommando (für einen Clock) anlegen
288
                                                STATE_M <= M2_WAIT_4_DONE;
289
                                                v_main_command_register <= "010";       -- INIT-CMD     
290
                                        else
291
                                                v_main_command_register <= "000"; -- NOP
292
                                                v_counter <= v_counter - 1;
293
                                        end if;
294
                                when M2_WAIT_4_DONE =>
295
                                        -- warte auf Init-Done-Signal vom RAM
296
                                        v_main_command_register <= "000"; -- NOP
297
                                        if (init_done = '1') then
298
                                                -- das RAM ist jetzt bereit
299
                                                STATE_M <= M3_AUTO_WRITE_START;
300
                                        end if;
301
                           -----------------------------------------------------
302
                                -- automatisches schreiben von ein paar Werten :
303
                                -- es werden 16 feste Datenwerte in die Adressen 0-15
304
                                -- ins RAM geschrieben
305
                                -----------------------------------------------------                                   
306
                                when M3_AUTO_WRITE_START =>
307
                                        -- automatisches schreiben von daten ins RAM
308
                                        if v_array_pos > MAX_ADR then
309
                                                -- wenn alle adressen geschrieben sind
310
                                                STATE_M <= M6_AUTO_READ_INIT;
311
                                                v_ROW <= (others => '0');
312
                                        else
313
                                                if v_write_busy = '0' and auto_ref_req = '0' then
314
                                                        -- wenn RAM nicht beschäftigt ist, starte das schreiben
315
                                                        STATE_M <= M4_AUTO_WRITE_INIT;
316
                                                end if;
317
                                        end if;
318
                                when M4_AUTO_WRITE_INIT =>
319
                                        -- warten bis zum schreiben bereit
320
                                        if v_write_busy = '0' and v_write_en='0' then
321
                                                -- daten zum schreiben freigeben
322
                                                v_write_en <= '1';
323
                                        elsif v_write_busy = '1' and v_write_en='1' then
324
                                                -- daten werden geschrieben
325
                                                v_write_en <= '0';
326
                                                STATE_M <= M5_AUTO_WRITING;
327
                                        end if;
328
                                when M5_AUTO_WRITING =>
329
                                        -- warte bis schreiben fertig
330
                                        if v_write_busy = '0' then
331
                                                -- naechste adresse beschreiben                                         
332
                                                v_array_pos <= v_array_pos +1;
333
                                                v_ROW <= v_ROW +1;
334
                                                STATE_M <= M3_AUTO_WRITE_START;
335
                                        end if;
336
                           -----------------------------------------------------
337
                                -- automatisches lesen von einem Wert :
338
                                -- es wird der Inhalt von Adr 0 vom RAM ausgelesen
339
                                -----------------------------------------------------                                   
340
                                when M6_AUTO_READ_INIT =>
341
                                        -- automatisches lesen vom RAM  (ein wert)
342
                                        -- warten bis zum lesen bereit
343
                                        if v_read_busy = '0' and v_read_en='0' and auto_ref_req = '0' then
344
                                                -- daten zum lesen freigeben
345
                                                v_read_en <= '1';
346
                                        elsif v_read_busy = '1' and v_read_en='1' then
347
                                                -- daten werden gelesen
348
                                                v_read_en <= '0';
349
                                                STATE_M <= M7_AUTO_READING;
350
                                        end if;
351
                                when M7_AUTO_READING =>
352
                                        -- warte bis lesen fertig
353
                                        if v_read_busy = '0' then
354
                                                STATE_M <= M8_NOP;
355
                                        end if;
356
                           -----------------------------------------------------
357
                                -- Dauerloop : warten auf User-Eingabe :
358
                                -- hier wird gewartet, bis einer der 4 Buttons
359
                                -- gedrückt wurde
360
                                -----------------------------------------------------                                           
361
                                when M8_NOP =>
362
                                        -- warte auf Taste fuer READ oder WRITE
363
                                        v_write_en <= '0';
364
                                        v_read_en <= '0';
365
                                        if risingedge_in(3) = '1' and v_write_busy = '0' and auto_ref_req = '0' then
366
                                                -- button = west
367
                                                -- write starten (nur wenn nicht busy und kein refresh-zyklus)
368
                                                STATE_M <= M9_WRITE_INIT;
369
                                        elsif risingedge_in(0) = '1' and v_read_busy = '0' and auto_ref_req = '0' then
370
                                           -- button = east
371
                                                -- read starten (nur wenn nicht busy und kein refresh-zyklus)
372
                                                STATE_M <= M11_READ_INIT;
373
                                        end if;
374
                                        -- warte auf Taste fuer Adr-Up oder Adr-Down                                                            
375
                                        if risingedge_in(1)='1' and v_ROW < 255 then
376
                                                -- button = north
377
                                                v_ROW <= v_ROW + 1;
378
                                        elsif risingedge_in(2)='1' and v_ROW > 0 then
379
                                                -- button = south
380
                                                v_ROW <= v_ROW - 1;
381
                                        end if;
382
                           -----------------------------------------------------
383
                                -- WRITE : schreiben eines Wertes ins RAM :
384
                                -- ein fester Datenwert wird in die aktuelle Adresse
385
                                -- ins RAM geschrieben
386
                                -----------------------------------------------------                                           
387
                                when M9_WRITE_INIT =>
388
                                        -- warten bis zum schreiben bereit
389
                                        if v_write_busy = '0' and v_write_en='0' then
390
                                                -- daten zum schreiben freigeben
391
                                                v_write_en <= '1';
392
                                        elsif v_write_busy = '1' and v_write_en='1' then
393
                                                -- daten werden geschrieben
394
                                                v_write_en <= '0';
395
                                                STATE_M <= M10_WRITING;
396
                                        end if;
397
                                when M10_WRITING =>
398
                                        -- warte bis schreiben fertig
399
                                        if v_write_busy = '0' then
400
                                                STATE_M <= M8_NOP;
401
                                        end if;
402
                           -----------------------------------------------------
403
                                -- READ : lesen eines Wertes vom RAM :
404
                                -- die aktuelle Adresse vom RAM wird ausgelesen
405
                                -----------------------------------------------------                                           
406
                                when M11_READ_INIT =>
407
                                        -- warten bis zum lesen bereit
408
                                        if v_read_busy = '0' and v_read_en='0' then
409
                                                -- daten zum lesen freigeben
410
                                                v_read_en <= '1';
411
                                        elsif v_read_busy = '1' and v_read_en='1' then
412
                                                -- daten werden gelesen
413
                                                v_read_en <= '0';
414
                                                STATE_M <= M12_READING;
415
                                        end if;
416
                                when M12_READING =>
417
                                        -- warte bis lesen fertig
418
                                        if v_read_busy = '0' then
419
                                                STATE_M <= M8_NOP;
420
                                        end if;
421
                                when others =>
422
                                        NULL;
423
                        end case;
424
                end if;
425
        end process P_State_Main;
426
 
427
        -----------------------------------------
428
        -- Weiterleitung von Signalen
429
        -- in Abhängigkeit von Read oder Write :
430
        -----------------------------------------       
431
        P_SIGNAL : process(clk_in)
432
        begin
433
                if falling_edge(clk_in) then
434
                        if STATE_M=M4_AUTO_WRITE_INIT or STATE_M=M5_AUTO_WRITING then
435
                           -----------------------------------------------------
436
                                -- automatisches schreiben von ein paar Werten
437
                                -----------------------------------------------------   
438
                                v_write_data <= RAM_DATA(v_array_pos);
439
                                input_adress <= v_ROW & v_COL & v_BANK;
440
                                command_register <= v_write_command_register;
441
                                burst_done <= v_write_burst_done;
442
                        elsif STATE_M=M6_AUTO_READ_INIT or STATE_M=M7_AUTO_READING then
443
                           -----------------------------------------------------
444
                                -- automatisches lesen von einem Wert
445
                                -----------------------------------------------------
446
                                v_write_data <= (others => '0');
447
                                input_adress <= v_ROW & v_COL & v_BANK;
448
                                command_register <= v_read_command_register;
449
                                burst_done <= v_read_burst_done;
450
                        elsif STATE_M=M9_WRITE_INIT or STATE_M=M10_WRITING then
451
                           -----------------------------------------------------
452
                                -- WRITE : schreiben eines Wertes ins RAM
453
                                -----------------------------------------------------   
454
                                v_write_data <= CONST_DATA;
455
                                input_adress <= v_ROW & v_COL & v_BANK;
456
                                command_register <= v_write_command_register;
457
                                burst_done <= v_write_burst_done;
458
                        elsif STATE_M=M11_READ_INIT or STATE_M=M12_READING then
459
                           -----------------------------------------------------
460
                                -- READ : lesen eines Wertes vom RAM
461
                                -----------------------------------------------------
462
                                v_write_data <= (others => '0');
463
                                input_adress <= v_ROW & v_COL & v_BANK;
464
                                command_register <= v_read_command_register;
465
                                burst_done <= v_read_burst_done;
466
                        else
467
                           -----------------------------------------------------
468
                                -- Dauerloop oder INIT
469
                                -----------------------------------------------------   
470
                                v_write_data <= (others => '0');
471
                                input_adress <= (others => '0');
472
                                command_register <= v_main_command_register;
473
                                burst_done <= '0';
474
                        end if;
475
                end if;
476
        end process P_SIGNAL;
477
 
478
        -----------------------------------------
479
        -- Ausgabe der gelesenen Daten
480
        -- je nach Schalterstellung
481
        -----------------------------------------       
482
        P_DataOut : process(clk_in,reset_in)
483
        begin
484
                if reset_in = '1' then
485
                        -- reset button ist gedrueckt
486
                        data_out <= (others => '0');
487
                elsif falling_edge(clk_in) then
488
                        if debounce_in(7 downto 5)="000" then data_out <= v_read_data(7 downto 0);
489
                        elsif debounce_in(7 downto 5)="001" then data_out <= v_read_data(15 downto 8);
490
                        elsif debounce_in(7 downto 5)="010" then data_out <= v_read_data(23 downto 16);
491
                        elsif debounce_in(7 downto 5)="011" then data_out <= v_read_data(31 downto 24);
492
                        elsif debounce_in(7 downto 5)="100" then data_out <= v_read_data(39 downto 32);
493
                        elsif debounce_in(7 downto 5)="101" then data_out <= v_read_data(47 downto 40);
494
                        elsif debounce_in(7 downto 5)="110" then data_out <= v_read_data(55 downto 48);
495
                        elsif debounce_in(7 downto 5)="111" then data_out <= v_read_data(63 downto 56);
496
                        end if;
497
                        -------------------------------------------                     
498
                end if;
499
        end process P_DataOut;
500
 
501
end Verhalten;
502
 

powered by: WebSVN 2.1.0

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