Hallo,
ich bin noch Anfänger was VHDL/FPGAs betrifft. Ich habe mir einen
IP-Core für den Microblaze erstellt welcher 1024 Byte BRAM sowie 2
Register enthält. Im Anhang ist mal die generierte VHDL-Datei. (IDE ist
ISE 13.1)
Mein Ziel ist es eine Anzahl von Bytes in den BRAM zu schreiben über die
dann der Mittelwert/Standardabweichung gebildet wird. Register eins soll
dabei die Anzahl der Bytes übergeben und als Starttrigger der Berechnung
dienen. Register zwei soll als Rückgaberegister dienen.
Nun zu meinen Problem/Fragen:
1. Wie kann ich auf das Schreiben in Register eins triggern?
reicht dazu folgendes:
1
ifBus2IP_Clk'eventandBus2IP_Clk='1'then
2
caseslv_reg_write_selis
3
when"01"=>
4
....
5
whenothers=>null;
6
endcase;
7
endif;
2. Wie kann ich Mittelwert/Standardabweichung mit einer variablen Anzahl
von Elementen berechnen lassen? Reicht da ein "for .. loop" statement
mit exit? bzw. wird aus einer loop mit max. 1024 Iterationen auch
sinnvolle Hardware generiert?
3. Wie kann ich außerhalb der "generate" statments auf den BRAM
zugreifen?
Wenn ich das richtig verstanden habe wird da ja 4x 256Byte BRAM erzeugt.
und 4. Die Synthese dauert bei mir ewig. Gibt es eine Möglichkeit nur
den IP-Core zu übersetzen. Der Microblaze ändert sich ja eigentlich
nicht.
Und wie kann ich die Hardware eines IP-Cores debuggen?
danke,
lenny
Nicht, dass ich eine Ahnung vom Microblaze hätte...
Trotzdem:
1
libraryieee;
2
useieee.std_logic_1164.all;
3
useieee.std_logic_arith.all;
4
useieee.std_logic_unsigned.all;
5
useieee.numeric_std.all;
Böse Sache...
Wurde dieser Header tatsächlich automatisch erzeugt?
lenny schrieb:> 2. Wie kann ich Mittelwert/Standardabweichung mit einer variablen Anzahl> von Elementen berechnen lassen? Reicht da ein "for .. loop" statement> mit exit?
Nein.
Denn auf BRAMs kannst du nicht massiv parallel zugreifen. Du musst also
z.B. in einer FSM jedes Datum einzeln abholen und verrechnen.
> bzw. wird aus einer loop mit max. 1024 Iterationen auch> sinnvolle Hardware generiert?
Eine Schleife erzeugt dir parallele Hardware. Das kannst du nicht
brauchen.
Hallo Lothar,
Lothar Miller schrieb:> Böse Sache...> Wurde dieser Header tatsächlich automatisch erzeugt?
Nein das "use ieee.numeric_std.all;" hab ich glaub ich beim rumprobieren
mit eingefügt. Bin jetzt schon mehrmals drüber gestolpert, dass das wohl
nicht gut sein sollte. Kannst du mir erklären warum?
Lothar Miller schrieb:> Denn auf BRAMs kannst du nicht massiv parallel zugreifen. Du musst also> z.B. in einer FSM jedes Datum einzeln abholen und verrechnen.
Wenn ich jetzt jedes Datum einzeln abhole bin ich aber genauso
langsam/schnell wie der Microblaze mit sequentieller Verarbeitung?
Ok lassen wir den BRAM mal aussen vor. Gibt es eine andere Möglichkeit
wie ich vom Microblaze aus hardwareparallel den Mittelwert aus mehreren
Werten berechnen kann?
lenny schrieb:> Nein das "use ieee.numeric_std.all;" hab ich glaub ich beim rumprobieren> mit eingefügt. Bin jetzt schon mehrmals drüber gestolpert, dass das wohl> nicht gut sein sollte. Kannst du mir erklären warum?
(Zitat/Textbaustein: Lothar Miller)
Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
Und einige mehr...
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
lenny schrieb:> Wenn ich jetzt jedes Datum einzeln abhole bin ich aber genauso> langsam/schnell wie der Microblaze mit sequentieller Verarbeitung?
Ich bin mir 100% sicher, dass du garantiert mit reiner Hardware
schneller sein wirst, auch wenn du das Blockram Wort für Wort
abklapperst. Denn du kannst da in jedem Takt ein Wort erledigen. Ich
glaube kaum, dass du das mit einem Soft-uC auch schaffst.
> Ok lassen wir den BRAM mal aussen vor. Gibt es eine andere Möglichkeit> wie ich vom Microblaze aus hardwareparallel den Mittelwert aus mehreren> Werten berechnen kann?
Wenn das wirklich parallel sein müsste, dann mußt du da einen massiv
parallelen Bus aufbauen (lassen): 1024 Byte BRAM wären dann genau 8096
parallele(!!!) Leitungen. Das ist ein Monster-Bus. Ich bin mir ebenfalls
fast sicher, dass die Laufzeit durch diesen Bus (incl. Kmbinatorik)
ähnlich lang dauern wird, wie wenn du das mit max. Geschwindigkeit
hintereinander ausrechnest...
Wenn ich Dich richtig verstehe, willst Du die Werte sequentiell per
Microblaze in Deine "Engine" schreiben und dann am Ende Mittelwert und
Standardabweichung lesen. Falls das so ist, brauchst Du gar kein Block
RAM:
Zur Mittelwertberechnung brauchst Du nur N, Summe(x) und Summe(x**2).
Die kannst Du mit jedem neuen Wert fortschreiben.
Das Interface zum Prozessor hat dann z.B. folgende Register:
Steuerregister: Schreiben einer 1 setzt alles auf 0.
Datenregister: Jedes Schreiben fügt den Wert zu den Summen hinzu und
erhöht den Zähler.
Ergebnisregister. Hier musst Du Dich enscheiden, ob Du die DIvisionen in
Hardware (aufwendig) oder lieber doch mit dem Prozessor machen willst.
Da Du nur zwei Divisionen am Ende Deines Datenblocks brauchst, würde ich
den Prozessor nehmen. Dann hast Du drei Ergebnisregister:
N
Summe(x)
Summe(x**2)
Je nach Wortbreite Deines Prozessors und der Daten musst Du das ggf. auf
mehrere Adressen am Prozessor aufteilen.
Das Quadrieren ist der aufwendigste Vorgang bei diesem Ansatz und kann
evtl. die maximal erreichbare Taktfrequenz Deines Designs herabsetzen.
Hier musst Du ggf. eine "Pipeline" aufbauen, um die Berechnung auf
mehrere Schritte aufzuteilen...
Man braucht für den gesamten Vorgang weder ein RAM oder irgendwas
anderes ausser den genannten Summen und einem Dividerer und eine Wurzel.
Die Summen bildet man bereits beim Empfang der Daten. Das geht sogar mit
Gewichtung und Schätzung der Werte bei der Bildung von Schwerpunkten,
StdAbw und MittQuadKontingenz.
Man muss sich nur entscheiden, ob man einen Divider für den Schwerpunkt
und die STABW gemeinsam benutzen will. Das macht am Ende die Latzenz.
Ich habe das mal mit einem Cyclone II bei 60MHz gemacht. Der DIV
brauchte 15 und die Wurzel 10 Takte.
Danke für eure Antworten.
dnalorac schrieb:> Wenn ich Dich richtig verstehe, willst Du die Werte sequentiell per> Microblaze in Deine "Engine" schreiben und dann am Ende Mittelwert und> Standardabweichung lesen. Falls das so ist, brauchst Du gar kein Block> RAM:
Ja genau das ist es was ich vorhabe. Irgendwie dachte ich, dass man mit
BRAM schneller ist. Wenn man aber nur sequentiell an die Daten rankommt
macht das keinen Sinn.
Ich werd mal die Variante mit den 3 Registern probieren und gebe dann
Rückmeldung ob es funktioniert.
Ein nerviges Problem bleibt allerdings immernoch: die Synthese des
IP-Cores+Microblaze dauert ziemlich lange. Gibts da keine Möglichkeit
das noch irgendwie zu beschleunigen?
Und kennt jemand eine Möglichkeit wie ich Hardware-Breakpoints setzen
kann? Es wär toll wenn ich bei einen bestimmten Hardwarezustand stoppen
könnte und durch den (VHDL)Code steppen kann.
@ Lothar Miller:
Tolle Seite die du da hast. Da kann ich mir bestimmt das ein oder andere
noch abschauen. ;)
lenny schrieb:> Ein nerviges Problem bleibt allerdings immernoch: die Synthese des> IP-Cores+Microblaze dauert ziemlich lange. Gibts da keine Möglichkeit> das noch irgendwie zu beschleunigen?
Du kannst Dir davon eine Netzliste erzeugen und diese in Dein Projekt
einbinden.
> Und kennt jemand eine Möglichkeit wie ich Hardware-Breakpoints setzen> kann? Es wär toll wenn ich bei einen bestimmten Hardwarezustand stoppen> könnte und durch den (VHDL)Code steppen kann.
Dazu müsstest Du die Zeit anhalten. Das klappt am Besten im Simulator.
Duke
So hab jetzt mal eine einfache Summenbildung mit einen Register gemacht,
also Wert reinschreiben und er wird automatisch aufsummiert.
Das ganze hab ich dann einer Softwarelösung mit Microblaze
gegenübergestellt und mit nen Timer gemessen:
HW: 533737 Ticks
SW: 400172 Ticks
Da ist wahrscheinlich das Schreiben ins Register zu langsam?
Duke Scarring schrieb:> Du kannst Dir davon eine Netzliste erzeugen und diese in Dein Projekt> einbinden.
Wie genau mach ich das? Ich habe nur system_top.vhd und system.xmp im
Projekt. Die system.xmp kann ich dann im Xilinx Platform Studio
bearbeiten.
Bin noch etwas erschlagen von der Vielzahl an Tools/Optionen/Menüs.
Duke Scarring schrieb:> Dazu müsstest Du die Zeit anhalten. Das klappt am Besten im Simulator.
Hab mal ISim laufen lassen, allerdings scheint er meine Breakpoints zu
ignorieren. Bin mir nicht sicher ob er zur Simulation auch die Software
mit einbezieht. Nur die reine Hardwaresimulation bringt ja nichts.
lenny schrieb:> Da ist wahrscheinlich das Schreiben ins Register zu langsam?
Gut möglich. Schnelle Portzugriffe sind nicht so die Stärke des
Microblaze (und anderer Softcores). Hast Du Caches aktiviert? Welche?
[Netzliste erzeugen]
> Wie genau mach ich das? Ich habe nur system_top.vhd und system.xmp im> Projekt. Die system.xmp kann ich dann im Xilinx Platform Studio> bearbeiten.
Genau dort müßtes Du auch eine Netzliste erzeugen können.
> Bin noch etwas erschlagen von der Vielzahl an Tools/Optionen/Menüs.
Dann finde Dich erstmal noch ein bischen rein und sei froh, daß Du
überhaupt ein laufendes Microblazesystem hast (über die Hürde kommt auch
nicht jeder...)
> Hab mal ISim laufen lassen, allerdings scheint er meine Breakpoints zu> ignorieren.
Was für Breakpoints? Software oder Hardware? Wo hast Du die definiert?
> Bin mir nicht sicher ob er zur Simulation auch die Software> mit einbezieht.
Das solltest Du vorher sicherstellen. Vielleicht simulierst Du Dir
erstmal ein Lauflicht auf den GPIO-Pins?
> Nur die reine Hardwaresimulation bringt ja nichts.
Das stimmt, das rockt nur zusammen mit Software.
Duke
Unknown schrieb:>>HW: 533737 Ticks>>SW: 400172 Ticks> Die Software ist schneller, als die Hrdware. Hat der Picoblaze etwa> einen Coprozessor?
Hier ist ein Microblaze am werkeln, wenn ich das richtig verstanden
habe. Und eine Addition bekommt der direkt im Prozessorkern schneller
hin, als über das ganze PLB/OPB-Gedöhns einen Portzugriff abzusetzen.
Für mich klingen die Zahlen glaubwürdig. Im Zweifelsfall guckt man sich
mal in der Simulation an, was das alles so passiert.
Duke
Durch den VHDL code steppen ???
Aus VHDL wird ein Konstrukt aus Flip-Flops, kombinatorischer Logik und
anderem Schnick Schnack wie multiplizieren und RAMs "gebaut". Es gibt
keine Verzweigungen oder Kontrollfluss. Man könnte sich höstens das RTL
angucken oder besser ne Testbench machen mit Stimuli usw.
Schließe DAS wo die Daten herkommen direkt an die Harware an und lass
diese rechnen. Der Microblaze holt sich nur noch das Ergebnis ab. So
gehen nicht die ganzen Daten über OPB oder PLB sondern nur das Ergebnis.
Duke Scarring schrieb:> Gut möglich. Schnelle Portzugriffe sind nicht so die Stärke des> Microblaze (und anderer Softcores). Hast Du Caches aktiviert? Welche?
Ja I-Cache und D-Cache sind an.
Hab mal Tests mit den verschiedenen anderen Kombinationen gemacht:
beide Caches aus:
HW: 3835482
SW: 4218574
D-Cache an I-Cache aus:
HW: 3649364
SW: 4084044
D-Cache aus I-Cache an:
HW: 1818209
SW: 1724211
Duke Scarring schrieb:> Genau dort müßtes Du auch eine Netzliste erzeugen können.
Also er rechnet zwar irgendwas wenn ich auf Netlist erzeugen klicke (der
kleine Kreis zeigt Aktivität) aber danach kommt keine Meldung. Übernimmt
er die dann automatisch ins Projekt?
Duke Scarring schrieb:> Was für Breakpoints? Software oder Hardware? Wo hast Du die definiert?
Hardware-Breakpoints beim Schreiben in das jeweilige Register (direkt in
der user_logic.vhd). Aber er stoppt nicht. Vielleicht hab ich bei ISim
auch noch irgendeine Konfiguration übersehen wo man einstellt welche
Software auf dem Microblaze laufen soll.
Duke Scarring schrieb:> Und eine Addition bekommt der direkt im Prozessorkern schneller> hin, als über das ganze PLB/OPB-Gedöhns einen Portzugriff abzusetzen.
Wie hoch ist eigentlich der Aufwand eines Dual-DDR-Ram Zugriffs?
Ich stell mir das so vor: ein eigener IP-Core bekommt vom Microblaze die
Startadresse und die Anzahl der Wert im RAM und holt sich dann über ein
eigenes Interface die Werte. Das müsste das Ganze doch etwas
beschleunigen oder?
Ich wünsche allen einen tollen Feiertag.
lenny schrieb:> Das müsste das Ganze doch etwas> beschleunigen oder?
ja, nennt sich dann DMA und könnte zum Bespiel über NPI realisiert
werden mithilfe des MPMC
Ich komme noch immer nicht ganz mit, warum die SW da schneler sein soll,
wenn sie in einer SPU als Softcore läuft. Wenn man das Ganze als
pipeline baut, ist das doch DIE Lösung.
Ich melde mich auch noch mal zum Thema. Leider muss das Projekt in
letzter Zeit etwas ruhen.
@andre:
Was genau meinst du mit Pipeline?
@Gerald Hellinghaus:
Vom Prinzip her ja. Ich wollte es nur vermeiden die ganzen RAM-Zugriffe
über den OPB-Bus zu machen da der evt. nicht der schnellste ist. (ist
meine Vermutung, bin noch FPGA-Neuling)
Ich habe jetzt versucht den Vorschlag von D. I. (grotesque) umzusetzen
und habe mir einen IP-Core mit Registern und NPI-Interface gebaut.
Das NPI-Interface scheint auch zu funktionieren. Ich bekomme zumindest
die richtigen Werte wenn ich vom Microblaze in den RAM schreibe und mit
NPI auslese.
Was noch nicht richtig funktioniert sind allerdings die Burst-Transfers.
Ich versuche mit NPI_RdFIFO_RdWdAddr rauszufinden welches Word ich
gerade lese, aber RdWdAddr scheint meistens 0 zu sein.
Ich würde das ganze auch gern mal komplett durch den Simulator jagen,
allerdings habe ich festgestellt, dass der Simulator den DDR-Ram nicht
initialisiert. (Bei einem realen Test auf dem Eval-Board bezieht der
Microblaze sein Programm aus dem DDR-RAM)