Forum: FPGA, VHDL & Co. Xilinx Spartan 3AN -- DDR2 SDRAM Ansteuerung


von Frank S. (karnikel)


Lesenswert?

Hallo,

ich bin ziemlich neu auf dem Gebiet der VHDL-Programmierung und hätte 
gleich mal eine Frage.

Wie genau programmiere ich die Ansteuerung des DDR2 SDRAM's auf meinem 
Xilinx Spartan 3AN Eval-Board?
Das ganze soll als FIFO aggieren.
Gibt es da eine definierte Anzahl an Bits, die pro Speicherzugriff 
gespeichert werden muss (kann)? Wie genau schreibe ich meinen Bitvektor 
(z.B. BITVEKTOR(15 downto 0) ) in den RAM?

Umgebung:
Xilinx ISE 11
Xilinx Spartan 3AN Eval-Board mit XC3S700AN FPGA

Ich hoffe ich hab alle wichtigen Infos mitgeteilt

Vielen Dank schonmal

Viele Grüße...Karnikel

von Thi L. (flothi)


Lesenswert?

Ouch, nicht gerade eine ideale Startaufgabe, aber gut...

Nach Lektüre diverses Userguides (v.a. UG086, vgl. g00gle) und den darin 
genannten AppNotes wird dir einiges klarer werden.

Auch kann ein Blick in das Datenblatt des Speichers, diverse 
Wiki-Artikel und die JEDEC-Standards Licht ins Dunkel bringen.

Kurzum: Als Anfänger eine, äähm, nicht einfache Aufgabe.

VG

von Frank S. (karnikel)


Lesenswert?

Naja...ganz Anfänger bin ich nicht mehr.
Aber ich hab mir auch die ganze Sache nich ganz freiwillig ausgesucht :) 
ich muss mich quasi damit beschäftigen und das ganze irgendwie 
hinbekommen :)
Trotzdem erstmal danke...

Um mal meine Aufgabe zu beschreiben:

Das Ziel ist Bits kontinuierlich einzulesen und abzuspeichern, um diese 
dann zeitverzögert (N*100ns) wieder rauszugeben. Ich hatte zuerst an 
D-FF's gedacht, so dass ich wie in einem Schieberegister die Bits von FF 
zu FF schiebe und dann nach N*FF's hinten wieder rausgebe. Soweit so 
gut, aber die Bits die ich speichern muss, sind zu viele und würden den 
FPGA an seine Grenzen bringen. Es sollen maximal 100000 Bits gespeichert 
werden (in 4 facher Ausführung) also insgesammt 400000 Bits. Und selbst 
wenn der Fpga das mitmachen würde, wäre das nich gerade eine feine 
Lösung glaube ich.
Darum will ich die reinkommenden Bits in einen Bitvektor nacheinander 
reinschieben und dann auf dem RAM abspeichern, um diesen dann wieder 
auszulesen und die Bits nach ner Zeitverzögerung wieder rausgeben.

Vielleicht habt ihr ne Idee, wie man es noch eleganter Lösen könnte???

Grüße Karnikel

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karnikel S. schrieb:
> Das Ziel ist Bits kontinuierlich einzulesen
Wie schnell? Abtastrate?

von Klaus F. (kfalser)


Lesenswert?

Karnikel S. schrieb:
> Es sollen maximal 100000 Bits gespeichert
> werden (in 4 facher Ausführung) also insgesammt 400000 Bits

Der 700AN hat bis 360 KBit Blockram, der ist intern und einfacher zu 
verwenden als ein externes DDR RAM.
Wenn's ein bischen kleiner geht, dann kommst Du mit dem Blockram aus.

Ansonsten fehlen noch Angaben über die Datenraten, mit denen die Bits 
rein und rausgehen

von Frank S. (karnikel)


Lesenswert?

also das ganze passiert mit 1Mbit/s und es geht leider von der Bitmenge 
nicht kleiner. Hätte auch zu gern den internen Speicher vom FPGA 
genutzt...aber das wäre ja zu einfach =)

von Johann (Gast)


Lesenswert?

Es gibt doch gößere FPGAs wie den Spartan3 1400 der hat deutlich mehr 
RAM. Auch die neue Spartan 6 Modelle habe deutlich mehr RAM. Ich weiß es 
ist jetzt sich nicht so einfach eine neue Platine zu erstellen, jedoch 
erleichtert es später das Routen, da so ein Speicher meist so 32 oder 64 
Datenleitungen hat und dann noch die ganzen Adressleitungen. Zudem 
benötigt dieser Baustein auch eine Menge Platz.

Daher kann ich nur den neuen SPARTAN 6 mit 192 Pin empfehlen dieser ist 
nur 5x5mm groß und kosten so unter 30€ hat ca. 560k RAM intern.

von Frank S. (karnikel)


Lesenswert?

Ich hab leider nur das oben genannte Eval-board und würde das auch gern 
benutzen (Neukauf kommt leider nicht in Frage).
Trotzdem danke für den Tipp...

von Thi L. (flothi)


Lesenswert?

Wie geschrieben, schau dir die o.g. Userguides an, wenn du mit 
DDR(2)-Speicher arbeiten willst.

Dann lass den Memory Interface Generator für dich arbeiten und überleg 
dir, wie du die Daten im Speicher organisierst (Ansatz im Verzeichnis 
Testbench des erzeugten Controllers).

VG

 Florian

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Ich habe das gleiche Board. Das MIG skript läuft bei mir nicht einmal 
durch und der zeugt mir die Files. In einer älteren ISE kam mit dem MIG 
Skript wenigsten noch was raus. Falls du Erfolg hast, gib mir bitte eine 
Info.

von Thi L. (flothi)


Lesenswert?

Laufen tuts bei mir ohne Probleme; nur wird nicht fehlerfrei 
synthetisiert - warum auch immer, aber mich wundert bei Xilinx nichts 
mehr. Hast du nach der Erstellung die bat-Datei "create_ise.bat" 
ausgeführt?

VG

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

> mehr. Hast du nach der Erstellung die bat-Datei "create_ise.bat"
> ausgeführt?

Was eine bat datei. Wie? Wo? Was?

Was macht die Bat datei? Ich arbeite unter Linux da ist ein Shell skript 
doch dieses habe ich nicht bemerkt.


Ich hatte mal ich glaube mit der ist 10.3 das Mig für das EVAL-Board 
laufen lassen. Dabei kam ein VHDL code bzw. ein Verilogcode heraus.

Warum kommt jetzt da eine Bat heraus?

von Thi L. (flothi)


Lesenswert?

Ich hab bei meinen erzeugten Files diverse Bat-Dateien, die mir aus dem 
Code ISE-Projekte erstellen. Es ginge bestimmt auch ohne ;-)

Den UG086 kennst du aber?

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Ich habe gerade nicht alle Unterlagen zur Hand ob ich auch UG086 gelesen 
habe. Vermutlich.

Ich hatte den größten Einblick, wie es funktionieren sollte mit XAPP454.

von Frank S. (karnikel)


Lesenswert?

Hi...da bin ich wieder...

ich hatte das Probem auch, dass der Core-Generator zwar durchlief, die 
Dateien dazu aber nicht erstellt wurden.
Ich hab dann mal das ISE-Progämmchen per update auf 11.5 gebracht und 
dann liefs wieder durch und alles hat funktioniert, vllt. hilft das euer 
Problem zu beseitigen...

Ich hätt aber noch ne Frage zum Core Generator. Und zwar fragt das Ding 
mich, welchen Speicher ich auf dem Board habe und Listet mir eine Reihe 
an Auswahlmöglichkeiten auf. Laut Xilinx habe ich einen MT47H32M16 Chip 
drauf. Die Auswahl erweitert sich aber beim Core Generator auf
MT47H32M16XX-3
MT47H32M16XX-37E
MT47H32M16XX-5E
Was bedeuten die letzten Zeichen hinter dem Minus und welchen muss ich 
da auswählen?

Die zweite Frage wäre: gibt es einen Unterschied zwischen Speed Grade = 
-4 und -5?
Also mir ist schon klar, dass er schneller bzw. langsamer arbeitet, aber 
gibt es unterschiede in der Stabilität oder sonstigem Zeitverhalten?

Viele Grüße

von Thi L. (flothi)


Lesenswert?

Laut BOM hast du, wenn du ein Spartan-3AN-Starterkit hast, einen 
MT47H32M16BN-3; im Datenblatt von Micron sind die einzelnen Stellen 
erläutert (hier: -3 -> Timing: cycle-time = 3,0 ns -> DDR2-667 möglich).

Der Speedgrade des FPGA gibt dir halt den maximalen Takt (vgl. 
Datenblatt), den der FPGA ausspucken kann. Auswirkungen auf Stabilität 
etc sollte es nicht haben, solang du in den Spezifikationen bist.

von Frank S. (karnikel)


Lesenswert?

Hi,

irgendwie habe ich ein Problem, den Ram in mein Programm zu 
implementieren.
die Port-List vom RAM sieht so aus:
1
entity FIFO_INST is
2
  port (
3
      cntrl0_ddr2_dq                : inout std_logic_vector(15 downto 0);
4
      cntrl0_ddr2_a                 : out   std_logic_vector(12 downto 0);
5
      cntrl0_ddr2_ba                : out   std_logic_vector(1 downto 0);
6
      cntrl0_ddr2_cke               : out   std_logic;
7
      cntrl0_ddr2_cs_n              : out   std_logic;
8
      cntrl0_ddr2_ras_n             : out   std_logic;
9
      cntrl0_ddr2_cas_n             : out   std_logic;
10
      cntrl0_ddr2_we_n              : out   std_logic;
11
      cntrl0_ddr2_odt               : out   std_logic;
12
      cntrl0_ddr2_dm                : out   std_logic_vector(1 downto 0);
13
      cntrl0_rst_dqs_div_in         : in    std_logic;
14
      cntrl0_rst_dqs_div_out        : out   std_logic;
15
      sys_clkb                      : in    std_logic;
16
      sys_clk                       : in    std_logic;
17
      reset_in_n                    : in    std_logic;
18
      cntrl0_burst_done             : in    std_logic;
19
      cntrl0_init_done              : out   std_logic;
20
      cntrl0_ar_done                : out   std_logic;
21
      cntrl0_user_data_valid        : out   std_logic;
22
      cntrl0_auto_ref_req           : out   std_logic;
23
      cntrl0_user_cmd_ack           : out   std_logic;
24
      cntrl0_user_command_register  : in    std_logic_vector(2 downto 0);
25
      cntrl0_clk_tb                 : out   std_logic;
26
      cntrl0_clk90_tb               : out   std_logic;
27
      cntrl0_sys_rst_tb             : out   std_logic;
28
      cntrl0_sys_rst90_tb           : out   std_logic;
29
      cntrl0_sys_rst180_tb          : out   std_logic;
30
      cntrl0_user_output_data       : out   std_logic_vector(31 downto 0);
31
      cntrl0_user_input_data        : in    std_logic_vector(31 downto 0);
32
      cntrl0_user_data_mask         : in    std_logic_vector(3 downto 0);
33
      cntrl0_user_input_address     : in    std_logic_vector(24 downto 0);
34
      cntrl0_ddr2_dqs               : inout std_logic_vector(1 downto 0);
35
      cntrl0_ddr2_dqs_n             : inout std_logic_vector(1 downto 0);
36
      cntrl0_ddr2_ck                : out   std_logic_vector(0 downto 0);
37
      cntrl0_ddr2_ck_n              : out   std_logic_vector(0 downto 0)
38
    );
39
end FIFO_INST;


und meine entity vom Programm (auf Grundlage der UCF-Datei ist:



1
SD_A      : in std_logic_vector(15 downto 0) := (others => '0');
2
SD_BA      : in std_logic_vector(2 downto 0)  := (others => '0');
3
SD_RAS      : in std_logic := '0';
4
SD_CAS      : in std_logic := '0';
5
SD_CK_N    : in std_logic := '0';
6
SD_CK_P    : in std_logic := '0';
7
SD_CKE      : in std_logic := '0';
8
SD_ODT      : in std_logic := '0';
9
SD_CS      : in std_logic := '0';
10
SD_WE      : in std_logic := '0';
11
SD_LDM      : in std_logic := '0';
12
SD_LDQS_N  : in std_logic := '0';
13
SD_LDQS_P  : in std_logic := '0';
14
SD_LOOP_IN : in std_logic := '0';
15
SD_LOOP_OUT: in std_logic := '0';
16
SD_UDM      : in std_logic := '0';
17
SD_UDQS_N  : in std_logic := '0';
18
SD_UDQS_P  : in std_logic := '0';
19
SD_DQ      : in std_logic_vector(15 downto 0) := (others => '0')

Also einige Signale kann ich noch Routen. Aber es fängt schonmal dabei 
an, dass z.B. der Vektor "cntrl0_ddr2_a" 13 Bit groß ist und der Vektor 
"SD_A" 16Bit. Und außerdem sind viel weniger Signale in der UCF Datei 
vorhanden als vom RAM gebraucht werden.

Also entweder hab ich nen Fehler beim erstellen des RAM's mit dem Core 
Generator gemacht, oder ich habe eine Falsche UCF-Datei.
Die UCF-Datei ist aber eigentlich die, die standartmäßig angeboten wird.

Vielen Dank
Grüße Karnikel

von Frank S. (karnikel)


Lesenswert?

Kennt jemand eine Quelle für eine ucf-Datei die auch 100% zu meinem 
Board passt?
Oder hat schonmal jemand eine DDR2 SDRAM Ansteuerung mit dem Core 
Generator erstellt und kann hier ein kleines HowTo posten?
Wäre echt ein feiner Zug und sicherlich auch vielen anderen 
Hilfreich...weil viel findet man im Netz nich unbedingt dazu...

Viele Grüße

von Duke Scarring (Gast)


Lesenswert?

Karnikel S. schrieb:
> Kennt jemand eine Quelle für eine ucf-Datei die auch 100% zu meinem
> Board passt?
Schau doch mal bei Xilinx nach Referenz-Designs.
ug334.pdf verweist auf:
http://www.xilinx.com/products/boards/s3astarter/files/s3astarter.ucf

> Oder hat schonmal jemand eine DDR2 SDRAM Ansteuerung mit dem Core
> Generator erstellt
Ja.
Da waren auch Simulations- und Syntheseskripte dabei. Da braucht man 
eigentlich kein Howto.

Duke

von Frank S. (karnikel)


Lesenswert?

Die richtige UCF-Datei hatte ich also schon, stimmt 1:1 überein. Jetz 
kanns eigentlich nur noch am MIG liegen.

Wo finde ich denn diese Simulations- und Syntheseskripte? (mit dem Sheet 
ug086 hab ich mich schon mehrmals auseinandergesetzt...irgendwie ohne 
Erfolg)

Tut mir leid, wenn ich mich bisschen blöd anstelle...aber ich suche 
schon seit Tagen nach einer Lösung und komm einfach nich weiter...

von Duke Scarring (Gast)


Lesenswert?

Karnikel S. schrieb:
> Wo finde ich denn diese Simulations- und Syntheseskripte?

Bei mir liegen die z.B. hier:
[...]/cores/ddr2_core_v0/example_design/par/create_ise.bat
[...]/cores/ddr2_core_vo/example_design/sim/sim.do

Einfach mal durch die vom MIG/Coregen generierten Verzeichnisse stöbern. 
Das hat sogar System.

Duke

von Frank S. (karnikel)


Lesenswert?

Hi mal wieder...

also mittlerweile bin ich etwas vorran gekommen und habe das vom MIG 
erstellte Interface in mein Program integriert. Nach wie vor weiß ich 
aber nicht, wie die Ansteuerung funktioniert. Ich hab schon so einiges 
ausprobiert aber sobald ich das ganze simuliere passiert gar nix. Bin 
ziemlich am verzweifeln.

Hat hier schonmal jemand eine einfach verständliche DDR2 SDRAM 
Ansteuerung gebastelt und kann die hier mal veröffentlichen? Die 
Beispiele von Xilinx sind schon ziemlich unverständlich.

von Migname (Gast)


Lesenswert?

Moin,

geht denn das "cntrl0_init_done" signal auf '1' wenn Du Dein System 
simulierst? Das dauert recht lange. Davon unabhängig würde ich an Deiner 
Stelle als erstes versuchen den vom MIG erzeugten rw-test sowohl in der 
Simulation als auch auf realer Hardware zum laufen zu bringen, bevor du 
was eigenes an das user interface "ranschraubst".

Gruß

von Frank S. (karnikel)


Lesenswert?

Hi,

danke für deine schnelle Antwort. Das mit dem init Signal ist nämlich 
genau mein Problem. Ich hab bisher folgendes Versucht:

1. Test
user_command_register = 010 für einen Takt bei fallender Flanke und 
danach 300µs simuliert.

2. Test
user_command_register = 010 nach 200µs für einen Takt bei fallender 
Flanke und danach weitere 300µs simuliert.

Is zwar nur quick&dirty geschriben, aber hiermal mein Programm für den 
2. Fall
1
signal STATE  : STATE_TYPE := INIT;
2
signal counter  : natural range 0 to 13400 := 13400;  
3
4
begin
5
6
FIFO_control : process(clk_i_P)
7
begin
8
  if falling_edge(clk_i_P) then
9
    if RESET = '1' then
10
      command_register <= "000";;
11
    else
12
      case STATE is
13
        when INIT =>
14
    if counter = 0 then
15
      command_register <= "010";
16
      counter <= counter - 1;
17
    else 
18
      command_register <= "000";
19
      counter <= counter - 1;
20
    end if;
21
    if init_done = '1' then
22
      counter <= counter;
23
    end if;
24
  end case;
25
      end if;
26
    end if;
27
  end process;    
28
end Behavioral;
in der Simulation Funktioniert auch alles (die CLK_P und CLK_N laufen 
entgegengesetzt und im richtigen 133 MHz Takt, das user_command_register 
wird kurz auf 010 gesetz) nur dieses init_done signal kommt einfach nich 
hoch.

Was genau meinst du mit "rw-test"?

von Thi L. (flothi)


Lesenswert?

Karnikel S. schrieb:
> Was genau meinst du mit "rw-test"?

Im "Example-Design" werden abwechselnd 5 Write und 5 Read-Bursts auf den 
Speicher ausgeführt; anschließend werden die Daten verglichen. Sind 
beide Datenströme identisch, bleibt cntrl_error (o.ä.) aus, ansonsten 
auf '1'.

Gesteuert wird das ganze an einer zentralen Stelle: cmd_fsm in der 
Testbench. An der Stelle habe ich meine eigene Logik eingebaut. Dazu 
dann noch addr_gen (Adressgenerierung) anpassen.

Ich würde also wie gesagt zusehen, ob das ganze in Simulation wie real 
läuft. Du brauchst zu Testen eigentlich nur clock und reset nebst zwei 
LED (Init Done und Error), mal die DDR2-Signale außen vor.

VG

von Duke Scarring (Gast)


Lesenswert?

Karnikel S. schrieb:
> init_done signal kommt einfach nich
> hoch

Das muss erstmal kommen.

Simulierst Du die DCMs mit?
Haben die einen Reset?
Liegt der Reset dort erstmal drei Takte lang an?
Welches Memory Model verwendest Du?

Duke

von Frank S. (karnikel)


Lesenswert?

Hi...vielen Dank für eure Hilfe, das init_done Signal springt nun an!!!
Und zwar lag es daran:
1. Ich Depp hab nich gesehen, dass das Reset Signal negative Logik hat
2. Das user_command_register darf erst kurzzeitig auf 010 stehen, wenn 
die 200µs vorbei sind...ich hatte (oben im VHDL Code) nur bis 13400 
gezählt, muss aber den counter bis 33500 laufen lassen und dann kurz das 
user_command_register auf 010 setzen.

Um die fragen zu beantworten:
> Simulierst Du die DCMs mit?
Ja

> Haben die einen Reset?
Ja, wie oben beschrieben in negativer Logik

> Liegt der Reset dort erstmal drei Takte lang an?
Nein, sollte er?

> Welches Memory Model verwendest Du?
Das Model mit DCM und ohne TB (UG086 Seite 325)

Aber wie gesagt, das Init geht jetzt schonmal (zumindest 
Simulativ)...endlich!!!

Vielen Dank euch schonmal...

Falls mal wieder was ist, meld ich mich...werden sicherlich noch so paar 
Probleme kommen ;)

Viele Grüße

von Duke Scarring (Gast)


Lesenswert?

Karnikel S. schrieb:
>> Liegt der Reset dort erstmal drei Takte lang an?
> Nein, sollte er?

Ja, laut:
http://forums.xilinx.com/t5/Simulation-and-Verification/DCMs-not-locking-in-ISE10-1-03i-ModelSim6-3c/m-p/30115/highlight/true#M283


Karnikel S. schrieb:
>> Welches Memory Model verwendest Du?
> Das Model mit DCM und ohne TB (UG086 Seite 325)
Ich meinte eigentlich das Speichermodel, welches nur zur Simulation 
dient.
Die besseren Modelle scheint es nur in verilog zu geben. Das geht leider 
nicht mit jedem Simulator.

Duke

von Thi L. (flothi)


Lesenswert?

Ich habe meine Simulationen bisher ohne Modell gemacht, einfach weil 
keins vorhanden war und neuschreiben nicht wirklich eine Alternative 
darstellte. Aber man "erkennt" nach einiger Zeit auch, ob die Signale, 
die kommen, logisch sind. ;-)

vg

von Frank S. (karnikel)


Lesenswert?

Hi,

also das mit dem "mindestens 3 Clock Takte muss das Reset auf 1 sein" 
stimmt so nicht ganz. Laut UG086 (Seite 337):
>>"...After the command acknowledge is asserted, the user waits for three
>>clock cycles before sending the next address. This three clock cycle time
>>is the Active-to-Command (tRCD) delay for a read or write command as
>>defined in the memory specification. Subsequent addresses are sent once
>>every two clock cycles for a burst length of four..."
Und da man sowieso 200µs warten muss, bis man überhaupt ein INIT Signal 
senden darf, ist das glaub ich nich kritisch.

Ich hab aber mal wieder ein neues Problem:
Wenn ich das ganze synthetisieren will, meckert der Compiler über meine 
UCF-Datei...er will die richtigen Pfade für die Netze haben.
So weit so gut...bekommt man ja hin die korrekten Pfade einzutippen.
Aber an einer Stelle komme ich nich ganz weiter, weil er sich am Ende 
auf eine Generate Anweisung bezieht.

Der Ursprüngliche Eintrag aus der vom MIG generierten UCF Datei war:
1
NET "main_00/top0/data_path0/data_read_controller0\gen_wr_en*fifo*_wr_en_inst/clk" 
2
TNM_NET = "fifo_waddr_clk";

Was ich zu
1
NET "FIFO_INST/top_00/data_path0/data_read_controller0\gen_wr_en[*].fifo_*_wr_en_inst/clk"
2
TNM_NET = "fifo_waddr_clk";
geändert habe.


Bis "FIFO_INST/top_00/data_path0/data_read_controller0/" sollte auch 
alles soweit stimmen. Aber das was danach kommt muss anscheinend eine 
andere Syntax haben.

Hier mal der VHDL Ausschnitt aus "data_read_controller0" der 
angesprochen werden soll:
1
gen_wr_en: for wr_en_i in 0 to DATA_STROBE_WIDTH-1 generate
2
    fifo_0_wr_en_inst: FIFO_fifo_0_wr_en_0
3
      port map (
4
        clk             => dqs_delayed_col1_n (wr_en_i),
5
        reset           => reset_r,
6
        din             => rst_dqs_div,
7
        rst_dqs_delay_n => rst_dqs_delay_0_n(wr_en_i),
8
        dout            => fifo_0_wr_en(wr_en_i)
9
        );
10
    fifo_1_wr_en_inst: FIFO_fifo_1_wr_en_0
11
      port map (
12
        clk             => dqs_delayed_col0(wr_en_i),
13
        rst_dqs_delay_n => rst_dqs_delay_0_n(wr_en_i),
14
        reset           => reset_r,
15
        din             => rst_dqs_div,
16
        dout            => fifo_1_wr_en(wr_en_i)
17
        );
18
  end generate;

Kann mir einer von euch helfen?

VG Frank

von Thi L. (flothi)


Lesenswert?

Äähm, wieso änderst du den Top-Level von main_00 um? Das sollte 
eigentlich stehen bleiben, da wir uns ja immer noch in den tiefen des 
Controllers befinden - oder hast du ein neues Top-Level eingefügt?

Dann müsste es
1
NET "NEUES_TOPLEVEL/main_00/top0/data_path0/data_read_controller0\gen_wr_en*fifo*_wr_en_inst/clk" 
2
TNM_NET = "fifo_waddr_clk";
 heißen.

VG

von Frank S. (karnikel)


Lesenswert?

Weil es in meiner FIFO_INST keine main_00 gibt, sondern nur die top_00 
und die infrastructure_top0
Die FIFO_INST ist das vom MIG erstellte Top_Level

von Duke Scarring (Gast)


Lesenswert?

Karnikel S. schrieb:
> dqs_delayed_col1_n (wr_en_i),
> dqs_delayed_col0(wr_en_i),

Wo kommen die beiden Takte her? Aus einer DCM? Warum setzt Du die 
constraints nicht auf deren Taktnetze?

Duke

von Christian A. (noeppkes)


Lesenswert?

Hallo Karnickel S.

Ich habe das gleiche Problem.
Ich suche eine DDR2-RAM Anbindung für mein Spartan 3AN Starterkit.
Bist du in der Zwischenzeit schon weitergekommen?
Ich stehe (so wie du hier vor ~3Monaten) genauso noch am Anfang.
Eventuell könnten wir uns austauschen ?

noeppkes ...

Karnikel S. schrieb:
> Hallo,
>
> ich bin ziemlich neu auf dem Gebiet der VHDL-Programmierung und hätte
> gleich mal eine Frage.
>
> Wie genau programmiere ich die Ansteuerung des DDR2 SDRAM's auf meinem
> Xilinx Spartan 3AN Eval-Board?
> Das ganze soll als FIFO aggieren.
> Gibt es da eine definierte Anzahl an Bits, die pro Speicherzugriff
> gespeichert werden muss (kann)? Wie genau schreibe ich meinen Bitvektor
> (z.B. BITVEKTOR(15 downto 0) ) in den RAM?
>
> Umgebung:
> Xilinx ISE 11
> Xilinx Spartan 3AN Eval-Board mit XC3S700AN FPGA
>
> Ich hoffe ich hab alle wichtigen Infos mitgeteilt
>
> Vielen Dank schonmal
>
> Viele Grüße...Karnikel

von Frank S. (karnikel)


Lesenswert?

Hi noeppkes,

also ich habe es aufgegeben, den DDR2-RAM anzusteuern. Habe dann eine 
Lösung mit dem BRAM gefunden.

Was ich zum Ende noch rausbekommen habe ist:
Es wird einfacher sein, den RAM mit einem Softcore (Microblaze oder 
eventuell auch Picoblaze) anzusteuern. Genaueres kann ich dir aber 
leider nich sagen, weil ich mich wie gesagt nich mehr tiefer damit 
beschäftigt habe. Tut mir leid.

Als ich damals das RAM-Ansteuerungsproblem hier zur Diskussion gestellt 
hatte, dachte ich mir aber, dass jemand Sachdienliche Hinweise geben 
kann, oder dass jemand ein Beispielprojekt zur Verfügung stellt.
Vllt. findet sich ja jetz jemand, damit dir evtl. weitergeholfen werden 
kann.

Für Leute, die nich so tief in der Materie drin stecken ist diese 
Ansteuerung ein ziemlich großes Problem, da eine Menge Spezifikationen 
eingehalten werden müssen.
Aber mach dich mal schlau, wie genau das mit dem Micro-/Picoblaze 
funktionieren könnte. Ich glaube dass dadurch viele Probleme gelößt 
werden können.

Viel Erfolg

Karnikel

von Christian A. (noeppkes)


Lesenswert?

Hallo Karnickel S.

vielen dank für deine letzte Nachricht.
Ich kann leider am DDR2 RAM und Spartan 3AN nicht aufgeben, da ich es 
beruflich dringend benötige. Ich habe schon das Problem, dass das Init 
done bei mir erst gar nicht anspringt.
Bei dir hat dies zumindest mal funktioniert. Ich wäre sehr froh, wenn 
ich schon einmal so weit wäre.
Deshalb meine Frage: Kannst du mir das Projekt zur Verfügung stellen.
Ich würde dir dann meine eMail-Adresse geben. Oder vielleicht kannst du 
es ja auch irgendwo zum download ablegen.
Sofern ich mit deinem Projekt weiterkomme, könnte ich es dir wieder zur 
Verfügung stellen.
Ich hoffe auf deine Mithilfe.
noeppkes ...

Karnikel S. schrieb:
> Hi...vielen Dank für eure Hilfe, das init_done Signal springt nun an!!!
> Und zwar lag es daran:
> 1. Ich Depp hab nich gesehen, dass das Reset Signal negative Logik hat
> 2. Das user_command_register darf erst kurzzeitig auf 010 stehen, wenn
> die 200µs vorbei sind...ich hatte (oben im VHDL Code) nur bis 13400
> gezählt, muss aber den counter bis 33500 laufen lassen und dann kurz das
> user_command_register auf 010 setzen.
>
> Um die fragen zu beantworten:
>> Simulierst Du die DCMs mit?
> Ja
>
>> Haben die einen Reset?
> Ja, wie oben beschrieben in negativer Logik
>
>> Liegt der Reset dort erstmal drei Takte lang an?
> Nein, sollte er?
>
>> Welches Memory Model verwendest Du?
> Das Model mit DCM und ohne TB (UG086 Seite 325)
>
> Aber wie gesagt, das Init geht jetzt schonmal (zumindest
> Simulativ)...endlich!!!
>
> Vielen Dank euch schonmal...
>
> Falls mal wieder was ist, meld ich mich...werden sicherlich noch so paar
> Probleme kommen ;)
>
> Viele Grüße

von Frank S. (karnikel)


Angehängte Dateien:

Lesenswert?

Hi,
ich hab dir hier mal mein damaliges Projekt zur Verfügung gestellt. 
Musst du mal schauen, ob du damit klar kommst. Die Initialisierung 
findet im Unterprog "FIFO_control_inst" statt. Ob das so wie es 
funktionieren sollte richtig gelöst ist, kann ich dir nicht sagen.
Ich wünsch dir viel Erfolg weiterhin. Wenn du deine Anteuerung geschafft 
hast, würd ich mich seh über das Projekt freuen, wenn ich es mir 
anschauen könnte.

Grüße

von Christian A. (noeppkes)


Lesenswert?

Hallo Karnickel S.
Danke für dein Projekt.
Habe es gleich mal geladen und versucht zu generieren.
ISE V12.3
Bekomme aber eine Fehlermeldung:
1
ERROR:Xst:2108 - Logic for signal <command_register> is controlled by a clock but does not appear to be a valid sequential description.
2
ERROR:Xst:1431 - Failed to synthesize unit <FIFO_control
Kannst du mir hier weiterhelfen, so dass ich zumindest mal das Projekt 
übersetzen kann ?

Mit welcher ISE hast du gearbeitet (Version ?)
noeppkes ...

Karnikel S. schrieb:
> Hi,
> ich hab dir hier mal mein damaliges Projekt zur Verfügung gestellt.
> Musst du mal schauen, ob du damit klar kommst. Die Initialisierung
> findet im Unterprog "FIFO_control_inst" statt. Ob das so wie es
> funktionieren sollte richtig gelöst ist, kann ich dir nicht sagen.
> Ich wünsch dir viel Erfolg weiterhin. Wenn du deine Anteuerung geschafft
> hast, würd ich mich seh über das Projekt freuen, wenn ich es mir
> anschauen könnte.
>
> Grüße

von Frank S. (karnikel)


Lesenswert?

Hi, also ich nutze die Version ISE 11.5 und eine Antwort auf deine Frage 
findest du hier:
Beitrag "Wie kann ich ''ERROR:Xst:2108'' fixieren?"

Warum der das dann bei mir synthetisiert, weiß ich nicht.

Viele Grüße

von Christian A. (noeppkes)


Lesenswert?

Hallo Karnikel S.

der Fehler lag in der Zeile:
1
if init_done = '1' and falling_edge(clk_i) then

Habe es geändert in:
1
if init_done = '1' then --and falling_edge(clk_i) then

(siehe unten).
Jetzt lässt sich das Projekt übersetzen.

Ich halte dich auf dem laufenden.
noeppkes ...

1
  begin
2
    if falling_edge(clk_i) then
3
      if RESET = '1' then
4
        STATE <= INIT;
5
      else
6
        case STATE is
7
          when INIT =>
8
            if counter = 0 then
9
              STATE <= RECEIVE;
10
              command_register <= "010";
11
            else 
12
              command_register <= "000";
13
              counter <= counter - 1;
14
            end if;
15
          when RECEIVE =>
16
            command_register <= "000";
17
            if init_done = '1' then --and falling_edge(clk_i) then
18
              command_register <= "100";
19
              input_adress <= "0000000000000000000000000";
20
            end if;
21
            if cmd_ack = '1' then
22
              --if rising_edge(clk90_i) then
23
              input_data <= "10010010010010011001001001001001";
24
              --end if;
25
            end if;
26
        end case;
27
      end if;
28
    end if;
29
  end process;

von Christian A. (noeppkes)


Lesenswert?

Hallo Karnikel.

Karnikel S. schrieb:
> ... Ich wünsch dir viel Erfolg weiterhin. Wenn du deine Anteuerung geschafft
> hast, würd ich mich seh über das Projekt freuen, wenn ich es mir
> anschauen könnte.
> ...

Du warst so nahe an der Lösung dran.

Sofern mich meine Augen nicht täuschen, habe ich es jetzt mal mit einer 
Adresse schreiben / lesen geschafft.

Ich habe das Schreiben und lesen noch mit in die StateMachine eingebaut.
Das Ergebnis stimmt.

Würde aber gerne noch wissen was bei dir im Projekt das FIFO_INST 
(FIFO.xco) ist.
Das muss irgend eine MIG-Konfig-Datei sein.
Diesen "Quellcode, bzw. die Einstellungen für die MIG würde ich noch 
benötigen, damit ich auch definitiv mit dem Projekt weitermachen kann.

noeppkes ...

von Frank S. (karnikel)


Lesenswert?

Hi...
also ich kann hier gerne mal ein HowTo für den MIG schreiben, wenn du 
das meinst...aber aktuell is meine Zeit ziemlich begrenzt...reichts wenn 
ich das Ende Februar mal mache?

von Christian A. (noeppkes)


Lesenswert?

Hallo.

Karnikel S. schrieb:
> Hi...
> also ich kann hier gerne mal ein HowTo für den MIG schreiben, wenn du
> das meinst...aber aktuell is meine Zeit ziemlich begrenzt...reichts wenn
> ich das Ende Februar mal mache?
Gerne. Das wäre super.Ich mache bis dahin mal weiter.
Werde jetzt mal versuchen mehrere Adressen zu schreiben und auch zu 
lesen.

noeppkes ...

von Frank S. (karnikel)



Lesenswert?

So da bin ich wieder...
Im Anhang findest du ein PDF in dem ich mal ein HowTo nach besten Wissen 
und Gewissen geschrieben habe. Korrekturen arbeite ich gerne darin ein.

PS: Wie weit bist du mittlerweile eigentlich?

von Anguel S. (anguel)


Lesenswert?

Frank S. schrieb:
> Im Anhang findest du ein PDF in dem ich mal ein HowTo nach besten Wissen
> und Gewissen geschrieben habe. Korrekturen arbeite ich gerne darin ein.

Hm, funktioniert denn das Ganze, wenn du so die Pins umdefinierst? 
Soweit ich weiß setzt MIG nicht nur Pin-Constraints sondern auch andere 
Location-Constraints intern im Design, damit das Timing hinkommt. Wenn 
Du nun aber die ganzen Pins umänderst, kommen die Timings evtl. nicht 
mehr hin...

von Christian A. (noeppkes)


Lesenswert?

Hallo Frnak.

Danke für die Anleitung.
Ist ja sehr ausführlich beschrieben.

Wie sieht es aus mit der Frage von Anguel. Pins umdefinieren usw ...

Ich habe in der Zwischenzeit leider nicht mehr weitermachen können.
Nachdem ich es geschafft habe 1 Byte korrekt zu schreiben und zu lesen, 
müsste ich mich anderen Projekten widmen.
Ich hoffe aber es geht demnächst weiter.

Ich halte dich auf dem "laufenden".

noeppkes ...

von Thi L. (flothi)


Lesenswert?

Anguel S. schrieb:
> Hm, funktioniert denn das Ganze, wenn du so die Pins umdefinierst?
> Soweit ich weiß setzt MIG nicht nur Pin-Constraints sondern auch andere
> Location-Constraints intern im Design, damit das Timing hinkommt.

Dafuer kannst du im MIG die UCF-File updaten (IIRC dritter oder vierter 
Auswahlpunkt ganz zu Beginn); laut Xilinx-Aussage soll dadurch dann das 
Design (auch die Lokalisierung der Slices) angepasst werden.

VG

von Anguel S. (anguel)


Lesenswert?

Thi Lo schrieb:
> Dafuer kannst du im MIG die UCF-File updaten (IIRC dritter oder vierter
> Auswahlpunkt ganz zu Beginn); laut Xilinx-Aussage soll dadurch dann das
> Design (auch die Lokalisierung der Slices) angepasst werden.

Stimmt, da war ja diese Option - es gibt so viele Sachen, dass man sie 
dann wieder vergisst. Danke für den Tipp!

von Uwe B. (derexponent)


Angehängte Dateien:

Lesenswert?

Hi @All,

-ich habe das Projekt von Frank S. mal weitergemacht

im Anhang das Projekt für ISE 11.1 und einem Spartan-3A Board
(XC3S700A) in VHDL

im Moment funktioniert der INIT vom RAM,
das schreiben eines 32Bit Wortes und das Lesen des Wortes
(es wird nur Adresse 0 beschrieben)

beim lesen kippt ab und zu noch ein Bit :-(

...muss aber dazusagen , das ist eines meiner ersten
FPGA Projekte ...also drückt ein Auge zu falls
es noch wie von einem NOOB geschrieben ist

werd noch versuchen den Lesefehler zu finden
und die anderen Adressen zu beschreiben

falls jemand Anregungen dazu hat oder Fehler findet...
immer her damit

Gruss Uwe

von Uwe B. (derexponent)


Lesenswert?

nachtrag,

-ich hab das Projekt DDR2-RAM jetzt abgeschlossen :

-das Read und Write über den kompletten Adressraum
funktioniert...mit der Einschränkung das ich
der Einfachheit halber nur 32MByte (statt 64MByte)
benutze

-wer Interrese am Code hat...einfach melden

Gruss Uwe

von Frank S. (karnikel)


Lesenswert?

Hi Uwe,

feine Sache, dass du es geschafft hast. Läuft das Programmierte auch in 
Echtzeit auf der Hardware oder nur simulativ?

Fänds gut, wenn du dein Progrämmchen für die Allgemeinheit hier im Forum 
bereitstellen könntest. Weil es immer wieder Leute geben wird die sich 
mit dem RAM-Anteuerungsproblem rumschlagen werden und mit diesem Thread 
endlich mal eine fundamentale Grundlage dazu hätten.

Gruß Karnikel

von Christian A. (noeppkes)


Lesenswert?

Hallo Uwe.

Uwe B. schrieb:
> nachtrag,
>
> -ich hab das Projekt DDR2-RAM jetzt abgeschlossen :
>
> -das Read und Write über den kompletten Adressraum
> funktioniert...mit der Einschränkung das ich
> der Einfachheit halber nur 32MByte (statt 64MByte)
> benutze

(Warum? gibt es mit dem 64MB grössere Probleme?)

>
> -wer Interrese am Code hat...einfach melden

Finde ich super. endlich mal ein Projekt das funktioniert. Ich habe 
grosses Interesse daran. Bitte stell doch den Code wie schon von Frank 
S. vorgeschlagen wurde doch hier ein.
Ich würde ihn sehr gerne haben.

>
> Gruss Uwe

Gruss noeppkes ...

von Uwe B. (derexponent)


Angehängte Dateien:

Lesenswert?

Hi ihr beiden,

-im Anhang das DDR2-RAM Projekt

es ist ein Text-File dabei mit ein paar Erklärungen


@Frank S,
-ich habe das Programm hier auf einem Spartan-3A Board
(XC3S700A-FGG484) am laufen

kann im Moment keine Fehler mehr sehen,
vielleicht findet ihr noch welche :-)

@Christian Armbruster,
-die MIG Einstellung lautet "Burst_Mode=4"
also schreibt er immer 4x16bit Daten
(das geht beim DDR2 anscheinend nicht anders)

-in meiner Ansteuerung übergebe ich beim "WRITE"
aber immer nur 1x32bit Daten

das bedeutet er schreibt mir mein Datenwort 2mal ins RAM
in 4 aufeinanderfolgenden Zellen

-ich hatte jetzt keine Lust das ganze umzuschreiben
(weil ich das erst am Ende gemerkt habe) und begnüge
mich halt mit "nur" 32MByte RAM :-)

-wenn ihr wollt könnt ihr das ganze ja noch abändern
und "perfektionieren"

-und wie gesagt...ist eins meiner ersten VHDL-Projekte
habt Mitleid falls manches "übers Eck" gelöst ist :-)

Gruss Uwe

von Uwe B. (derexponent)


Lesenswert?

Hi,

...kein Feedback ?

- ist das jetzt ein gutes oder schlechtes Zeichen ?

- wäre über Hinweise (brauchbar/unbrauchbar)
  oder Verbesserungsvorschläge dankbar

Gruss und schönes WE ... Uwe

von Frank S. (karnikel)


Lesenswert?

Moin,
> ...kein Feedback ?
> - ist das jetzt ein gutes oder schlechtes Zeichen ?

Das ist denk ich mal ein gutes Zeichen...weil negative Kritik kommt ja 
meistens nur wenn etwas schlecht is :)

Ne mal im ernst...ich konnte mir dein Progrämmchen aus zeittechnischen 
Gründen noch nicht genauer anschauen...vllt. liegts auch daran, dass ich 
die Ansteuerung nicht mehr benötige.
Ich denke mal, sobald jemand wiedereinmal das Ansteuerungsproblem hat 
und mithilfe dieses Threads erheblich vorran kommt, werden (so hoffe 
ich) Verbesserungsvorschläge kommen...

Ich wollt aber mal ein fettes Dankeschön und großen Lob aussprechen, für 
alle die, die daran mitgewirkt haben, dieses Problem in seinen 
Grundlagen zu lösen! Es ist schwierig im Netz etwas zusammenhängendes 
darüber zu finden, was mit diesem Thread aber denk ich mal behoben ist.

So denn...bis bald und schönes WE

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Ich habe den Thread verfolgt.

Konnte auch noch nicht testen.


Was mir noch fehlt ist, was kanm ich mit dem RAM machen?

Hat jemand ein Beispielprojekt mit einem Softcore oder Videospeicher 
oder etwas ähnlichen?

Es klingt etwas komisch.
Ich habe mich gezwungen ohne externen RAM auszukommen, weil ich keinen 
nutzen konnte. Da fällt es mir schwer auch aus Timing Gründen, wann die 
Werte des externen RAMs gültig sind. Diese müssen erst aus dem exteren 
RAM geholt werden. Es ist sicher ganz einfach, doch im Moment habe ich 
einen Knoten.

von Uwe B. (derexponent)


Lesenswert?

Hi René,

-zur Anwendung :

-ich hab vor ein Bild "JPG" ins externe NOR-Flash zu schreiben,
beim starten des FPGA dann das Bild ins RAM zu laden
und den Inhalt vom RAM per VGA anzeigen

-vom Flash-lesen funktioniert
(war gerade ein "Schnellschuss" nach Datenblatt)

-was mir noch fehlt ist die Wandlung eines Bildes
in Daten und das schreiben ins Flash

da werd ich wohl das "parallel Flash-Programmer Tool"
per RS232 von Xilinx nehmen, das beim Board dabei war

und zu deiner Frage :

schau mal im MIG-User-Guide (ug086.pdf)
die Daten sind gueltig, wenn das Signal "data_valid"
auf Hi-Pegel geht

Gruss Uwe

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Hallo,

Uwe die Wandlung eines Bildes habe ich ganz zufällig schon vorbereitet.

Ich habe einen Jpeg decoder parat. Ohne Witz.
Mindestens ein halbes Jahr Arbeit. Ich habe vor kurzem den Code 
überarbeitet.

Jpeg Marken erkennen. Quantisierung IDFT  und und..........



Der läuft in der Simulation und ist fitbar. Der Platz im Internen RAM 
ist nicht zum Darstellen ausreichend.

Ich hätte esvor als unter der BSD Lizenz zu stellen. Das es auch 
gewerblich nutzbar ist. Wenn du auch deinen Code unter BSD stellen 
würdest könnten wir zusammen arbeiten.

von Uwe B. (derexponent)


Lesenswert?

Hi René D.,

-über die Wandlung des Bildes mache ich mir
die wenigsten Gedanken :-)

-ich werde das Bild mit einem PC-Programm wandeln
(Auflösung 640x480 mit 12Bit Farbtiefe)
(dafür brauch ich keinen Tag)
...wahrscheinlich gibts da sogar schon ein fertiges Programm

-aber auf der VHDL Seite bin ich noch Anfänger...
...da dauert alles etwas länger

Danke trotzdem

von René D. (Firma: www.dossmatik.de) (dose)


Angehängte Dateien:

Lesenswert?

Ich hänge mal zur Vollständigkeit ein Diagramm an.

Momentan bin ich bei Version zwei. Es gibt noch so drei bis vier 
kleinere Baustellen. Bei Jepg muss man viel Vorwissen haben und die 
Erleuchtungen kommen immer später.



Rene

von Uwe B. (derexponent)


Lesenswert?

Hi nochmal,

-ich glaube wir reden aneinander vorbei ...

...ich will nicht den FPGA das wandeln des Bildes machen
lassen, sondern ich werde die Bild-Daten manuell vorher
z.B. mit GIMP in die Richtige Auflösung bringen
und dann mit einem selbst geschriebenen PC-Programm
die Farbtiefe auf 12Bit reduzieren

-diese Bild-Roh-Daten
(es sind dann für ein Bild 640x480x12 = 460kByte)
werde ich im Flash bzw. RAM ablegen

-dann kann die VGA-Unit die Daten direkt 1:1
auslesen und anzeigen

-der FPGA muss also gar nichts mehr umrechnen
oder wandeln

...so wie ich das sehe haben wir also
zwei Unterschiedliche Projekte

(wobei deines für mich im Moment ne Nummer zu gross wäre)

und P.S. wir sind etwas "Off Topic" mit dem ganzen :-)

Gruss Uwe

von Christian A. (noeppkes)


Lesenswert?

Uwe B. schrieb:
> Hi,
>
> ...kein Feedback ?
>
> - ist das jetzt ein gutes oder schlechtes Zeichen ?
>
> - wäre über Hinweise (brauchbar/unbrauchbar)
>   oder Verbesserungsvorschläge dankbar
>
> Gruss und schönes WE ... Uwe

Hallo Uwe.

Ich hatte gleich die Zeit gefunden dein Projekt auszuprobieren.
!! Klasse !! Hat auf Anhieb funktioniert.
Bin gerade dabei, dein Projekt im mein TFT-Display-Projekt einzubauen.
D.h. Schreiben / Lesen von einer MCU in das DDR-Ram und gleichzeitg das 
Display darstellen.
Das ganze funktioniert schon mit dem Spartan-3 Board (hat aber nur 1MB 
SRAM).
Wenn ich dann 32MB zur Verfügung habe, macht es direkt Spass.
(MEhrere pages etc.)

Wo ich im Moment noch Probleme habe ist, dass ich nur 16Bit von der MCU 
her schreiben kann. Da das CL4 ja 64 Bit unterstützt, würden bei mir 
noch einmal die Hälfte an DDR-Ram "flöten" gehen . (Sehe ich das 
richtig?). Somit habe ich nur noch 16MB. Wenn du hier noch etwas tun 
könntest, wäre es Superklasse.

Also noch einmal: Hut ab. Lässt sich soweit verwenden.
Melde mich noch einmal, wenn ich dein Projekt in meines eingebunden 
habe.

Bis dahin ...
(Halte mich auf dem laufenden hier, wenn es von deiner Seite aus was 
neues gibt. Vielleicht machst du ja auch noch die 64 MB voll.)

noeppkes

von Uwe B. (derexponent)


Lesenswert?

Hi noeppkes,

-schön das es bei dir funktioniert...

...und du hast recht, wenn du nur 16Bit Daten hast,
geht der Speicherplatz runter auf 16MByte

-bei einem einzelnen Byte wird es noch schlimmer :-(
(nur 8MByte nutzbare Daten)

-da ich die DDR2_Control für mein aktuelles
Projekt sowieso ändern muss, versuch ich mal
ob ich das verbessern kann

Gruss Uwe

von Christian A. (noeppkes)


Lesenswert?

Hallo Uwe.

Danke für deine Antwort.

Mein Problem geht noch ein bisschen weiter.
Da der Controller bekanntlich ja 8, 16 (andere auch 32 oder sogar 64) 
Bit schreiben können, stehe ich vor dem nächsten Problem.

Wie schafft man es, dass die vollen 64 MB ausgenutzt werden, obwohl man 
mit 8 bzw. mit 16 Bit ins DDR-Ram schreibt.

Also falls du da was machen würdest, könntest du das gleich etwas 
flexibler halten. Die normalen SRAM's haben hdafür verschiedene 
WR-Signale.

Gruss noeppkes ...

von Thi L. (flothi)


Lesenswert?

Ich bastel zur Zeit an einer Lösung mit FiFo-Speichern; allerdings ist 
das noch nicht so ganz sauber. Ich denke mal, die könnte man 
entsprechend befüllen, oder?

VG

von Uwe B. (derexponent)


Lesenswert?

@noeppkes,

-wenn auch 8bit funktionieren sollen,
muss sogar die Adressleitung um ein Bit vergrößert werden !

ich habe an folgendes gedacht :
(nur mal so ins blaue)

das jetzige DDR2_Control abändern
und in eine reine DDR2-Read/Write Unit umbauen

mit folgenden zusätzlichen Signalen :

ROW_ADR (13Bit)
COL_ADR (11Bit) -> 1 Bit mehr, um jedes Byte adressieren zu können
BANK_ADR (2Bit)

DATA_IN (32Bit) -> Nutzdaten ab LSB auffüllen
DATA_OUT (32Bit) -> Nutzdaten ab LSB auslesen

DATA_WIDTH (2Bit) -> um 8,16,32 Bit Read/Write zu unterscheiden

DDR_BUSY (1Bit) -> info ob ein Read/Write prozess läuft
WRITE_ENABLE (1Bit)
READ_ENABLE (1Bit)

------------------------------

wie und ob das ganze funktioniert ?!?

vor allem der User muss sehr genau auf die COL_ADR
aufpassen ... sonst kommt Datenmüll raus

Gruss Uwe

von Christian A. (noeppkes)


Lesenswert?

Hallo Uwe.

Danke für die Nachricht.

Hört sich ja gut an. Die Signale könnte man erzeugen.

Ich habe von der Controllerseite her entwerder ein SRAM-Interface oder 
ein SDRAM-Interface. SRAM wäre mir am liebsten. Ist einfacher zu 
handeln. Die benötigten Signale dürften sich auch relativ einfach 
ableiten lassen.

Der Hintergrund ist: Ich möchte das DDR-RAM nicht nur für die 
Darstellung des Display's nutzen, sondern auch gleichzeitig als Speicher 
für den Controller. Daher 8, 16 und ev. auch 32 Bit.

Wäre toll wenn das ginge.

noeppkes ...

von fpga greenhorn (Gast)


Lesenswert?

Hi,

ich bin neu auf dem Gebiet der fpga's, das vorweg.
Aber war so mutig deinen Code mal aus zuprobieren. Kann auch keine 
Fehler mehr entdecken...;)
Und ich hatte mal einen Traum...Entwickel deine eigene CPU :)
Das ist jetzt möglich. Unglaublich :)
Das ist jetzt eine Wochen her. Als Softwareentwickler habe ich mich 
erstmal im bekannten Umfeld bewegt und einen kleinen Compiler 
geschrieben.
Auf Hardwareseite habe ich bis dato: ProgrammCounter, Blockram als Rom 
für das Programm, sowie acht Register, Multiplikator, und Steuerung für 
die Befehle...Der Compiler Output ist eine blockram-init Datei für 
Einfaches: Compilieren - Simulieren - (doch noch Studieren?)
Soweit so gut, lange Rede fast kein Sinn: Ich versuche nun deinen Code 
als Ram für meine Cpu zu integrieren. Mh...da gab es doch was mit 
Clock-Domains, was nicht Gutes...oder löst der Fifo den du benutzt etwa 
dieses Problem?  Wenn ja sind die Daten auf data_out schon gepuffert?. 
Wie würdest du einen Datenbus am besten anschließen und steuern?

 Gruß Jonas

von Uwe B. (derexponent)


Angehängte Dateien:

Lesenswert?

Hi Jonas,

-ich bin auch noch ein Greenhorn in VHDL,
mit deinen Fragen bin ich überfordert :-(
SORRY

@All :

-ich habe den Code jetzt erweitert und versuche
das ganze RAM zu nutzen

-dafür muss ich 2 Datenworte pro Zykus (je 32Bit)
schreiben/auslesen

-das schreiben funktioniert ohne Probleme
aber beim Read habe ich einen Fehler :

-das letzte Lo-Nibble vom 1ten Wort
wird ab und zu falsch gelesen
(also nur 4Bit von einem 32Bit Wort stimmen nicht)

-das 2te Word (32Bit) ist immer komplett OK

...ich kann mir das ganze nicht erklären
weil ja der Übergabevector 32Bit breit ist,
wie können da 4Bit davon nicht stimmen ??

-ich komme mit dem Timing-Diagramm im User-Guide (ug086.pdf Seite 333)
nicht wirklich klar

-ich weiss nicht ab wann die Daten VALID sind
und auf welche Flanke ich diese abholen muss/kann
(im Moment mache ich es auf der Lo-Flanke vom Clk90-Signal)

im Anhang das komplette Projekt

falls jemand lust hat und über das Timing besser bescheid weis,
wäre ich für Hilfe dankbar

Ich arbeite mit Burst_Len=4 und einer Burst Anzahl von 1
(siehe PDF : ich will die Daten D0,D1 + D2,D3 lesen)

Gruss Uwe

von PittyJ (Gast)


Lesenswert?

Ich habe mal dein Projekt genommen und auf dem Spartan 3AN Board zum 
Laufen gebracht. Ich erhalte auch diese Bitfehler.
Falls da schon jemand den Fehler gefunden hat, wäre ich über eine 
Korrektur dankbar.

von Uwe B. (derexponent)


Lesenswert?

Hi PittyJ,

-hab mir schon gedacht das es ein "generelles" Problem
von dem Code ist

-ich hab das Thema DDR2-RAM beiseite geschoben
(ist einfach zu kompliziert für einen Newbie)

-das Parallele-Flash war dagegen ein Klax
(da braucht man halt auch nicht so ein Timing gezuppel zu beachten)

-auch das einbinden der 8bit CPU (Picoblaze) -> NULL Probleme

-ich habe auch keinen brauchbaren "fertigen" Code für DDR2 gesehen,
mit dem ich vergleichen könnte

-aber nur internen RAM zu verwenden ist auch blöd
(einfach zu klein für manche Dinge)

-vielleicht findet sich noch jemand mit mehr Sachverstand,
der helfen kann

P.S. da ich von der Software-Seite komme, vermisse ich
das debuggen (auf der Hardware) und komme
nur mit der Simulation einfach nicht weiter
(zumal es da einwandfrei funktioniert :-(

Gruss Uwe

von Rudolph (Gast)


Lesenswert?

Bei der Implementierung müssen bestimmte Implemetierungs-Properties 
gesetzt sein. Welche das sind, kann man aus dem MIG Beispieldesign 
rauslesen. Stimmen die nicht, läuft das Design zwar durch die Synthese 
und P&R, ist aber nicht richtig implementiert. Das muss man im 
FPGA-Editor nachprüfen, wie in UG086 im Kapitel "Debugging the Spartan-3 
FPGA Design" beschrieben. Vergleiche auch AR# 25245 und AR# 31107. Wenn 
das nicht stimmt, läuft es in Hardware nicht richtig, obwohl die 
funktionale Simulation stimmt.

Uwe B. schrieb:
> P.S. da ich von der Software-Seite komme, vermisse ich
> das debuggen (auf der Hardware) und komme
> nur mit der Simulation einfach nicht weiter
> (zumal es da einwandfrei funktioniert :-(

Chipscope ist Dir aber ein Begriff?

von Uwe B. (derexponent)


Angehängte Dateien:

Lesenswert?

Hi Rudolph,

-du hattest recht...es waren nur die Einträge im UCF-File vom DDR2 
falsch

-da ich von dem ganzen keine Ahnung habe,
hatte ich die ganze Zeit die ToDo von Frank S. benutzt
um das UCF anzupassen

ABER !! da werden nur die falschen FPGA-Pins den richtigen zugeordnet...
...die ganzen LUT locations passen dann natürlich nicht mehr dazu

...ich habe jetzt das Referenz-Design von Xilinx benutzt
(für Spartan 3A Boards) da passen die LOC einträge schon

-im gleichen Zuge (weil ich auf ISE 13.1 umgestiegen bin,
habe ich nochmal selbst per MIG die notwendigen Files erstellen lassen
(leider kann ich diese nur in Verilog erzeugen...keine Ahnung warum)

und siehe da ...... keine Fehler mehr !!

die Hardware schreibt jetzt 16 Datenwerte (je 64Bit)
ins RAM...und das lesen funktioniert auch ohne Probleme

also....wie immer, kleiner Fehler , große Wirkung

das Projekt ist im Anhang, wer damit weitermachen will...
viel Spass damit...eine Readme ist dabei

Gruss Uwe

von Uwe B. (derexponent)


Lesenswert?

Hi nochmal,

-vielleicht nochmal eine Frage am Rande....

im original UCF-File von Xilinx gibts diesen Eintrag :
1
##############################################################################################################
2
## Area Group Constraint For tap_dly and cal_ctl module.                                                   
3
##############################################################################################################
4
5
6
INST "INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/cal_ctl0" AREA_GROUP = cal_ctl;
7
INST "INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0" AREA_GROUP = cal_ctl;
8
AREA_GROUP "cal_ctl" RANGE = SLICE_X26Y8:SLICE_X37Y21;
9
AREA_GROUP "cal_ctl" GROUP = CLOSED;

ISE meckert mir aber an, das er die beiden "Netze ?"
(cal_ctl0 und tap_dly0) nicht finden kann...

hat jemand eine Ahnung was das ist, bzw wie ich das fixen kann
...ich hab die Zeilen jetzt einfach auskommentiert
(würde aber gerne Wissen was es damit aufsich hat)

Gruss Uwe

von Rudolph (Gast)


Lesenswert?

Die Zeilen
1
INST "INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/cal_ctl0" AREA_GROUP = cal_ctl;
2
INST "INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0" AREA_GROUP = cal_ctl;
bezeichnen sozusagen einen Pfad durch die Design-Hierarchy zu den 
Elementen, die platziert werden sollen. Dieser ist "absolut" und damit 
designabhängig, hier ist "INST_DDR2_RAM_CORE" als Top-Entity angenommen. 
Du musst diese Einträge also auf dein Design bzw. deine Design-Hierarchy 
anpassen. Wenn ich mich recht erinnere gabs auch die Möglichkeit 
"relative Pfade" anzugeben, in etwa in dieser Form:
1
INST "*/infrastructure_top0/cal_top0/cal_ctl0" AREA_GROUP = cal_ctl;
Für die Syntax leg ich jetzt aber meine Hand nicht ins Feuer.

von Uwe B. (derexponent)


Lesenswert?

Hi Rudolph,

-Danke für den Hinweis...aber die Pfade
habe ich schon angepasst
(das Top-Entity vom MIG lautet "INST_DDR2_RAM_CORE"

der original Eintrag von Xilinx lautet :
1
INST "infrastructure_top0/cal_top0/cal_ctl0" AREA_GROUP = cal_ctl;

die Pfadänderung musste ich vorher schon
an vielen Stellen im UCF-File machen

ich habe jetzt mit dem FPGA-Editor versucht das Element
"tap_dly0" zu finden

wenn ich nach "*tap_dly0*" suche bekomme ich
bei den Netzen die Treffer :
1
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/flop1<0>"
2
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/flop1<1>"
3
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/flop1<2>"
4
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/flop1<3>"
5
usw bis
6
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/flop1<31>"
7
und
8
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/tap<0>"
9
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/tap<1>"
10
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/tap<2>"
11
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/tap<3>"
12
usw bis
13
"INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/tap<30>"

ich habe danach den Eintrag im UCF wie folgt abgeändert :
1
INST "INST_DDR2_RAM_CORE/infrastructure_top0/cal_top0/tap_dly0/*" AREA_GROUP = cal_ctl;

damit läuft das Place&Route jetzt ohne Fehlermeldung durch...
...aber ob das richtig ist ??

na ja...egal...Danke trotzdem für deine Hilfe

Gruss Uwe

von Christian A. (noeppkes)


Lesenswert?

Hallo Uwe B.

Ich versuche mich auch gerade mit DDR2/3. Welche Lesezeiten kannst du 
dem Design "entlocken"?
Genauer gesagt würde micht interessieren, (wenn du 1 Datensatz (16 Bit) 
aus dem DDR2 liest) wie lange es von der Anforderung bis zum entgültigen 
Bereitstellen der Daten dauert.

noeppkes ...

von Uwe B. (derexponent)


Lesenswert?

Hi noeppkes,

-ich kann es per Oszi nicht messen
 aber mit einer Änderung im Code habe ich mir die
 notwendigen Taktzyklen an den LEDs ausgeben lassen

-Hinweis : es werden in meinem Code immer 64Bit geschrieben
 oder gelesen (anders hab ich es nicht hinbekommen)

 Ergebnis :

 - zum schreiben eines einzelnen 64Bit Wertes : 25 Clockzyklen
 - zum lesen eines einzelnen 64Bit Wertes : 22 Clockzyklen

 bei 133,33MHz Clockfrequenz sind das dann :

 - ca. 188 ns zum schreiben
 - ca. 165 ns zum lesen

Gruss Uwe

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.