Forum: FPGA, VHDL & Co. Custom IP-Core für Mittelwert/Standardabweichung


von lenny (Gast)


Angehängte Dateien:

Lesenswert?

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
if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
2
    case slv_reg_write_sel is
3
        when "01" => 
4
        ....
5
        when others => null;
6
    end case;
7
end if;


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

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


Lesenswert?

Nicht, dass ich eine Ahnung vom Microblaze hätte...
Trotzdem:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
use ieee.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.

von lenny (Gast)


Lesenswert?

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?

von Duke Scarring (Gast)


Lesenswert?

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"

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


Lesenswert?

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

von dnalorac (Gast)


Lesenswert?

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

von Oli (Gast)


Lesenswert?

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.

von lenny (Gast)


Lesenswert?

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

von Duke Scarring (Gast)


Lesenswert?

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

von lenny (Gast)


Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

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

von Unknown (Gast)


Lesenswert?

>HW: 533737 Ticks
>SW: 400172 Ticks
Die Software ist schneller, als die Hrdware. Hat der Picoblaze etwa 
einen Coprozessor?

von Duke Scarring (Gast)


Lesenswert?

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

von Uwe (Gast)


Lesenswert?

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.

von Uwe (Gast)


Lesenswert?

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.

von lenny (Gast)


Lesenswert?

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.

von D. I. (Gast)


Lesenswert?

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

von Andre (Gast)


Lesenswert?

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.

von H. G. (Gast)


Lesenswert?

Du baust einen IP-Core für die Standardabweichung?
Da braucht man doch nur zwei Akkumulatoren, oder?

von lenny (Gast)


Lesenswert?

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)

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.