Forum: FPGA, VHDL & Co. DDR-RAM TopLevel Modul. Wie anbinden an Controller?


von Christian A. (noeppkes)


Lesenswert?

Hallo zusammen.

Nachdem ich es jetzt endlich nach Tagen geschafft habe (nicht zuletzt 
auch mit Hilfe über dieses Forum) den DDR2-Controller für das Spartan 
3AN Board von Xilinx erfolgreich zu compilieren habe ich nun das Problem 
dass ich nicht weiss wie ich das TopLevel an meinen Controller 
anschliesse.

Hier das Toplevel (welches ich hier gefunden und leicht abgeändert habe)
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    13:52:07 03/24/2010 
6
-- Design Name: 
7
-- Module Name:    TopModule - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.STD_LOGIC_ARITH.ALL;
23
use IEEE.STD_LOGIC_UNSIGNED.ALL;
24
25
---- Uncomment the following library declaration if instantiating
26
---- any Xilinx primitives in this code.
27
--library UNISIM;
28
--use UNISIM.VComponents.all;
29
30
entity TopModule is
31
    Port ( sys_clk50              : in  STD_LOGIC;
32
           sys_clk133             : in  STD_LOGIC;
33
           reset_in               : in  STD_LOGIC;
34
           rst_dqs_div_in         : IN std_logic;
35
           burst_done             : in std_logic;
36
           led_ar_done            : out std_Logic;
37
           ddr2_a                 : out std_logic_vector(12 downto 0);
38
           ddr2_ba                : out std_logic_vector(1 downto 0);
39
           ddr2_cke               : out std_logic;
40
           ddr2_cs_n              : out std_logic;
41
           ddr2_ras_n             : out std_logic;
42
           ddr2_cas_n             : out std_logic;
43
           ddr2_we_n              : out std_logic;
44
           ddr2_odt               : out std_logic;
45
           --ddr2_dm              : out std_logic_vector(1 downto 0); # Christian entfernt
46
           --ddr2_dqs             : inout std_logic_vector(1 downto 0);
47
           --ddr2_dqs_n           : inout std_logic_vector(1 downto 0);
48
           -- user_data_mask      : in    std_logic_vector(3 downto 0); # Christian entfernt
49
           user_input_address     : in    std_logic_vector(24 downto 0);
50
           ddr2_ck                : out   std_logic_vector(0 downto 0);
51
           ddr2_ck_n              : out   std_logic_vector(0 downto 0);
52
           ddr2_dq                : inout std_logic_vector(15 downto 0);
53
           user_output_data       : out   std_logic_vector(31 downto 0);
54
           user_input_data        : in    std_logic_vector(31 downto 0);        
55
           led_init_done          : out  STD_LOGIC);
56
end TopModule;
57
58
architecture Behavioral of TopModule is
59
60
component mig_v3_61
61
 port(
62
      cntrl0_ddr2_dq                : inout std_logic_vector(15 downto 0);
63
      cntrl0_ddr2_a                 : out   std_logic_vector(12 downto 0);
64
      cntrl0_ddr2_ba                : out   std_logic_vector(1 downto 0);
65
      cntrl0_ddr2_cke               : out   std_logic;
66
      cntrl0_ddr2_cs_n              : out   std_logic;
67
      cntrl0_ddr2_ras_n             : out   std_logic;
68
      cntrl0_ddr2_cas_n             : out   std_logic;
69
      cntrl0_ddr2_we_n              : out   std_logic;
70
      cntrl0_ddr2_odt               : out   std_logic;
71
      --cntrl0_ddr2_dm                : out   std_logic_vector(1 downto 0); # Christian entfernt
72
      cntrl0_rst_dqs_div_in         : in    std_logic;
73
      cntrl0_rst_dqs_div_out        : out   std_logic;
74
      sys_clk_in                    : in    std_logic;
75
      reset_in_n                    : in    std_logic;
76
      cntrl0_burst_done             : in    std_logic;
77
      cntrl0_init_done              : out   std_logic;
78
      cntrl0_ar_done                : out   std_logic;
79
      cntrl0_user_data_valid        : out   std_logic;
80
      cntrl0_auto_ref_req           : out   std_logic;
81
      cntrl0_user_cmd_ack           : out   std_logic;
82
      cntrl0_user_command_register  : in    std_logic_vector(2 downto 0);
83
      cntrl0_clk_tb                 : out   std_logic;
84
      cntrl0_clk90_tb               : out   std_logic;
85
      cntrl0_sys_rst_tb             : out   std_logic;
86
      cntrl0_sys_rst90_tb           : out   std_logic;
87
      cntrl0_sys_rst180_tb          : out   std_logic;
88
      cntrl0_user_output_data       : out   std_logic_vector(31 downto 0);
89
      cntrl0_user_input_data        : in    std_logic_vector(31 downto 0);
90
      --cntrl0_user_data_mask         : in    std_logic_vector(3 downto 0); # Christian entfernt
91
      cntrl0_user_input_address     : in    std_logic_vector(24 downto 0);
92
      --cntrl0_ddr2_dqs               : inout std_logic_vector(1 downto 0);
93
      --cntrl0_ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
94
      cntrl0_ddr2_ck                : out   std_logic_vector(0 downto 0);
95
      cntrl0_ddr2_ck_n              : out   std_logic_vector(0 downto 0)
96
97
);
98
end component;
99
100
101
-- **************************************************************************
102
103
104
-- Eigener Code by FT
105
106
107
108
-- type und signaldefs fuer die FSM
109
type init_s_m is (IDLE, DELAY, DO_INIT, AFTER_INIT);
110
signal current_state, next_state : init_s_m;
111
112
-- zaehlvariable fuer 260 us bei einem Takt von 50 MHz (T=20.0 ns)
113
-- -> 13000|10 = ....|2
114
signal delay250us : std_logic_vector(13 downto 0) := "11001011001000"; --13000
115
--signal delay250us : std_logic_vector(12 downto 0) := "1100101100100"; --6500
116
--signal init_cmd : std_logic_vector(2 downto 0) := "010";  
117
118
-- **************************************************************************  
119
120
121
signal sig_user_cmd : std_logic_vector(2 downto 0) := "000"; -- 000: NOP
122
signal sig_reset_in_n : std_logic;
123
124
125
begin
126
127
128
u_mig_v3_61 :mig_v3_61
129
       port map (
130
      cntrl0_rst_dqs_div_in         => rst_dqs_div_in,
131
    --  cntrl0_rst_dqs_div_out        => cntrl0_rst_dqs_div_out,
132
    cntrl0_burst_done             => burst_done,
133
      sys_clk_in                    => sys_clk133,
134
      reset_in_n                    => sig_reset_in_n,
135
      cntrl0_init_done              => led_init_done,
136
      cntrl0_ar_done                => led_ar_done,
137
      cntrl0_user_command_register  => sig_user_cmd,
138
      --cntrl0_user_data_mask         => user_data_mask, # Christian entfernt
139
      cntrl0_user_input_address     => user_input_address,
140
    cntrl0_ddr2_dq => ddr2_dq,
141
    cntrl0_user_output_data => user_output_data,
142
      cntrl0_user_input_data => user_input_data,
143
    cntrl0_ddr2_ck => ddr2_ck,
144
    cntrl0_ddr2_ck_n => ddr2_ck_n,
145
    cntrl0_ddr2_a => ddr2_a,
146
    cntrl0_ddr2_ba => ddr2_ba,
147
    cntrl0_ddr2_cke => ddr2_cke,
148
    cntrl0_ddr2_cs_n => ddr2_cs_n,
149
    cntrl0_ddr2_ras_n => ddr2_ras_n,
150
    cntrl0_ddr2_cas_n => ddr2_cas_n,
151
    cntrl0_ddr2_we_n => ddr2_we_n,
152
    --cntrl0_ddr2_dqs => ddr2_dqs,
153
    --cntrl0_ddr2_dqs_n => ddr2_dqs_n,
154
    cntrl0_ddr2_odt => ddr2_odt
155
    --cntrl0_ddr2_dm => ddr2_dm # Christian entfernt
156
);
157
158
-- *********************************************************
159
-- Begin eigener CODE
160
161
-- Einbau einer FSM zum automatischen Initialisieren
162
163
-- Statemachine mit vier Zustaenden:
164
-- ---------------------------------
165
-- IDLE.     Ist der Endzustand nach der Initialisierung; von hier aus: Weitere Steuerung
166
-- DELAY.     Startzustand; der zuvor geladene Counter wird hier heruntergezaehlt
167
-- DO_INIT.    Wird nach Erreichen des Nullstandes des Counters durchgefuehrt; hier wird das
168
--          Signal 010 (= INIT) abgesetzt
169
-- AFTER_INIT.  Das zuvor abgesetzt  Signal 010 wird hier wieder aufgehoben und auf 000 gesetzt,
170
--          was einem NOP-Kommando entspricht
171
172
173
-- Zeitverzug: Wichtig, da das Kommando erst nach einer Blockzeit von 200 us (33414 Takte)
174
-- angenommen wird; vorherige Kommando werden ignoriert
175
-- bei einer Frequenz von 133 MHz entspricht dies 251.3 us, die es zu warten gilt; 
176
-- der Timer (Wert des Signals delay250us) wurde entsprechend auf 260us angepasst
177
178
-- INIT-Command: Das Init-Command darf nur einen Takt anliegen, sonst werden die entsprechenden
179
-- Signale nicht auf die zuvor benoetigten Pegel gezogen; dies wird aus der Simulation vor allem
180
-- bei den Signalen "init_memory" und "init_mem" deutlich.
181
-- Das Signal rst180 bzw _r wird nach einem "cke"-Signal auf 0 gesetzt, steuernd dafuer ist das
182
-- Signal wait_200us im Modul controller (top00 -> controller)
183
-- Vorher wird der Chip fuer alle anliegenden Signale gesperrt
184
185
-- *********************************************************
186
187
process
188
begin
189
  wait until rising_edge(sys_clk50);
190
  sig_reset_in_n <= not reset_in;
191
end process;
192
193
-- Start der State_Machine
194
195
process
196
begin
197
  wait until falling_edge(sys_clk50);
198
  case current_state is
199
    when DELAY         => if delay250us = "00000000000000" then
200
                      next_state <= DO_INIT;
201
                    else
202
                      delay250us <= delay250us-'1';                
203
                      next_state <= DELAY;
204
                    end if;
205
    when IDLE        => next_state <= IDLE;
206
    when DO_INIT       => sig_user_cmd <= "010"; -- hier wird 010 ins UCR geschrieben
207
                    next_state <= AFTER_INIT;
208
    when AFTER_INIT    => sig_user_cmd <= "000";
209
                    next_state <= IDLE;
210
  end case;
211
end process;
212
213
-- Einen Status weiterspringen und init setzen
214
process
215
begin
216
  wait until falling_edge(sys_clk50);
217
  if reset_in = '1' then
218
    current_state <= DELAY;
219
  else
220
    current_state <= next_state;
221
  end if;
222
end process;
223
224
225
end Behavioral;
Mein Controller hat zwar einen DDR-Controler aber auch, was mir 
persönlich lieber wäre, einen SRAM Controller.
SRAM ist einfacher für mich und auch einfacher zu messen wenn man mal 
muss.

Was so ziemlich klar ist, sind die ersten 3 Signale. Die 2 CLK sind 
richtig auf die Pin's gelegt.
Das Reset_in werde ich wohl mit dem Reset des Controllers verbinden 
müssen.
Das UCF-File für das Board ist eingebunden.

Aber dann wird für mich undurchsichtig.

Vielleicht kann mir jemand mal kurz einen Ansatz in vhdl basteln.

SRAM-Siglane wie man sie so kennt:
CS, RD, WR, A0 .. Ax, D0...D15

Vielen Dank.
noeppkes ...

von Duke Scarring (Gast)


Lesenswert?

Christian Armbruster schrieb:

> ddr2_ck                : out   std_logic_vector(0 downto 0);
> ddr2_ck_n              : out   std_logic_vector(0 downto 0);
> ddr2_dq                : inout std_logic_vector(15 downto 0);
Die DDR2_XX gehen über die Pins an Deinen Speicherchip.


> user_input_address     : in    std_logic_vector(24 downto 0);
> user_output_data       : out   std_logic_vector(31 downto 0);
> user_input_data        : in    std_logic_vector(31 downto 0);
Die kommen an Deinen Core. Allerdings vermisse ich da noch sowas wie
ein Write Enable und ein Read Request...

Hast Du eine Testbench dazu?
Versuch erstmal die zum Laufen zu bekommen, auch wenn es u.U. nicht ganz 
trivial ist.

Duke

von Rudolph (Gast)


Lesenswert?

Mir sind ein paar Dinge unklar:

> dass ich nicht weiss wie ich das TopLevel an meinen Controller
> anschliesse.

Was für einen Controller?

>           --ddr2_dm              : out std_logic_vector(1 downto 0); #
> Christian entfernt
>           --ddr2_dqs             : inout std_logic_vector(1 downto 0);
>           --ddr2_dqs_n           : inout std_logic_vector(1 downto 0);
>           -- user_data_mask      : in    std_logic_vector(3 downto 0); #
> Christian entfernt

Wieso sind diese Signale auskommentiert?

> Mein Controller hat zwar einen DDR-Controler aber auch, was mir
> persönlich lieber wäre, einen SRAM Controller.

Was sind das jetzt alles für Controller?

Und das, was Du möchtest, ist eine Komponente, die das DDR2-MIG-Design 
kapselt und Dir ein SRAM-like Interface bereitstellt?

von Christian A. (noeppkes)


Lesenswert?

Hallo Duke.
Danke für deine Antwort,

Duke Scarring schrieb:
> Christian Armbruster schrieb:
>
>> ddr2_ck                : out   std_logic_vector(0 downto 0);
>> ddr2_ck_n              : out   std_logic_vector(0 downto 0);
>> ddr2_dq                : inout std_logic_vector(15 downto 0);
> Die DDR2_XX gehen über die Pins an Deinen Speicherchip.
O.K. Das dachte ich mir.

>
>
>> user_input_address     : in    std_logic_vector(24 downto 0);
>> user_output_data       : out   std_logic_vector(31 downto 0);
>> user_input_data        : in    std_logic_vector(31 downto 0);
> Die kommen an Deinen Core. Allerdings vermisse ich da noch sowas wie
> ein Write Enable und ein Read Request...
>
Ja. Genau das denke ich auch. Jedoch stellt die MIG nichts weiteres zur 
Verfügung. Siehe oben. Ich selbst habe ja nur den TopLevel darum 
gebastelt.

> Hast Du eine Testbench dazu?
Nein, habe ich noch nicht. Ich habe lediglich mit MIG 3.61 den coregen 
erstellen lassen und ein TopLevel darum gebastelt.

> Versuch erstmal die zum Laufen zu bekommen, auch wenn es u.U. nicht ganz
> trivial ist.
O.K. Das wätre ein Ansatz. Aber wenn es läuft, stehe ich immer noch vor 
dem gleichen Problem. Ich benötige doch mind. ein WR oder RD und auch 
ein CS. user_input_address, user_output_data und user_input_data 
verstehe ich ja noch. Die kann ich mir an meinen Controller basteln.

>
> Duke

noeppkes ...

von Christian A. (noeppkes)


Lesenswert?

Rudolph schrieb:

Hallo Rudolf. Auch dir Danke für deine Antwort.

> Mir sind ein paar Dinge unklar:
>
>> dass ich nicht weiss wie ich das TopLevel an meinen Controller
>> anschliesse.
>
> Was für einen Controller?
Das ist ein Renesas SH2A (7216) MCU mit 16-Bit Datenbus. Dieser 
Controller hat einerseits ein SDRAM-Interface und ein 
SRAM-Interface.Lässt sich konfigurieren. Wie schon gesagt: 
SRAM-Interface wäre mir am liebsten.

>
>>           --ddr2_dm              : out std_logic_vector(1 downto 0); #
>> Christian entfernt
>>           --ddr2_dqs             : inout std_logic_vector(1 downto 0);
>>           --ddr2_dqs_n           : inout std_logic_vector(1 downto 0);
>>           -- user_data_mask      : in    std_logic_vector(3 downto 0); #
>> Christian entfernt
>
> Wieso sind diese Signale auskommentiert?
Die MIG 3.61 von Xilinx hat diese Signale nicht erstellt. Daher habe ich 
sie auskommentiert. Siehe oben.
>
>> Mein Controller hat zwar einen DDR-Controler aber auch, was mir
>> persönlich lieber wäre, einen SRAM Controller.
>
> Was sind das jetzt alles für Controller?
>
Wie oben geschrieben ein SH2A 7216 von Renesas. Dieser soll den FPGA am 
besten über SRAM angeschaltet bekommen. Der FPGA handelt dann einen DDR 
RAM. Über den FPGA kann ich dann mit dem Controller Daten lesen und 
schreiben. Das ist mein Ziel. Du fragst dich jetzt sicherlich warum über 
den FPGA. Ganz einfach. Das DDR-Ram am FPGA stellt gleichzeitig den 
TFT-Display-Speicher dar für mein TFT-Modul. Der FPGA holt sich die 
Daten aus dem angeschalteten DDR-Speicher. Der Controller schreibt über 
den FPGA die Bildschirmdaten in das DDR-Ram. Das ganze funktioniert 
schon mit einem SRAM. Jedoch hat mein SRAM nur 1MB. 768KB werden aber 
schon vom Display gebraucht (800  480 Pixel  16Bit.) Ich möchte aber 
mehrere Bildschirmseiten im RAM unterbringen, daher mehr Speicher. Das 
geht nur noch mit SDRAM, DDR, DDR2 o.ä. Da hat man dann gleich ein paar 
MB. Mit SRAM wird das dann irgend wann mal "unbezahlbar".

> Und das, was Du möchtest, ist eine Komponente, die das DDR2-MIG-Design
> kapselt und Dir ein SRAM-like Interface bereitstellt?

Tja. So der Ansatz von mir.
noeppkes ...

von Duke Scarring (Gast)


Lesenswert?

@Christian Armbruster:

Das heißt Du hast vier Teilprojekte:

SH2A <-> FPGA
FPGA <-> SRAM
FPGA <-> SDRAM
FPGA <-> TFT

Dein FPGA ist in diesem Fall Speicher- und Displaycontroller für den 
SH2A, richtig?!

Und jetzt scheitert es am Punkt FPGA <-> SDRAM und der Rest funktioniert 
schon?

Schreibt der MIG ein .xco-File mit raus? Könntest Du dessen Inhalt hier 
mal posten?

Duke

von Christian A. (noeppkes)


Lesenswert?

Hallo Duke.
Danke für deine Antwort.

Duke Scarring schrieb:
> @Christian Armbruster:
>
> Das heißt Du hast vier Teilprojekte:
>
> SH2A <-> FPGA
> FPGA <-> SRAM
> FPGA <-> SDRAM
> FPGA <-> TFT
>
Nein. Der SH2A soll über SRAM-Interface an den FPGA angebunden werden. 
Das DDR-RAM hängt am FPGA.
Somit bin ich in der Lage vom SH2A über den FPGA ins DDR-RAM zu 
schreiben und auch vom DDR-RAM zu lesen.
Das TFT hängt dann auch am FPGA und wird vom DDR-RAM gefüttert.
D.h. eine State-Machine arbeitet die Anfragen ab. Einerseits den 
Controller (SH2A) überwachen ob dieser neue Daten ins DDR-RAM schreiben 
oder Daten aus dem DDR-Ram lesen möchte und andererseits kontinuierlich 
die Daten aus dem DDR-RAM dem TFT zur Verfügung zu stellen.
Aber wie schon erwähnt. Das alles funktioniert ja schon mit dem Spartan 
3 Starterkit. Das hat aber am FPGA nur 1MB SRAM. Das reicht mir nicht. 
Deswegen der Umstieg auf das Spartan 3AN Starterkit mit 32MB DDR-RAM.
Brauche nur noch die Anbindung meines Controllers an den FPGA, damit ich 
mit dem Controller Daten ins DDR-Ram schrieben bzw. Daten aus dem 
DDR-Ram lesen kann.
Sozusagen ein DDR-Ram Controller für einen FPGA.

SH2A<-->FPGA (über SRAM-Interface)
FPGA<-->DDR-Ram     (Hat MIG V3.61 erstellt)
FPGA<-->TFT-Display (Funktioniert schon)

> Dein FPGA ist in diesem Fall Speicher- und Displaycontroller für den
> SH2A, richtig?!
>
Ja.

> Und jetzt scheitert es am Punkt FPGA <-> SDRAM und der Rest funktioniert
> schon?
>
Nein. Nicht ganz. Das DDR-RAM wird ja schon vom MIG erzeugt. Die nötigen 
Signale sind da. Das UCF-File für das Board habe ich auch. Somit sollte 
die Verbindung FPGA<-->DDR-RAM von der Theorie her mal abgeschlossen 
sein.
Mein Problem ist jetzt nur noch die Anbindung SH2A<-->FPGA über (wenn 
möglich) ein SRAM Interface.

Die TFT-Darstellung habe ich schon in einem anderen Projekt erfolgreich 
umgesetzt.

Zusammengefasst: Ich brauche für mein Startkit (ich habe mir jetzt extra 
dafür den Spartan 3AN gekauft, heute gekommen) einen 
DDR2-RAM-Controller, welcher mir die Verbindung zw. meinem Controller 
(SRAM-Interface) und dem DDR2-RAM herstellt, so dass ich Daten aus dem 
DDR2-RAM schreiben bzw. lesen kann.
Den Rest bekomme ich selbst gelöst.

P.S. Ich habe mir das Spartan 3AN Starterkit geholt, weil in den Foren 
immer wieder von Problemen mit dem Spartan 3E Starterkit berichtet 
wurde. Ausserdem hatte ich noch die alte Rev.C.

> Schreibt der MIG ein .xco-File mit raus? Könntest Du dessen Inhalt hier
> mal posten?
Ja: Hier ist es:
1
##############################################################
2
#
3
# Xilinx Core Generator version 12.4
4
# Date: Fri Jan 28 10:56:57 2011
5
#
6
##############################################################
7
#
8
#  This file contains the customisation parameters for a
9
#  Xilinx CORE Generator IP GUI. It is strongly recommended
10
#  that you do not manually alter this file as it may cause
11
#  unexpected and unsupported behavior.
12
#
13
##############################################################
14
#
15
# BEGIN Project Options
16
SET addpads = false
17
SET asysymbol = true
18
SET busformat = BusFormatAngleBracketNotRipped
19
SET createndf = false
20
SET designentry = VHDL
21
SET device = xc3s700an
22
SET devicefamily = spartan3a
23
SET flowvendor = Foundation_ISE
24
SET formalverification = false
25
SET foundationsym = false
26
SET implementationfiletype = Ngc
27
SET package = fgg484
28
SET removerpms = false
29
SET simulationfiles = Behavioral
30
SET speedgrade = -4
31
SET verilogsim = false
32
SET vhdlsim = true
33
# END Project Options
34
# BEGIN Select
35
SELECT MIG family Xilinx,_Inc. 3.61
36
# END Select
37
# BEGIN Parameters
38
CSET component_name=mig_v3_61
39
CSET xml_input_file=./mig_v3_61/user_design/mig.prj
40
# END Parameters
41
GENERATE
42
# CRC:  5f6f976

>
> Duke

Bis dann ...
noeppkes

von Christian A. (noeppkes)


Lesenswert?

Hallo zusammen.

Ich habe bisher vergeblich nach einem CS, RD bzw. einem WR-Signal 
gesucht.
Ich denke nun heruasgefunden zu haben, warum es ein solches Signal nicht 
gibt.
Das ganze wird meiner Meinung nach über das command gesteuert.
Dabei ist: "000" = NOP, "010" = Initialize Memory, "100" Write request, 
"110" Read Request.
Somit muss ich "nur" das command richtig erzeugen, sofern ich lesen oder 
schreiben möchte.
Wie lange muss ich das command anlegen damit es übernommen wird. Reicht 
hier 1 Takt aus ?

Ist mein Ansatz richtig ?

noeppkes ...

von Rudolph (Gast)


Lesenswert?

Christian Armbruster schrieb:

>>>           --ddr2_dm              : out std_logic_vector(1 downto 0); #
>>> Christian entfernt
>>>           --ddr2_dqs             : inout std_logic_vector(1 downto 0);
>>>           --ddr2_dqs_n           : inout std_logic_vector(1 downto 0);
>>>           -- user_data_mask      : in    std_logic_vector(3 downto 0); #
>>> Christian entfernt
>>
>> Wieso sind diese Signale auskommentiert?
> Die MIG 3.61 von Xilinx hat diese Signale nicht erstellt. Daher habe ich
> sie auskommentiert. Siehe oben.

Das mag ich nicht so recht glauben. Entweder ist da was übel schief 
gelaufen, oder Du hast was übersehen. Ohne diese Signale wird das 
DDR2-Ram nicht laufen.

Christian Armbruster schrieb:
> Das ganze wird meiner Meinung nach über das command gesteuert.
>
> Ist mein Ansatz richtig ?

Grundsätzlich ja. Wie das ganze funktioniert, steht im UG086, S. 331ff.

von Christian A. (noeppkes)


Lesenswert?

Hallo zusammen.
(Hallo Rudolph)
Ich bin nun einen Schritt weiter.
Ich habe die auskommentierten Signale eingebunden.
Meine Frage: Was mache ich mit den Signalen:

      cntrl0_rst_dqs_div_in         : in    std_logic;
      cntrl0_rst_dqs_div_out        : out   std_logic;

cntrl0_rst_dqs_div_in ist ja schon "verdrahtet" mit meinem 
TopLevel-Signal rst_dqs_div_in. Jedoch habe ich im UCF-File keine 
Angaben über ein Pin?
Und wohin kommt das Signal cntrl0_rst_dqs_div_out ?

Mein TopLevel sieht nun folgendermaßen aus:
(Im Anschluss mein UCF-File)
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    13:52:07 03/24/2010 
6
-- Design Name: 
7
-- Module Name:    TopModule - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.STD_LOGIC_ARITH.ALL;
23
use IEEE.STD_LOGIC_UNSIGNED.ALL;
24
25
---- Uncomment the following library declaration if instantiating
26
---- any Xilinx primitives in this code.
27
--library UNISIM;
28
--use UNISIM.VComponents.all;
29
30
entity TopModule is
31
    Port ( sys_clk50              : in  STD_LOGIC;
32
           sys_clk133             : in  STD_LOGIC;
33
           reset_in               : in  STD_LOGIC;
34
           rst_dqs_div_in         : IN std_logic;
35
           burst_done             : in std_logic;
36
           led_ar_done            : out std_Logic;
37
           ddr2_a                 : out std_logic_vector(12 downto 0);
38
           ddr2_ba                : out std_logic_vector(1 downto 0);
39
           ddr2_cke               : out std_logic;
40
           ddr2_cs_n              : out std_logic;
41
           ddr2_ras_n             : out std_logic;
42
           ddr2_cas_n             : out std_logic;
43
           ddr2_we_n              : out std_logic;
44
           ddr2_odt               : out std_logic;
45
           ddr2_dm                : out std_logic_vector(1 downto 0);
46
           ddr2_dqs               : inout std_logic_vector(1 downto 0);
47
           ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
48
           user_data_mask         : in    std_logic_vector(3 downto 0);
49
           user_input_address     : in    std_logic_vector(24 downto 0);
50
           ddr2_ck                : out   std_logic_vector(0 downto 0);
51
           ddr2_ck_n              : out   std_logic_vector(0 downto 0);
52
           ddr2_dq                : inout std_logic_vector(15 downto 0);
53
           user_output_data       : out   std_logic_vector(31 downto 0);
54
           user_input_data        : in    std_logic_vector(31 downto 0);        
55
           led_init_done          : out  STD_LOGIC);
56
end TopModule;
57
58
architecture Behavioral of TopModule is
59
60
component mig_v3_61
61
 port(
62
      cntrl0_ddr2_dq                : inout std_logic_vector(15 downto 0);
63
      cntrl0_ddr2_a                 : out   std_logic_vector(12 downto 0);
64
      cntrl0_ddr2_ba                : out   std_logic_vector(1 downto 0);
65
      cntrl0_ddr2_cke               : out   std_logic;
66
      cntrl0_ddr2_cs_n              : out   std_logic;
67
      cntrl0_ddr2_ras_n             : out   std_logic;
68
      cntrl0_ddr2_cas_n             : out   std_logic;
69
      cntrl0_ddr2_we_n              : out   std_logic;
70
      cntrl0_ddr2_odt               : out   std_logic;
71
      cntrl0_ddr2_dm                : out   std_logic_vector(1 downto 0);
72
      cntrl0_rst_dqs_div_in         : in    std_logic;
73
      cntrl0_rst_dqs_div_out        : out   std_logic;
74
      sys_clk_in                    : in    std_logic;
75
      reset_in_n                    : in    std_logic;
76
      cntrl0_burst_done             : in    std_logic;
77
      cntrl0_init_done              : out   std_logic;
78
      cntrl0_ar_done                : out   std_logic;
79
      cntrl0_user_data_valid        : out   std_logic;
80
      cntrl0_auto_ref_req           : out   std_logic;
81
      cntrl0_user_cmd_ack           : out   std_logic;
82
      cntrl0_user_command_register  : in    std_logic_vector(2 downto 0);
83
      cntrl0_clk_tb                 : out   std_logic;
84
      cntrl0_clk90_tb               : out   std_logic;
85
      cntrl0_sys_rst_tb             : out   std_logic;
86
      cntrl0_sys_rst90_tb           : out   std_logic;
87
      cntrl0_sys_rst180_tb          : out   std_logic;
88
      cntrl0_user_output_data       : out   std_logic_vector(31 downto 0);
89
      cntrl0_user_input_data        : in    std_logic_vector(31 downto 0);
90
      cntrl0_user_data_mask         : in    std_logic_vector(3 downto 0);
91
      cntrl0_user_input_address     : in    std_logic_vector(24 downto 0);
92
      cntrl0_ddr2_dqs               : inout std_logic_vector(1 downto 0);
93
      cntrl0_ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
94
      cntrl0_ddr2_ck                : out   std_logic_vector(0 downto 0);
95
      cntrl0_ddr2_ck_n              : out   std_logic_vector(0 downto 0)
96
97
);
98
end component;
99
100
101
-- **************************************************************************
102
103
104
-- Eigener Code by FT
105
106
107
108
-- type und signaldefs fuer die FSM
109
type init_s_m is (IDLE, DELAY, DO_INIT, AFTER_INIT);
110
signal current_state, next_state : init_s_m;
111
112
-- zaehlvariable fuer 260 us bei einem Takt von 50 MHz (T=20.0 ns)
113
-- -> 13000|10 = ....|2
114
signal delay250us : std_logic_vector(13 downto 0) := "11001011001000"; --13000
115
--signal delay250us : std_logic_vector(12 downto 0) := "1100101100100"; --6500
116
--signal init_cmd : std_logic_vector(2 downto 0) := "010";  
117
118
-- **************************************************************************  
119
120
121
signal sig_user_cmd : std_logic_vector(2 downto 0) := "000"; -- 000: NOP
122
signal sig_reset_in_n : std_logic;
123
124
125
begin
126
127
128
u_mig_v3_61 :mig_v3_61
129
       port map (
130
      cntrl0_rst_dqs_div_in         => rst_dqs_div_in,
131
      cntrl0_rst_dqs_div_out        => cntrl0_rst_dqs_div_out,
132
      cntrl0_burst_done             => burst_done,
133
      sys_clk_in                    => sys_clk133,
134
      reset_in_n                    => sig_reset_in_n,
135
      cntrl0_init_done              => led_init_done,
136
      cntrl0_ar_done                => led_ar_done,
137
      cntrl0_user_command_register  => sig_user_cmd,
138
      cntrl0_user_data_mask         => user_data_mask,
139
      cntrl0_user_input_address     => user_input_address,
140
      cntrl0_ddr2_dq                => ddr2_dq,
141
      cntrl0_user_output_data       => user_output_data,
142
      cntrl0_user_input_data        => user_input_data,
143
      cntrl0_ddr2_ck                => ddr2_ck,
144
      cntrl0_ddr2_ck_n              => ddr2_ck_n,
145
      cntrl0_ddr2_a                 => ddr2_a,
146
      cntrl0_ddr2_ba                => ddr2_ba,
147
      cntrl0_ddr2_cke               => ddr2_cke,
148
      cntrl0_ddr2_cs_n              => ddr2_cs_n,
149
      cntrl0_ddr2_ras_n             => ddr2_ras_n,
150
      cntrl0_ddr2_cas_n             => ddr2_cas_n,
151
      cntrl0_ddr2_we_n              => ddr2_we_n,
152
      cntrl0_ddr2_dqs               => ddr2_dqs,
153
      cntrl0_ddr2_dqs_n             => ddr2_dqs_n,
154
      cntrl0_ddr2_odt               => ddr2_odt,
155
      cntrl0_ddr2_dm                => ddr2_dm
156
);
157
158
-- *********************************************************
159
-- Begin eigener CODE
160
161
-- Einbau einer FSM zum automatischen Initialisieren
162
163
-- Statemachine mit vier Zustaenden:
164
-- ---------------------------------
165
-- IDLE.     Ist der Endzustand nach der Initialisierung; von hier aus: Weitere Steuerung
166
-- DELAY.     Startzustand; der zuvor geladene Counter wird hier heruntergezaehlt
167
-- DO_INIT.    Wird nach Erreichen des Nullstandes des Counters durchgefuehrt; hier wird das
168
--          Signal 010 (= INIT) abgesetzt
169
-- AFTER_INIT.  Das zuvor abgesetzt  Signal 010 wird hier wieder aufgehoben und auf 000 gesetzt,
170
--          was einem NOP-Kommando entspricht
171
172
173
-- Zeitverzug: Wichtig, da das Kommando erst nach einer Blockzeit von 200 us (33414 Takte)
174
-- angenommen wird; vorherige Kommando werden ignoriert
175
-- bei einer Frequenz von 133 MHz entspricht dies 251.3 us, die es zu warten gilt; 
176
-- der Timer (Wert des Signals delay250us) wurde entsprechend auf 260us angepasst
177
178
-- INIT-Command: Das Init-Command darf nur einen Takt anliegen, sonst werden die entsprechenden
179
-- Signale nicht auf die zuvor benoetigten Pegel gezogen; dies wird aus der Simulation vor allem
180
-- bei den Signalen "init_memory" und "init_mem" deutlich.
181
-- Das Signal rst180 bzw _r wird nach einem "cke"-Signal auf 0 gesetzt, steuernd dafuer ist das
182
-- Signal wait_200us im Modul controller (top00 -> controller)
183
-- Vorher wird der Chip fuer alle anliegenden Signale gesperrt
184
185
-- *********************************************************
186
187
process
188
begin
189
  wait until rising_edge(sys_clk50);
190
  sig_reset_in_n <= not reset_in;
191
end process;
192
193
-- Start der State_Machine
194
195
process
196
begin
197
  wait until falling_edge(sys_clk50);
198
  case current_state is
199
    when DELAY         => if delay250us = "00000000000000" then
200
                      next_state <= DO_INIT;
201
                    else
202
                      delay250us <= delay250us-'1';                
203
                      next_state <= DELAY;
204
                    end if;
205
    when IDLE        => next_state <= IDLE;
206
    when DO_INIT       => sig_user_cmd <= "010"; -- hier wird 010 ins UCR geschrieben
207
                    next_state <= AFTER_INIT;
208
    when AFTER_INIT    => sig_user_cmd <= "000";
209
                    next_state <= IDLE;
210
  end case;
211
end process;
212
213
-- Einen Status weiterspringen und init setzen
214
process
215
begin
216
  wait until falling_edge(sys_clk50);
217
  if reset_in = '1' then
218
    current_state <= DELAY;
219
  else
220
    current_state <= next_state;
221
  end if;
222
end process;
223
224
225
end Behavioral;



Und hier nun noch das UCF-File:


1
NET "sys_clk50" TNM_NET = "sys_clk50";
2
TIMESPEC TS_sys_clk50 = PERIOD "sys_clk50" 50 MHz HIGH 50 % INPUT_JITTER 60 ps;
3
NET "sys_clk133" TNM_NET = "sys_clk133";
4
TIMESPEC TS_sys_clk133 = PERIOD "sys_clk133" 133 MHz HIGH 50 %;
5
OFFSET = IN 6 ns VALID 6 ns BEFORE "sys_clk50" RISING;
6
OFFSET = IN 7.5188 ns VALID 7.5188 ns BEFORE "sys_clk133" RISING;
7
8
# PlanAhead generated physical constraints 
9
10
# PlanAhead generated physical constraints 
11
12
NET "ddr2_a[0]" LOC = R2;
13
NET "ddr2_a[10]" LOC = T3;
14
NET "ddr2_a[11]" LOC = V1;
15
NET "ddr2_a[12]" LOC = Y2;
16
NET "ddr2_a[1]" LOC = T4;
17
NET "ddr2_a[2]" LOC = R1;
18
NET "ddr2_a[3]" LOC = U3;
19
NET "ddr2_a[4]" LOC = U2;
20
NET "ddr2_a[5]" LOC = U4;
21
NET "ddr2_a[6]" LOC = U1;
22
NET "ddr2_a[7]" LOC = Y1;
23
NET "ddr2_a[8]" LOC = W1;
24
NET "ddr2_a[9]" LOC = W2;
25
NET "ddr2_ba[0]" LOC = p3;
26
NET "ddr2_ba[1]" LOC = r3;
27
NET "ddr2_dm[0]" LOC = j3;
28
NET "ddr2_dm[1]" LOC = e3;
29
30
# PlanAhead generated physical constraints 
31
32
NET "ddr2_dqs[0]" LOC = k3;
33
NET "ddr2_dqs_n[0]" LOC = k2;
34
35
##############################################################################################################
36
# I/O STANDARDS                                                         
37
##############################################################################################################
38
39
NET "ddr2_a[*]" IOSTANDARD = SSTL18_II;
40
NET "ddr2_ba[0]" IOSTANDARD = SSTL18_II;
41
NET "ddr2_ba[1]" IOSTANDARD = SSTL18_II;
42
NET "ddr2_cke" IOSTANDARD = SSTL18_II;
43
NET "ddr2_cs_n" IOSTANDARD = SSTL18_II;
44
NET "ddr2_ras_n" IOSTANDARD = SSTL18_II;
45
NET "ddr2_cas_n" IOSTANDARD = SSTL18_II;
46
NET "ddr2_we_n" IOSTANDARD = SSTL18_II;
47
NET "ddr2_odt" IOSTANDARD = SSTL18_II;
48
NET "ddr2_dm[0]" IOSTANDARD = SSTL18_II;
49
NET "ddr2_dm[1]" IOSTANDARD = SSTL18_II;
50
NET "ddr2_dqs[0]" IOSTANDARD = DIFF_SSTL18_II;
51
NET "ddr2_dqs[1]" IOSTANDARD = DIFF_SSTL18_II;
52
NET "ddr2_dqs_n[0]" IOSTANDARD = DIFF_SSTL18_II;
53
NET "ddr2_dqs_n[1]" IOSTANDARD = DIFF_SSTL18_II;
54
NET "ddr2_dq[*]" IOSTANDARD = SSTL18_II;
55
56
57
# PlanAhead generated physical constraints 
58
59
NET "ddr2_cas_n" LOC = M4;
60
NET "ddr2_cke" LOC = N3;
61
NET "ddr2_cs_n" LOC = M5;
62
NET "ddr2_odt" LOC = P1;
63
NET "ddr2_ras_n" LOC = M3;
64
NET "ddr2_we_n" LOC = N4;
65
NET "led_ar_done" LOC = T19 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
66
NET "led_init_done" LOC = R20 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
67
NET "sys_clk133" LOC = V12;
68
NET "sys_clk50" LOC = E12;
69
70
# PlanAhead generated physical constraints 
71
72
NET "ddr2_ck[0]" LOC = M1;
73
NET "ddr2_ck_n[0]" LOC = M2;
74
NET "reset_in" LOC = T15;
75
76
# PlanAhead generated IO constraints 
77
78
NET "ddr2_ck[0]" IOSTANDARD = DIFF_SSTL18_II;
79
NET "ddr2_ck_n[0]" IOSTANDARD = DIFF_SSTL18_II;
80
81
# PlanAhead generated IO constraints 
82
83
NET "sys_clk133" IOSTANDARD = LVCMOS33;
84
NET "sys_clk50" IOSTANDARD = LVCMOS33;
85
86
# PlanAhead generated physical constraints 
87
88
NET "ddr2_dq[0]" LOC = H1;
89
NET "ddr2_dq[10]" LOC = G1;
90
NET "ddr2_dq[11]" LOC = H6;
91
NET "ddr2_dq[12]" LOC = H5;
92
NET "ddr2_dq[13]" LOC = F1;
93
NET "ddr2_dq[14]" LOC = G3;
94
NET "ddr2_dq[15]" LOC = F3;
95
NET "ddr2_dq[1]" LOC = K5;
96
NET "ddr2_dq[2]" LOC = K1;
97
NET "ddr2_dq[3]" LOC = L3;
98
NET "ddr2_dq[4]" LOC = L5;
99
NET "ddr2_dq[5]" LOC = L1;
100
NET "ddr2_dq[6]" LOC = K4;
101
NET "ddr2_dq[7]" LOC = H2;
102
NET "ddr2_dq[8]" LOC = F2;
103
NET "ddr2_dq[9]" LOC = G4;
104
105
# PlanAhead generated physical constraints 
106
107
NET "ddr2_dqs[1]" LOC = k6;
108
NET "ddr2_dqs_n[1]" LOC = j5;

noeppkes ...

von Rudolph (Gast)


Lesenswert?

Christian Armbruster schrieb:
> Meine Frage: Was mache ich mit den Signalen:
>
>       cntrl0_rst_dqs_div_in         : in    std_logic;
>       cntrl0_rst_dqs_div_out        : out   std_logic;
>
> cntrl0_rst_dqs_div_in ist ja schon "verdrahtet" mit meinem
> TopLevel-Signal rst_dqs_div_in. Jedoch habe ich im UCF-File keine
> Angaben über ein Pin?

Doch, hast Du. Das ist das Loopback-Signal mit dem der Core sein Delay 
einstellt. In den Schematics ist es das "SD_LOOP"-Signal. Vergleiche 
deinen MIG-Output sonst mal mit dem Referenz-Design. Da stehen sowieso 
noch ein paar evtl. interessante Hinweise drin.

von Christian A. (noeppkes)


Lesenswert?

Rudolph schrieb:
> Christian Armbruster schrieb:
>> Meine Frage: Was mache ich mit den Signalen:
>>
>>       cntrl0_rst_dqs_div_in         : in    std_logic;
>>       cntrl0_rst_dqs_div_out        : out   std_logic;
>>
>> cntrl0_rst_dqs_div_in ist ja schon "verdrahtet" mit meinem
>> TopLevel-Signal rst_dqs_div_in. Jedoch habe ich im UCF-File keine
>> Angaben über ein Pin?
>
> Doch, hast Du. Das ist das Loopback-Signal mit dem der Core sein Delay
> einstellt. In den Schematics ist es das "SD_LOOP"-Signal. Vergleiche
> deinen MIG-Output sonst mal mit dem Referenz-Design. Da stehen sowieso
> noch ein paar evtl. interessante Hinweise drin.

Hallo Rudolph.
Danke für deinen Antwort aber:

Äähh? Wo soll ich das rst_dqs_div_out haben bzw. das loop_back? Im 
TopLevel ist doch nur das Signal rst_dqs_div_in "rausgeführt". Das 
rst_dqs_div_out ist im TopLevel doch gar nicht verwendet.
Anderes herum gefragt. Würde es so funktionieren?. Habe das UG086 schon 
öfters durchgelsen, jedoch ist es für mich noch etwas schwer zu 
verstehen.

Ich würde gerne mal probieren ob das Init_done funktioniert und dann mal 
versuchen ein paar Daten ins Ram zu schreiben und wieder zu lesen.

noeppkes ...

von Rudolph (Gast)


Lesenswert?

Guck Dir mal die Top-Entity deines MIG-Outputs an. Dort findest Du beide 
Signale. Warum die in deiner Top-Entity nicht drinstehen kann ich Dir 
nicht sagen.

Die "SD_LOOP"-Leitung ist auf deinem Board. Die schriebst zu Anfang, 
dass Du das Spartan-3AN Eval-Board hättest. Guck da mal in die 
Schematic.

Christian Armbruster schrieb:
> Ich würde gerne mal probieren ob das Init_done funktioniert und dann mal
> versuchen ein paar Daten ins Ram zu schreiben und wieder zu lesen.

Das ist schon die richtige Vorgehensweise ;-).

von Christian A. (noeppkes)


Lesenswert?

Hallo Rudolph.
Danke für deine Antwort.

Rudolph schrieb:
> Guck Dir mal die Top-Entity deines MIG-Outputs an. Dort findest Du beide
> Signale. Warum die in deiner Top-Entity nicht drinstehen kann ich Dir
> nicht sagen.
>
> Die "SD_LOOP"-Leitung ist auf deinem Board. Die schriebst zu Anfang,
> dass Du das Spartan-3AN Eval-Board hättest. Guck da mal in die
> Schematic.

Habe das SD_LOOP Signal gefunden. H3 raus, H4 rein.
Ich baue es jetzt in den TopLevel ein.

>
> Christian Armbruster schrieb:
>> Ich würde gerne mal probieren ob das Init_done funktioniert und dann mal
>> versuchen ein paar Daten ins Ram zu schreiben und wieder zu lesen.
>
> Das ist schon die richtige Vorgehensweise ;-).

Prüfe jetzt mal ob das Init-Signal kommt.

noeppkes ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.