mikrocontroller.net

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


Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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)
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:52:07 03/24/2010 
-- Design Name: 
-- Module Name:    TopModule - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity TopModule is
    Port ( sys_clk50              : in  STD_LOGIC;
           sys_clk133             : in  STD_LOGIC;
           reset_in               : in  STD_LOGIC;
           rst_dqs_div_in         : IN std_logic;
           burst_done             : in std_logic;
           led_ar_done            : out std_Logic;
           ddr2_a                 : out std_logic_vector(12 downto 0);
           ddr2_ba                : out std_logic_vector(1 downto 0);
           ddr2_cke               : out std_logic;
           ddr2_cs_n              : out std_logic;
           ddr2_ras_n             : out std_logic;
           ddr2_cas_n             : out std_logic;
           ddr2_we_n              : out std_logic;
           ddr2_odt               : out std_logic;
           --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
           user_input_address     : in    std_logic_vector(24 downto 0);
           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);
           user_output_data       : out   std_logic_vector(31 downto 0);
           user_input_data        : in    std_logic_vector(31 downto 0);        
           led_init_done          : out  STD_LOGIC);
end TopModule;

architecture Behavioral of TopModule is

component mig_v3_61
 port(
      cntrl0_ddr2_dq                : inout std_logic_vector(15 downto 0);
      cntrl0_ddr2_a                 : out   std_logic_vector(12 downto 0);
      cntrl0_ddr2_ba                : out   std_logic_vector(1 downto 0);
      cntrl0_ddr2_cke               : out   std_logic;
      cntrl0_ddr2_cs_n              : out   std_logic;
      cntrl0_ddr2_ras_n             : out   std_logic;
      cntrl0_ddr2_cas_n             : out   std_logic;
      cntrl0_ddr2_we_n              : out   std_logic;
      cntrl0_ddr2_odt               : out   std_logic;
      --cntrl0_ddr2_dm                : out   std_logic_vector(1 downto 0); # Christian entfernt
      cntrl0_rst_dqs_div_in         : in    std_logic;
      cntrl0_rst_dqs_div_out        : out   std_logic;
      sys_clk_in                    : in    std_logic;
      reset_in_n                    : in    std_logic;
      cntrl0_burst_done             : in    std_logic;
      cntrl0_init_done              : out   std_logic;
      cntrl0_ar_done                : out   std_logic;
      cntrl0_user_data_valid        : out   std_logic;
      cntrl0_auto_ref_req           : out   std_logic;
      cntrl0_user_cmd_ack           : out   std_logic;
      cntrl0_user_command_register  : in    std_logic_vector(2 downto 0);
      cntrl0_clk_tb                 : out   std_logic;
      cntrl0_clk90_tb               : out   std_logic;
      cntrl0_sys_rst_tb             : out   std_logic;
      cntrl0_sys_rst90_tb           : out   std_logic;
      cntrl0_sys_rst180_tb          : out   std_logic;
      cntrl0_user_output_data       : out   std_logic_vector(31 downto 0);
      cntrl0_user_input_data        : in    std_logic_vector(31 downto 0);
      --cntrl0_user_data_mask         : in    std_logic_vector(3 downto 0); # Christian entfernt
      cntrl0_user_input_address     : in    std_logic_vector(24 downto 0);
      --cntrl0_ddr2_dqs               : inout std_logic_vector(1 downto 0);
      --cntrl0_ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
      cntrl0_ddr2_ck                : out   std_logic_vector(0 downto 0);
      cntrl0_ddr2_ck_n              : out   std_logic_vector(0 downto 0)

);
end component;


-- **************************************************************************


-- Eigener Code by FT



-- type und signaldefs fuer die FSM
type init_s_m is (IDLE, DELAY, DO_INIT, AFTER_INIT);
signal current_state, next_state : init_s_m;

-- zaehlvariable fuer 260 us bei einem Takt von 50 MHz (T=20.0 ns)
-- -> 13000|10 = ....|2
signal delay250us : std_logic_vector(13 downto 0) := "11001011001000"; --13000
--signal delay250us : std_logic_vector(12 downto 0) := "1100101100100"; --6500
--signal init_cmd : std_logic_vector(2 downto 0) := "010";  

-- **************************************************************************  


signal sig_user_cmd : std_logic_vector(2 downto 0) := "000"; -- 000: NOP
signal sig_reset_in_n : std_logic;


begin


u_mig_v3_61 :mig_v3_61
       port map (
      cntrl0_rst_dqs_div_in         => rst_dqs_div_in,
    --  cntrl0_rst_dqs_div_out        => cntrl0_rst_dqs_div_out,
    cntrl0_burst_done             => burst_done,
      sys_clk_in                    => sys_clk133,
      reset_in_n                    => sig_reset_in_n,
      cntrl0_init_done              => led_init_done,
      cntrl0_ar_done                => led_ar_done,
      cntrl0_user_command_register  => sig_user_cmd,
      --cntrl0_user_data_mask         => user_data_mask, # Christian entfernt
      cntrl0_user_input_address     => user_input_address,
    cntrl0_ddr2_dq => ddr2_dq,
    cntrl0_user_output_data => user_output_data,
      cntrl0_user_input_data => user_input_data,
    cntrl0_ddr2_ck => ddr2_ck,
    cntrl0_ddr2_ck_n => ddr2_ck_n,
    cntrl0_ddr2_a => ddr2_a,
    cntrl0_ddr2_ba => ddr2_ba,
    cntrl0_ddr2_cke => ddr2_cke,
    cntrl0_ddr2_cs_n => ddr2_cs_n,
    cntrl0_ddr2_ras_n => ddr2_ras_n,
    cntrl0_ddr2_cas_n => ddr2_cas_n,
    cntrl0_ddr2_we_n => ddr2_we_n,
    --cntrl0_ddr2_dqs => ddr2_dqs,
    --cntrl0_ddr2_dqs_n => ddr2_dqs_n,
    cntrl0_ddr2_odt => ddr2_odt
    --cntrl0_ddr2_dm => ddr2_dm # Christian entfernt
);

-- *********************************************************
-- Begin eigener CODE

-- Einbau einer FSM zum automatischen Initialisieren

-- Statemachine mit vier Zustaenden:
-- ---------------------------------
-- IDLE.     Ist der Endzustand nach der Initialisierung; von hier aus: Weitere Steuerung
-- DELAY.     Startzustand; der zuvor geladene Counter wird hier heruntergezaehlt
-- DO_INIT.    Wird nach Erreichen des Nullstandes des Counters durchgefuehrt; hier wird das
--          Signal 010 (= INIT) abgesetzt
-- AFTER_INIT.  Das zuvor abgesetzt  Signal 010 wird hier wieder aufgehoben und auf 000 gesetzt,
--          was einem NOP-Kommando entspricht


-- Zeitverzug: Wichtig, da das Kommando erst nach einer Blockzeit von 200 us (33414 Takte)
-- angenommen wird; vorherige Kommando werden ignoriert
-- bei einer Frequenz von 133 MHz entspricht dies 251.3 us, die es zu warten gilt; 
-- der Timer (Wert des Signals delay250us) wurde entsprechend auf 260us angepasst

-- INIT-Command: Das Init-Command darf nur einen Takt anliegen, sonst werden die entsprechenden
-- Signale nicht auf die zuvor benoetigten Pegel gezogen; dies wird aus der Simulation vor allem
-- bei den Signalen "init_memory" und "init_mem" deutlich.
-- Das Signal rst180 bzw _r wird nach einem "cke"-Signal auf 0 gesetzt, steuernd dafuer ist das
-- Signal wait_200us im Modul controller (top00 -> controller)
-- Vorher wird der Chip fuer alle anliegenden Signale gesperrt

-- *********************************************************

process
begin
  wait until rising_edge(sys_clk50);
  sig_reset_in_n <= not reset_in;
end process;

-- Start der State_Machine

process
begin
  wait until falling_edge(sys_clk50);
  case current_state is
    when DELAY         => if delay250us = "00000000000000" then
                      next_state <= DO_INIT;
                    else
                      delay250us <= delay250us-'1';                
                      next_state <= DELAY;
                    end if;
    when IDLE        => next_state <= IDLE;
    when DO_INIT       => sig_user_cmd <= "010"; -- hier wird 010 ins UCR geschrieben
                    next_state <= AFTER_INIT;
    when AFTER_INIT    => sig_user_cmd <= "000";
                    next_state <= IDLE;
  end case;
end process;

-- Einen Status weiterspringen und init setzen
process
begin
  wait until falling_edge(sys_clk50);
  if reset_in = '1' then
    current_state <= DELAY;
  else
    current_state <= next_state;
  end if;
end process;


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 ...

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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:
##############################################################
#
# Xilinx Core Generator version 12.4
# Date: Fri Jan 28 10:56:57 2011
#
##############################################################
#
#  This file contains the customisation parameters for a
#  Xilinx CORE Generator IP GUI. It is strongly recommended
#  that you do not manually alter this file as it may cause
#  unexpected and unsupported behavior.
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = VHDL
SET device = xc3s700an
SET devicefamily = spartan3a
SET flowvendor = Foundation_ISE
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = fgg484
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -4
SET verilogsim = false
SET vhdlsim = true
# END Project Options
# BEGIN Select
SELECT MIG family Xilinx,_Inc. 3.61
# END Select
# BEGIN Parameters
CSET component_name=mig_v3_61
CSET xml_input_file=./mig_v3_61/user_design/mig.prj
# END Parameters
GENERATE
# CRC:  5f6f976

>
> Duke

Bis dann ...
noeppkes

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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)
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:52:07 03/24/2010 
-- Design Name: 
-- Module Name:    TopModule - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity TopModule is
    Port ( sys_clk50              : in  STD_LOGIC;
           sys_clk133             : in  STD_LOGIC;
           reset_in               : in  STD_LOGIC;
           rst_dqs_div_in         : IN std_logic;
           burst_done             : in std_logic;
           led_ar_done            : out std_Logic;
           ddr2_a                 : out std_logic_vector(12 downto 0);
           ddr2_ba                : out std_logic_vector(1 downto 0);
           ddr2_cke               : out std_logic;
           ddr2_cs_n              : out std_logic;
           ddr2_ras_n             : out std_logic;
           ddr2_cas_n             : out std_logic;
           ddr2_we_n              : out std_logic;
           ddr2_odt               : out std_logic;
           ddr2_dm                : out std_logic_vector(1 downto 0);
           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);
           user_input_address     : in    std_logic_vector(24 downto 0);
           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);
           user_output_data       : out   std_logic_vector(31 downto 0);
           user_input_data        : in    std_logic_vector(31 downto 0);        
           led_init_done          : out  STD_LOGIC);
end TopModule;

architecture Behavioral of TopModule is

component mig_v3_61
 port(
      cntrl0_ddr2_dq                : inout std_logic_vector(15 downto 0);
      cntrl0_ddr2_a                 : out   std_logic_vector(12 downto 0);
      cntrl0_ddr2_ba                : out   std_logic_vector(1 downto 0);
      cntrl0_ddr2_cke               : out   std_logic;
      cntrl0_ddr2_cs_n              : out   std_logic;
      cntrl0_ddr2_ras_n             : out   std_logic;
      cntrl0_ddr2_cas_n             : out   std_logic;
      cntrl0_ddr2_we_n              : out   std_logic;
      cntrl0_ddr2_odt               : out   std_logic;
      cntrl0_ddr2_dm                : out   std_logic_vector(1 downto 0);
      cntrl0_rst_dqs_div_in         : in    std_logic;
      cntrl0_rst_dqs_div_out        : out   std_logic;
      sys_clk_in                    : in    std_logic;
      reset_in_n                    : in    std_logic;
      cntrl0_burst_done             : in    std_logic;
      cntrl0_init_done              : out   std_logic;
      cntrl0_ar_done                : out   std_logic;
      cntrl0_user_data_valid        : out   std_logic;
      cntrl0_auto_ref_req           : out   std_logic;
      cntrl0_user_cmd_ack           : out   std_logic;
      cntrl0_user_command_register  : in    std_logic_vector(2 downto 0);
      cntrl0_clk_tb                 : out   std_logic;
      cntrl0_clk90_tb               : out   std_logic;
      cntrl0_sys_rst_tb             : out   std_logic;
      cntrl0_sys_rst90_tb           : out   std_logic;
      cntrl0_sys_rst180_tb          : out   std_logic;
      cntrl0_user_output_data       : out   std_logic_vector(31 downto 0);
      cntrl0_user_input_data        : in    std_logic_vector(31 downto 0);
      cntrl0_user_data_mask         : in    std_logic_vector(3 downto 0);
      cntrl0_user_input_address     : in    std_logic_vector(24 downto 0);
      cntrl0_ddr2_dqs               : inout std_logic_vector(1 downto 0);
      cntrl0_ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
      cntrl0_ddr2_ck                : out   std_logic_vector(0 downto 0);
      cntrl0_ddr2_ck_n              : out   std_logic_vector(0 downto 0)

);
end component;


-- **************************************************************************


-- Eigener Code by FT



-- type und signaldefs fuer die FSM
type init_s_m is (IDLE, DELAY, DO_INIT, AFTER_INIT);
signal current_state, next_state : init_s_m;

-- zaehlvariable fuer 260 us bei einem Takt von 50 MHz (T=20.0 ns)
-- -> 13000|10 = ....|2
signal delay250us : std_logic_vector(13 downto 0) := "11001011001000"; --13000
--signal delay250us : std_logic_vector(12 downto 0) := "1100101100100"; --6500
--signal init_cmd : std_logic_vector(2 downto 0) := "010";  

-- **************************************************************************  


signal sig_user_cmd : std_logic_vector(2 downto 0) := "000"; -- 000: NOP
signal sig_reset_in_n : std_logic;


begin


u_mig_v3_61 :mig_v3_61
       port map (
      cntrl0_rst_dqs_div_in         => rst_dqs_div_in,
      cntrl0_rst_dqs_div_out        => cntrl0_rst_dqs_div_out,
      cntrl0_burst_done             => burst_done,
      sys_clk_in                    => sys_clk133,
      reset_in_n                    => sig_reset_in_n,
      cntrl0_init_done              => led_init_done,
      cntrl0_ar_done                => led_ar_done,
      cntrl0_user_command_register  => sig_user_cmd,
      cntrl0_user_data_mask         => user_data_mask,
      cntrl0_user_input_address     => user_input_address,
      cntrl0_ddr2_dq                => ddr2_dq,
      cntrl0_user_output_data       => user_output_data,
      cntrl0_user_input_data        => user_input_data,
      cntrl0_ddr2_ck                => ddr2_ck,
      cntrl0_ddr2_ck_n              => ddr2_ck_n,
      cntrl0_ddr2_a                 => ddr2_a,
      cntrl0_ddr2_ba                => ddr2_ba,
      cntrl0_ddr2_cke               => ddr2_cke,
      cntrl0_ddr2_cs_n              => ddr2_cs_n,
      cntrl0_ddr2_ras_n             => ddr2_ras_n,
      cntrl0_ddr2_cas_n             => ddr2_cas_n,
      cntrl0_ddr2_we_n              => ddr2_we_n,
      cntrl0_ddr2_dqs               => ddr2_dqs,
      cntrl0_ddr2_dqs_n             => ddr2_dqs_n,
      cntrl0_ddr2_odt               => ddr2_odt,
      cntrl0_ddr2_dm                => ddr2_dm
);

-- *********************************************************
-- Begin eigener CODE

-- Einbau einer FSM zum automatischen Initialisieren

-- Statemachine mit vier Zustaenden:
-- ---------------------------------
-- IDLE.     Ist der Endzustand nach der Initialisierung; von hier aus: Weitere Steuerung
-- DELAY.     Startzustand; der zuvor geladene Counter wird hier heruntergezaehlt
-- DO_INIT.    Wird nach Erreichen des Nullstandes des Counters durchgefuehrt; hier wird das
--          Signal 010 (= INIT) abgesetzt
-- AFTER_INIT.  Das zuvor abgesetzt  Signal 010 wird hier wieder aufgehoben und auf 000 gesetzt,
--          was einem NOP-Kommando entspricht


-- Zeitverzug: Wichtig, da das Kommando erst nach einer Blockzeit von 200 us (33414 Takte)
-- angenommen wird; vorherige Kommando werden ignoriert
-- bei einer Frequenz von 133 MHz entspricht dies 251.3 us, die es zu warten gilt; 
-- der Timer (Wert des Signals delay250us) wurde entsprechend auf 260us angepasst

-- INIT-Command: Das Init-Command darf nur einen Takt anliegen, sonst werden die entsprechenden
-- Signale nicht auf die zuvor benoetigten Pegel gezogen; dies wird aus der Simulation vor allem
-- bei den Signalen "init_memory" und "init_mem" deutlich.
-- Das Signal rst180 bzw _r wird nach einem "cke"-Signal auf 0 gesetzt, steuernd dafuer ist das
-- Signal wait_200us im Modul controller (top00 -> controller)
-- Vorher wird der Chip fuer alle anliegenden Signale gesperrt

-- *********************************************************

process
begin
  wait until rising_edge(sys_clk50);
  sig_reset_in_n <= not reset_in;
end process;

-- Start der State_Machine

process
begin
  wait until falling_edge(sys_clk50);
  case current_state is
    when DELAY         => if delay250us = "00000000000000" then
                      next_state <= DO_INIT;
                    else
                      delay250us <= delay250us-'1';                
                      next_state <= DELAY;
                    end if;
    when IDLE        => next_state <= IDLE;
    when DO_INIT       => sig_user_cmd <= "010"; -- hier wird 010 ins UCR geschrieben
                    next_state <= AFTER_INIT;
    when AFTER_INIT    => sig_user_cmd <= "000";
                    next_state <= IDLE;
  end case;
end process;

-- Einen Status weiterspringen und init setzen
process
begin
  wait until falling_edge(sys_clk50);
  if reset_in = '1' then
    current_state <= DELAY;
  else
    current_state <= next_state;
  end if;
end process;


end Behavioral;



Und hier nun noch das UCF-File:


NET "sys_clk50" TNM_NET = "sys_clk50";
TIMESPEC TS_sys_clk50 = PERIOD "sys_clk50" 50 MHz HIGH 50 % INPUT_JITTER 60 ps;
NET "sys_clk133" TNM_NET = "sys_clk133";
TIMESPEC TS_sys_clk133 = PERIOD "sys_clk133" 133 MHz HIGH 50 %;
OFFSET = IN 6 ns VALID 6 ns BEFORE "sys_clk50" RISING;
OFFSET = IN 7.5188 ns VALID 7.5188 ns BEFORE "sys_clk133" RISING;

# PlanAhead generated physical constraints 

# PlanAhead generated physical constraints 

NET "ddr2_a[0]" LOC = R2;
NET "ddr2_a[10]" LOC = T3;
NET "ddr2_a[11]" LOC = V1;
NET "ddr2_a[12]" LOC = Y2;
NET "ddr2_a[1]" LOC = T4;
NET "ddr2_a[2]" LOC = R1;
NET "ddr2_a[3]" LOC = U3;
NET "ddr2_a[4]" LOC = U2;
NET "ddr2_a[5]" LOC = U4;
NET "ddr2_a[6]" LOC = U1;
NET "ddr2_a[7]" LOC = Y1;
NET "ddr2_a[8]" LOC = W1;
NET "ddr2_a[9]" LOC = W2;
NET "ddr2_ba[0]" LOC = p3;
NET "ddr2_ba[1]" LOC = r3;
NET "ddr2_dm[0]" LOC = j3;
NET "ddr2_dm[1]" LOC = e3;

# PlanAhead generated physical constraints 

NET "ddr2_dqs[0]" LOC = k3;
NET "ddr2_dqs_n[0]" LOC = k2;

##############################################################################################################
# I/O STANDARDS                                                         
##############################################################################################################

NET "ddr2_a[*]" IOSTANDARD = SSTL18_II;
NET "ddr2_ba[0]" IOSTANDARD = SSTL18_II;
NET "ddr2_ba[1]" IOSTANDARD = SSTL18_II;
NET "ddr2_cke" IOSTANDARD = SSTL18_II;
NET "ddr2_cs_n" IOSTANDARD = SSTL18_II;
NET "ddr2_ras_n" IOSTANDARD = SSTL18_II;
NET "ddr2_cas_n" IOSTANDARD = SSTL18_II;
NET "ddr2_we_n" IOSTANDARD = SSTL18_II;
NET "ddr2_odt" IOSTANDARD = SSTL18_II;
NET "ddr2_dm[0]" IOSTANDARD = SSTL18_II;
NET "ddr2_dm[1]" IOSTANDARD = SSTL18_II;
NET "ddr2_dqs[0]" IOSTANDARD = DIFF_SSTL18_II;
NET "ddr2_dqs[1]" IOSTANDARD = DIFF_SSTL18_II;
NET "ddr2_dqs_n[0]" IOSTANDARD = DIFF_SSTL18_II;
NET "ddr2_dqs_n[1]" IOSTANDARD = DIFF_SSTL18_II;
NET "ddr2_dq[*]" IOSTANDARD = SSTL18_II;


# PlanAhead generated physical constraints 

NET "ddr2_cas_n" LOC = M4;
NET "ddr2_cke" LOC = N3;
NET "ddr2_cs_n" LOC = M5;
NET "ddr2_odt" LOC = P1;
NET "ddr2_ras_n" LOC = M3;
NET "ddr2_we_n" LOC = N4;
NET "led_ar_done" LOC = T19 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "led_init_done" LOC = R20 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "sys_clk133" LOC = V12;
NET "sys_clk50" LOC = E12;

# PlanAhead generated physical constraints 

NET "ddr2_ck[0]" LOC = M1;
NET "ddr2_ck_n[0]" LOC = M2;
NET "reset_in" LOC = T15;

# PlanAhead generated IO constraints 

NET "ddr2_ck[0]" IOSTANDARD = DIFF_SSTL18_II;
NET "ddr2_ck_n[0]" IOSTANDARD = DIFF_SSTL18_II;

# PlanAhead generated IO constraints 

NET "sys_clk133" IOSTANDARD = LVCMOS33;
NET "sys_clk50" IOSTANDARD = LVCMOS33;

# PlanAhead generated physical constraints 

NET "ddr2_dq[0]" LOC = H1;
NET "ddr2_dq[10]" LOC = G1;
NET "ddr2_dq[11]" LOC = H6;
NET "ddr2_dq[12]" LOC = H5;
NET "ddr2_dq[13]" LOC = F1;
NET "ddr2_dq[14]" LOC = G3;
NET "ddr2_dq[15]" LOC = F3;
NET "ddr2_dq[1]" LOC = K5;
NET "ddr2_dq[2]" LOC = K1;
NET "ddr2_dq[3]" LOC = L3;
NET "ddr2_dq[4]" LOC = L5;
NET "ddr2_dq[5]" LOC = L1;
NET "ddr2_dq[6]" LOC = K4;
NET "ddr2_dq[7]" LOC = H2;
NET "ddr2_dq[8]" LOC = F2;
NET "ddr2_dq[9]" LOC = G4;

# PlanAhead generated physical constraints 

NET "ddr2_dqs[1]" LOC = k6;
NET "ddr2_dqs_n[1]" LOC = j5;

noeppkes ...

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-).

Autor: Christian Armbruster (noeppkes)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.