Hat jemand hier im Forum ein Nexys4-DDR Board in Betrieb? Ich hätte ein
paar Fragen bzw. Beobachtungen zur Nutzung des DDR2 Speichers; dabei
handelts es sich um ein MT47H64M16 mit 64 Meg x 16 Konfiguration und
einer eingestellten Burstlänge von 8. Ich benutze ISE 14.7.
1. Simulation:
Der per MIG erzeugte DDR2 Core lässt sich mit ISim nicht simulieren,
der Simulator stoppt mit einem Fehler "Signal phy_dout index is out of
bound." Tatsächlich findet sich in der MIG-Doku der Hinweis, dass nur
ModelSim unterstützt wird. Eine ModelSim Lizenz kommt für mein
Hobbyprojekt nicht in Frage - kann ich evtl. einen anderen (freien)
Simulator einsetzen?
2. Erstellen einer Netzliste:
Es muss wohl möglich sein, aus den per MIG generierten Sourcen eine
Netlist-Datei einmalig zu erstellen und in das Projekt einzubinden. Kann
jemand das Vorgehen dazu kurz skizzieren?
(BTW: Die von Digilent in
https://reference.digilentinc.com/_media/nexys4-ddr:ram2ddr_refcomp.zip
bereitgestellte Datei hat einen Bug).
3. Timing:
Digilent gibt die Cycle-Time
(https://reference.digilentinc.com/nexys4-ddr:sram) mit 210 (tRC) bzw.
260 (tWR) ns an. Tatsächlich gemessen habe ich für den Lesezyklus ca.
350 ns, mit gelegentlichen Ausreissern (> 400 ns) nach oben (vom Anlegen
des CEN Signals bis zur Assertion von RD_DATA_VALID des MIG UIs - bei
Verwendung des RAM2DDRxadc Moduls von Digilent). Die Zeit für einen
Schreibzyklus kann ich mit meinem Mitteln leider nicht messen; sie
scheint aber unter der fürs Lesen zu liegen.
Hat evtl. jemand die Zeit für einen Schreibzyklus gemessen oder per
Simulation ermittelt?
Meine Anwendung erzeugt 2x16 bit (Audio-)Daten mit 1 MSps/s die per
FFT analysiert und später auf 200 kSps/s reduziert ausgegeben werden.
Bei den oben dargestellten Zugriffszeiten muss ich die aus dem RAM
gelesenen Daten (Burstlänge 8) in einem FiFo zwischenspeichern.
Hinsichtlich des Timings ist der Ersatz von SRAM durch DDR2 ein eher
enttäuschender Rückschritt.
Nur so nebenbei: Digilent umgeht in seinem Referenzdesign für das
Board mögliche Timingprobleme durch eine fest eingestellte Wartezeit von
1200 ns (sic!) vor Ausgabe des ACK-Signals.
Gruß,
Burkhard
Ich habe auch ein Nexys4, aber die Variante mit dem PSRAM.
Bis zum externen Speicher bin ich aber noch nicht vorgedrungen...
Burkhard K. schrieb:> 1. Simulation:> Der per MIG erzeugte DDR2 Core lässt sich mit ISim nicht simulieren,> der Simulator stoppt mit einem Fehler "Signal phy_dout index is out of> bound."
Erzeugt der MIG 'normale' Netzlisten zum Simulieren oder irgendwas
verschüsseltes/proprietäres?
> Tatsächlich findet sich in der MIG-Doku der Hinweis, dass nur> ModelSim unterstützt wird. Eine ModelSim Lizenz kommt für mein> Hobbyprojekt nicht in Frage - kann ich evtl. einen anderen (freien)> Simulator einsetzen?
Du kannst GHDL probieren. Ich weiß nicht, ob es bei Altera noch
ModelSim-AE gibt. Aber der Fehler sieht nach einem kaputten Design bzw.
kaputtem Modell aus. Da sollte ein anderer Simulator die gleiche
Fehlermeldung bringen.
Duke
Duke Scarring schrieb:> Erzeugt der MIG 'normale' Netzlisten zum Simulieren oder irgendwas> verschüsseltes/proprietäres?
Eine *.ngc Datei kann ich nicht finden, dafür aber ein Verzeichns
"user_design" mit Verilog Sourcen, die bei der Synthese gelesen werden.
Siehe auch meine zweite Frage zur Erzeugung einer Netlist-Datei.
>
Aber der Fehler sieht nach einem kaputten Design bzw.
> kaputtem Modell aus. Da sollte ein anderer Simulator die gleiche> Fehlermeldung bringen.
Zu dieser Vermutung würden die ca. 2300 Warnungen passen, mit denen mich
Synthese und Implementation überschütten.
Burkhard
Hallo Burkhard,
Habe auch ein Nexys4 Board und möchte den DDR2-Ram ansteuern.
Wenn ich es richtig lese hast du es geschafft den Ram anzusteuern,
zumindest als SRAM.
Dabei soll Vivado 15.4 genutzt werden.
Wie hast du dass geschafft?
Ich habe nun verschiedene Varianten versucht:
1. Mit MIG7 das DDR-Interface so wie hier:
https://reference.digilentinc.com/nexys4-ddr:sram
vorgesehen einzustellen und den Ram als DDR-Ram zu nutzen.
2. Ein Demoprojekt welches DDR-Ram nutzt als Basys für mein eigenes
Projekt zu nutzen.
3. Die auf der Seite vorgesehene refferenz Komponente nutzen, sie
richtig verbinden:
z.b. mit PLL für clk_200MHz_i und einem Ablauf bei dem ich versuche den
RAM so wie es mit sinvoll erscheint anzusprechen:
1
RD_DATA:process(CLK100MHZ)
2
variablecounter:integer;
3
variablecounter_langsam:integer;
4
begin
5
ifrising_edge(CLK100MHZ)then
6
counter:=counter+1;
7
ifcounter=200000000then
8
counter:=0;
9
counter_langsam:=counter_langsam+1;
10
ifcounter_langsam=11then
11
counter_langsam:=0;
12
endif;
13
endif;
14
ifcounter_langsam=0then
15
LED<="0000000000000001";
16
schreibdaten<=x"0FA5";
17
cen<='0';
18
read_en<='0';
19
write_en<='0';
20
ub<='0';
21
lb<='0';
22
elsifcounter_langsam=1then
23
LED<="0000000000000010";
24
schreibdaten<=x"0FA5";
25
cen<='0';
26
read_en<='0';
27
write_en<='1';
28
ub<='1';
29
lb<='1';
30
elsifcounter_langsam=2then
31
LED<="0000000000000100";
32
schreibdaten<=x"0FA5";
33
cen<='1';
34
read_en<='0';
35
write_en<='1';
36
ub<='1';
37
lb<='1';
38
elsifcounter_langsam=3then
39
LED<="0000000000001000";
40
schreibdaten<=x"0000";
41
cen<='0';
42
read_en<='0';
43
write_en<='1';
44
ub<='1';
45
lb<='1';
46
elsifcounter_langsam=4then
47
LED<="0000000000010000";
48
schreibdaten<=x"0000";
49
cen<='0';
50
read_en<='0';
51
write_en<='0';
52
ub<='0';
53
lb<='0';
54
elsifcounter_langsam=5then
55
LED<="0000000000100000";
56
schreibdaten<=x"0000";
57
cen<='0';
58
read_en<='1';
59
write_en<='0';
60
ub<='1';
61
lb<='1';
62
elsifcounter_langsam=6then
63
LED<="0000000001000000";
64
schreibdaten<=x"0000";
65
cen<='1';
66
read_en<='1';
67
write_en<='0';
68
ub<='1';
69
lb<='1';
70
elsifcounter_langsam=7then
71
LED<="0000000010000000";
72
schreibdaten<=x"0000";
73
cen<='1';
74
read_en<='1';
75
write_en<='0';
76
ub<='1';
77
lb<='1';
78
LED<=lesedaten;
79
elsifcounter_langsam=8then
80
LED<="0000000100000000";
81
schreibdaten<=x"0000";
82
cen<='0';
83
read_en<='1';
84
write_en<='0';
85
ub<='1';
86
lb<='1';
87
elsifcounter_langsam>9then
88
LED<="0000001000000000";
89
schreibdaten<=x"0000";
90
cen<='0';
91
read_en<='0';
92
write_en<='0';
93
ub<='0';
94
lb<='0';
95
else
96
LED<=x"0000";
97
cen<='0';
98
read_en<='0';
99
write_en<='0';
100
ub<='0';
101
lb<='0';
102
endif;
103
endif;
104
endprocess;
Doch im grunde spielt es keine Rolle welchen weg ich wähle, es treten
immer an die 1000 Info's, von denen nicht wenige auf Fehler innerhalb
des MIG-Erzeugten Verilogs hindeuten.
Dies führt zu etwa 500 Warnungen, verschiedenster Art, die aber
sicherlich aufzeigen, dass es so nicht gehen kann.
Es entstehen zwischen 100 und 200 Warnungen, z.b. der Form:
Sowas sollte doch nicht vorkommen, wozu bekommt man vordefinierte
UCF-Files für das Pining?
Letztendlich gibt es beim Bitstream generieren Fehler, diese sind von je
mach Fall verscienener Art, besonders was den Clk_eingang der 200MHz
angeht.
Burkhard K. schrieb:> Hat jemand hier im Forum ein Nexys4-DDR Board in Betrieb?
Auf dem Atlys
> Der per MIG erzeugte DDR2 Core lässt sich mit ISim nicht simulieren,
das ist keine so wirklich neue Information
ISIM wird von Xilinx aus irgendeinem mir nicht verständlichen Grund
nicht vollständig gepflegt. Im Bereich SERDES und GBT habe ich weitere
Beispiele, wo man mit ISIM nicht weiterkommt und nur ModelSIM das kann.
> Es muss wohl möglich sein, aus den per MIG generierten Sourcen eine> Netlist-Datei einmalig zu erstellen und in das Projekt einzubinden. Kann> jemand das Vorgehen dazu kurz skizzieren?
Du musst das user design entsprechend anpassen. Meistens muss man einen
internen Takt benutzen, der aus einer eigenen PLL kommt, oder sich an
die des DDR-CTRL dranhängen.
> Meine Anwendung erzeugt 2x16 bit (Audio-)Daten mit 1 MSps/s die per> FFT analysiert und später auf 200 kSps/s reduziert ausgegeben werden.
Warum wird die so hoch gesampelt? Wenn man eine Steigerung der Auflösung
möchte, muss man in der Regel auch die Bitbreite anpassen. 24 Bit wären
bei Audio ohnehin Pflicht.
> Bei den oben dargestellten Zugriffszeiten muss ich die aus dem RAM> gelesenen Daten (Burstlänge 8) in einem FiFo zwischenspeichern.> Hinsichtlich des Timings ist der Ersatz von SRAM durch DDR2 ein eher> enttäuschender Rückschritt.
Eigentlich würde man bei FFTs eher die Blockrams nehmen. Wenn Du später
runtersampelst, müssen bei 200kHz x Stereoaudio aber ein SRAM 100mal
reichen (?)
Ungeachtet dessen, willst Du sicher den DDR-CRTRL ins Laufen bekommen.
Hast Du die Möglichkeit, einen physischen Test zu machen? Einfach mal
statisch reinschreiben und rausschreiben, ohne großartige
Zugriffskontrolle?
Ich habe zwar kein Nexys4, aber vielleicht ist
in diesem Zusammenhang folgendes interessant:
Bei der Realisierung meines 8bit-Computers auf dem Spartan-3A-Starterkit
hatte ich das Problem, das DDR2-RAM (MT47H32M16) als Ersatz für ein SRAM
verwenden zu müssen. Der Zeitablauf besteht aus einer Folge von Halb-
zyklen tA und tB, welche jeweils 320 ns dauern. Der Speicherzugriff
durch die CPU erfolgt während tA, der Refresh während tB.
Ich habe das Problem ohne Verwendung des MIG so gelöst: Bei
der Initialisierung des RAMs habe ich eingestellt Burstlänge 4. Bei
den Speicherzugriffen verwende ich Auto-Precharge. Die 4 Datenworte
eines Bursts werden als ein einziges Datenwort behandelt: Beim
Schreiben erhalten alle 4 Worte denselben Wert. Das Lesen erfolgt
irgendwo im Inneren des Bursts. Man braucht keine DDR-Flipflops,
und das Timing beim Lesen vereinfacht sich drastisch. Ich habe
nicht einmal Timing-Constraints gebraucht. Ein theoretisch
denkbares Glitch-Problem beim Lesen ist nie aufgetreten.
Siehe Datei ps3a.vhd auf der Seite Downloads meiner Website:
http://www.bomerenzprojekt.de
Hallo Matze,
den DDR2 habe ich inzwischen eigenem Controller in Benutzung (mit
ISE14.7). Die Anzahl der Warnungen ist Legion (> 1700). Simulieren ist
nicht (s.oben). PAR schmeisst zwei Timing-Violations aus den Tiefen des
PHY-Layers, die ich aber als unkritisch einstufe (Temperatur-Kontrolle).
Mein Controller-Design habe ich aus Digilentics Referenzkomponente
https://reference.digilentinc.com/_media/nexys4-ddr:ram2ddr_refcomp.zip
(ram2ddrxadc.vhd) abgeleitet. Die Referenz-Komponente basiert auf dem
MIG-UserInterface.
Gestört hat mich an Digilents ram2ddrxadc.vhd insbeondere das sehr
langsame Timing und die fest eingestellte Wartezeit (1200 ns bis zum
RAM-ACK). Um ein für meine Anwendung brauchbares Timing zu realisieren,
habe ich einge Anpassungen vorgenommen:
* den vorgeschalteten SRAM Controller eingedampft
* die Steuer-Eingänge (ram_cen, ram_rnw) nach ram2ddrxadc.vhd
übernommen und dort registriert
* die Steuersignale "rd_data_valid" bzw. "mem_rdy" für die Erzeugung
der ACK-Signale ausgewertet
* eine fixe Datenbreite von 32 Bit eingestellt, wodurch sich das
Setzen der WDF-Maske erheblich vereinfacht
* und schliesslich das MIG Interface auf 2:1 Mode umgestellt so dass
sich die Zugriffszeiten für einzelne Schreib- ( < 100 ns) Lesezugriffe
(ca. 200 ns) erheblich verkürzen
* einen Arbiter mit fixer Priorität (Schreiben) integriert
Das MIG-UserInterface läuft mit 75 MHz (4:1 Mode) bzw. 150 MHz (2:1) bei
eingestellter 3333 ps DDR2-Clock. Daher müssen die Kontroll-Signale im
User-Design einsynchronisiert werden - bei 150 MHz zusätzlich noch
gestreckt werden.
Da ich nicht simulieren kann (s.o.) musste ich die relevanten
Steuersignale auf einen Pmod-Port legen und per USB-Logicanalyzer
anschauen (Mein Hobby-Bastel Analog-Discovery kann 10 ns Auflösung
gerade noch so). Zum Testen und Verifizieren habe ich die Daten über die
16 Schiebeschalter eingegeben, die Address-Eingabe per an einen Pmod
angeschlossen Drehgeber realisiert, die 27bit Adresse auf der
7-Segmentanzeige ausgegeben.
@Jürgen - ich analysiere Ultraschalldaten bis ca. 200 kHz - 5faches
Oversampling scheint mir dafür angemessen. Für die (hörbare) Ausgabe der
heruntergemischten bzw. Frequenz-transponierten Signale verwende ich
"normale" Audio-Samplingraten. HiFi spielt in diesem Zusammenhang keine
Rolle, 16bit Datenbreite reicht aus.
Gruß,
Burkhard
Burkhard K. schrieb:> Hi Matze, das mem_rdy Signal des UserInterfaces ist tatsichlich 99% der> Zeit auf '1', bewegt sich aber doch auf '0' - nämlich bei zwei> Gelegenheiten:>> * sobald das Write Kommando akzeptiert wurde, also als Reaktion auf> das Setzen von "mem_wdf_wren" UND "mem_wdf_end"
Stimmt, das konnte ich nun auch nachvollziehen.
Burkhard K. schrieb:> Wenn Dein "debug"-Signal in einer anderen> Clk-Domäne weiterverarbeitet wird, muss es noch einsynchronisiert> werden, die mem_ui_clk läuft mit einem Viertel bzw. der Hälfte (2:1> Mode) der DDR2 Clk.
Würde es von einem anderen CLK getaktet müsste es einsyncronisiert
werden.
Werde von daher erstmal den ui_clk als Systemtackt nutzen.
Der ui_clk läuft etwa mit 150MHZ.
Burkhard K. schrieb:> Tatsächlich gibt es gleich mehrere mögliche Reihenfolgen, in denen> Daten, WDF Maske und Schreibkommando präsentiert werden können, bitte am> besten selbst im MIG User Guide, Abschnitt "User Interface" nachlesen -> und zwar in der neuesten Version (Zynq-7000 AP SoC and 7 Series Devices> Memory Interface Solutions v2.4)! In älteren Versionen des Dokuments ist> die Abfolge unvollständig dargestellt, was mich einige Zeit gekostet> hat.
Danke, dies ist der entscheidende Tipp, ich hatte ein unvollständiges
Datenblatt und wusste so nicht genau in welcher Reihenfolge die Signale
gesetzt werden müssen.
Habe schreiben/lesen nun deutlich verkürzen können.
Hiermit kann man den RAM lesen + schreiben
1
if(rising_edge(ui_clk))then
2
ifstate=0then--Idle
3
addr<=address;
4
cmd<=CMD_WRITE;
5
en<='0';
6
wdf_mask<="00000000";
7
wdf_wren<='0';
8
wdf_data<=data_in;
9
wdf_end<='0';
10
debug<=x"0";
11
write_ok<='0';
12
read_ok<='0';
13
ifwdf_rdy='1'andrdy='1'then--MIGbereit
14
DDR2_rdy<='1';--Controllerbereit
15
ifwrite_en='1'andread_en='0'then
16
state:=1;
17
elsifwrite_en='0'andread_en='1'then
18
state:=2;
19
else
20
state:=0;
21
endif;
22
else
23
DDR2_rdy<='0';--Controller!bereit
24
endif;
25
elsifstate=1then--Schreiben
26
addr<=address;
27
cmd<=CMD_WRITE;
28
en<='1';
29
wdf_mask<="00000000";
30
wdf_wren<='1';
31
wdf_data<=data_in;
32
wdf_end<='1';
33
debug<=x"1";
34
write_ok<='1';
35
read_ok<='0';
36
DDR2_rdy<='0';
37
state:=0;
38
elsifstate=2then--Lesen
39
addr<=address;
40
cmd<=CMD_READ;
41
en<='1';
42
wdf_mask<="11111111";
43
wdf_wren<='0';
44
wdf_data<=data_in;
45
wdf_end<='0';
46
debug<=x"2";
47
write_ok<='0';
48
DDR2_rdy<='0';
49
ifrd_data_valid='1'then
50
data_out<=rd_data;
51
read_ok<='1';
52
state:=0;
53
else
54
read_ok<='0';
55
endif;
56
57
else
58
state:=0;
59
endif;
60
endif;
61
endprocess;
Angesteuert wird das ganze Testhalber so:
1
ifstate="0000"then
2
data_in<=address(26downto0)&x"000000000"&'0';
3
ifDDR2_rdy='1'then
4
write_en<='1';
5
read_en<='0';
6
state<="0001";
7
endif;
8
JC(1downto0)<="01";--Gelb,Blau,Lila
9
JC(2)<='0';
10
elsifstate="0001"then
11
ifwrite_ok='1'then
12
write_en<='0';
13
read_en<='0';
14
state<="0010";
15
endif;
16
JC(1downto0)<="10";
17
JC(2)<='0';
18
elsifstate="0010"then
19
ifDDR2_rdy='1'then
20
data_in<=address(26downto0)&x"000000000"&'0';
21
write_en<='0';
22
read_en<='1';
23
state<="0011";
24
endif;
25
JC(1downto0)<="11";
26
JC(2)<='0';
27
elsifstate="0011"then
28
ifread_ok='1'then
29
write_en<='0';
30
read_en<='0';
31
LED(15downto0)<=data_out(63downto48);
32
disp_data(15downto0)<=data_out(47downto32);
33
address<=address+'1';
34
data_in<=address(26downto0)&x"000000000"&'0';
35
state<="0000";
36
endif;
37
JC(1downto0)<="00";
38
JC(2)<='1';
39
endif;
Problem ist der Lesezyklus, wie du es schreibst dauert er bei mir gut
400ns, da die Gültigkeit der daten ewig auf sich warten lässt.
Jedenfalls liegen die Signale
1
JC(1downto0)<="00";
2
JC(2)<='1';
des so lange an.
Somit müsste es hierran liegen:
1
ifrd_data_valid='1'then
Aber es kann doch nicht sein, dass der DDR-Controller so extrem langsam
liest. Was bringen 128MByte DDR2 wenn man nur mit Einstelliger MB/s-
Datenrate davon lesen kann?
Schreiben scheint um ein vielfaches schneller zu gehen.
Somit hast du völlig Recht:
Burkhard K. schrieb:> 3. Timing:> Digilent gibt die Cycle-Time> (https://reference.digilentinc.com/nexys4-ddr:sram) mit 210 (tRC) bzw.> 260 (tWR) ns an. Tatsächlich gemessen habe ich für den Lesezyklus ca.> 350 ns, mit gelegentlichen Ausreissern (> 400 ns) nach oben (vom Anlegen> des CEN Signals bis zur Assertion von RD_DATA_VALID des MIG UIs - bei> Verwendung des RAM2DDRxadc Moduls von Digilent). Die Zeit für einen> Schreibzyklus kann ich mit meinem Mitteln leider nicht messen; sie> scheint aber unter der fürs Lesen zu liegen.
Hast du schon versucht den DDR-Controller MIG7 IP-Block von Hand
anzulegen.
Dass werd ich nun mal versuchen.
Duke Scarring schrieb:> Ich habe auch ein Nexys4, aber die Variante mit dem PSRAM.
Ist zwar OT, aber ich häng mich mal hier mit einer Frage dran:
Mir ist aufgefallen, dass Digilent innerhalb kurzer Zeit die Boards
Nexys2/Nexys3/Nexys4 mit PSRAM vom Markt genommen hat, obwohl die
FPGAs darauf verschiedenen Generationen angehören. Offenbar lag's
nicht an veralteten FPGAs (Spartan-3E beim Nexys2), sondern an
den PSRAMs. Weiss jemand, was es damit auf sich hat? Werden
diese RAMs nicht mehr hergestellt?
M. W. schrieb:> Hat sich das mit dem Speicherproblem geklärt?
Ich selbst habe den DDR2-Speicher im 2:1 Modus - nach einigen "Gotchas"
(MIG-7 - die Doku ist extrem dünn und in älteren Versionen
unvollständig) - im Einsatz; Matze soweit ich lese ebenso. Das Digilent
"Referenz-Design" ist ein schlechter Witz. Was genau willst Du wissen?
MIG: Was immer noch nervt, ist die Nichtsimulierbarkeit mit ISIM und die
in die Tausenden gehenden Warnungen aus diesem IP-Block. Implementieren
mit MIG im Design dauert ewig (gefühlt +10 Minuten). Leider habe ich es
bisher nicht hinbekommen, das MIG User Interface für den Speicher
vorsynthesiert in eine .ngc Datei zu packen (ISE). Noch genialer wäre
es, wenn sich der ganze MIG Kram vorimplementiert (PAR) auf den FPGA
klatschen liesse und ich mein restliches Design anschliessend darum
bauen könnte. Für einen Tip in diese Richtung wäre ich dankbar.
Gruß,
Burkhard
Das Nexsys 4 ist doch ein Artix Board, wieso nutzt ihr dann ISE? In
Vivado kann man den Mig simulieren, geht zwar langsamer als Modelsim
aber immerhin. Doku ist beschissen aber anhand des Example Designs
kriegt man das hin. Den 2:1 Modus sollte man meiner Meinung nach nur
nutzen, wenn man auf Schmerzen steht. Im 4:1 ist das wenigstens halbwegs
sinnvoll, da kann man einfach beim Schreiben den Fall 1 nehmen, und
Daten, Adresse, app_en wdf_end und wren gleichzeitig setzen.
Klar, beim Sdram hat man immer Latenz, wenn man nur einen Burst liest,
ist das langsam, aber wenn es einmal los ging kommen die Daten
hintereinander.
Christian R. schrieb:> Den 2:1 Modus sollte man meiner Meinung nach nur> nutzen, wenn man auf Schmerzen steht.
Danke für die Blumen - Du hast im Thread meine Requirements gelesen? Was
nützt mir der vermeintlich einfachere Transfer, wenn das Timing nicht zu
gebrauchen ist?
2:1 Mode: Eine zusätzliche UI_Clock Periode und 4 Zeilen Code mehr - das
piekst nur ganz sanft - sobald man mal weiss wie's geht.
1
MEM_WR_CTL:process(cState,ram_wrm_int)
2
begin
3
-- first transmission - upper address part transferred during BL8
4
-- these part must be masked completely to prevent unintended
5
-- overwrite at app_addr(7 downto 4)
6
ifcState=stSendDatathen
7
mem_wdf_wren<='1';
8
mem_wdf_end<='0';
9
mem_wdf_mask<="11111111";
10
11
-- second transmission - lower address part transferred during BL8
12
-- contains 32bit payload
13
-- mask non-payload data at app_addr(3 downto 2)
14
elsifcState=stSendData2then
15
mem_wdf_wren<='1';
16
mem_wdf_end<='1';
17
mem_wdf_mask<="1111"&"0000";
18
else
19
mem_wdf_wren<='0';
20
mem_wdf_end<='0';
21
mem_wdf_mask<="11111111";
22
endif;
23
endprocessMEM_WR_CTL;
Für ISE hab ich meine Gründe - z.B. hätte mein Design von dem ganzen
AXI-Geraffel nur den Overhead - aber keinen Vorteil (ausser dass ich
eine Handvoll IP-Blöcke grafisch in das Design klicken könnte).
Gruß, Burkhard
Man kann Vivado und dort auch den MIG komplett ohne Axi benutzen. Ivh
mag Axi auch nicht und benutze es nicht. Aber ISE und Artix war wirklich
nur eine Krücke. Das mit dem Timing verstehe ich nicht ganz, DDR Sdram
braucht halt prinzipiell eine gewisse Latenz, dafürgibts Buffer. Jeder
B8L einzeln mag dann mit 2:1 besser gehen, richtig.
Christian R. schrieb:> Man kann Vivado und dort auch den MIG komplett ohne Axi benutzen.
Den MIG schon - aber divsere andere IPs (FIR-Compiler, CIC-Compiler,
CORDIC, DDS-Compiler, XADC-Wizard etc.) gibt es - anders als in ISE - in
Vivado offensichtlich nur noch mit AXI-Interface. Sollten sich in ISE
vorhandene, ältere Versionen dieser IPs nach Vivado importieren, wäre
das ein Grund mir Vivado noch mal anzuschauen.
Beim Timing gibt es nicht viel zu verstehen, wenn ich in einer
Mikrosekunde je einen Schreib- und einen (oder sogar zwei)
Lesezugriff(e) unterbringen muss, dann ist der 4:1 Modus mit der
schlecht definierten Lesezeit von 400 ns und darüber zu dicht am Limit.
OK, manche Cores gibts nur noch mit Axi, stimmt, aber Axi Streaming ist
auch nur ein simples FIFO Interface. Ich hab mit ISE und dem Artix ganz
schlechte Erfahrungen gemacht, dauert alles lange, Simulation klappt
nicht, da bin ich dann auch auf Vivado umgestiegen. Hat auch Macken,
aber für die 7er einfach besser als ISE.
Klar, wenn du nicht puffern kannst, ist der 2:1 besser. Ich finde den
halt bissl seltsam, passt nicht so recht zu meinem Interface und
außerdem braucht der bei DDR400 den 3er Speedgrade. Timing ist schon bei
4:1 irre, aber bei 2:1 mit DDR400 aufm Artix schon echt schwierig.
Daher umgehe ich den wo es geht. ;)