Hallo Zusammen,
ich implementiere momentan ein Design auf einem Altera Arria II GX mit
PCIe-Anbindung. Vom PICe-Core erhalte ich den Systemtakt von 125 MHz,
mit welchem meine Module getaktet sind. Allerding stelle ich jetzt in
der Timing-Analyse fest, dass er diesen Takt nicht schafft, maximal 104
MHz wären drin. Untenstehend habe ich den Code zum kritischen Pfad
beigefügt:
Kritischer Pfad: Signal "par_factor" to Signal ""res_mult
Mir ist klar, dass 125 MHz kein Pappenstiel sind, aber kann es sein,
dass schon eine 32-Bit-Multiplikation (plus etwas Logik davor und
dahinter) den Rahmen des Möglichen sprengt? Oder ist das
unwahrscheinlich und ich mache vermutlich Fehler bei der Timing-Analyse?
Peter
Hallo,
du willst eine 32bit x 32bit Multiplikation ein einem Takt schaffen. Der
Arria II GX hat 18bit x 18bit Multiplizierer, davon muss Quartus vier
parallel schalten und die Produkte noch addieren. Das wird nicht in 8
ns. Du musst die Multiplikation pipelinen. Vielleicht bietet der
Megawizzard einen entscprechenden Multiplizierer an.
Tom
Warum nimmst du nicht einen fertigen Hardware-Multiplier aus dem FPGA,
dann kannst du das Timing im Datenblatt nachlesen...
Ein alter Spartan 3 schafft hier 139MHz:
1
entityMultiply32x32is
2
Port(a:inSTD_LOGIC_VECTOR(31downto0);
3
b:inSTD_LOGIC_VECTOR(31downto0);
4
q:outSTD_LOGIC_VECTOR(31downto0);
5
clk:inSTD_LOGIC);
6
endMultiply32x32;
7
8
architectureBehavioralofMultiply32x32is
9
signalla,lb,lq:unsigned(31downto0);
10
begin
11
la<=unsigned(a);
12
lb<=unsigned(b);
13
14
processbegin
15
waituntilrising_edge(clk);
16
lq<=la*lb;
17
q<=std_logic_vector(lq);
18
endprocess;
19
20
endBehavioral;
Aber ich glaube, nicht die Multiplikation ist hier das Problem, sondern
die gleichzeitige Prüfung des Überlaufs. Kannst du die nicht einen
Takt später machen?
Danke für eure Antworten!
Hardware-Multiplizierer habe ich bisher keine instanziiert, da ich
Multiplikation nach diesem Schema an mehreren Stellen durchführe, und
deshalb in eine Funktion ausgelagert habe. Kann ich denn trotzdem in der
Funktion einen Hardware-Multiplizier instanziieren? Wenn ja, hätte dies
aber vermutlich den Nachteil, dass die Hardware für jeden Aufruf der
Funktion erzeugt werden muss, da ja der Funktionsaufruf prinzipiell
mehrfach gleichzeitig stattfinden könnte.
Zum Pipelining der Multiplikation und anschließendem Überlauf-Check:
Selbige Begründung. In der Funktion kann ich das meines Wissens nach
nicht auf mehrere Takte verteilen.
Peter Z. schrieb:> Hardware-Multiplizierer habe ich bisher keine instanziiert,
Das macht die Toolchain solange möglich von sich aus, wenn du sowas
schreibst:
1
-- Multiply
2
temp:=a*b;
Irgendwann gehen dir aber die Mutltiplizierer aus, dann wird haarig...
Musst du diese Multiplizierer immer alle gleichzeitig nutzen? Falls
nein, dann sollten die sinnvoll gemultiplext werden. Denn Multiplizierer
sind wertvoll, weil nur in endlicher Stückzahl auf dem FPGA vorhanden...
>> Hardware-Multiplizierer habe ich bisher keine instanziiert,> Das macht die Toolchain solange möglich von sich aus, wenn du sowas> schreibst:
Das ist schonmal erfreulich ;-)
> Musst du diese Multiplizierer immer alle gleichzeitig nutzen?
Jein. Die Funktion wird momentan von mehreren Komponenten aus
aufgerufen. Innerhalb jeder Komponente erfolgen aber alle Berechnungen
getaktet nacheinander. Somit bräuchte ich einmal pro Komponente den
Hardware-Multiplizierer, was vertretbar sein sollte.
Nur fällt mir eben keine elegante Beschreibung ein, um diese
Multiplikation mit anschließender Begrenzung so gekapselt wie möglich zu
beschreiben. Ich habe diese Funktion extra in ein Package ausgelagert,
um Redundanzen in Code der einzelnen Komponenten zu minimieren.
Peter Z. schrieb:> Mir ist klar, dass 125 MHz kein Pappenstiel sind, aber kann es sein,> dass schon eine 32-Bit-Multiplikation (plus etwas Logik davor und> dahinter) den Rahmen des Möglichen sprengt?
Hier die klare Aussage: Ja dass KANN sein:
Die im Datenblatt angegebene Maximale Frequenz der Multplier sind
zumeist ziemlich ausgelutscht: Der Marketing K(r)ampf zwischen A und X
lässt grüssen...
Außerdem sind die Multiplier nicht feingranuliert über den Chip
verteilt, so dass Routing Delays sowie die Propagation deiner "etwas"
Logik schon ganz schön ins Gesamtbudget eingehen.
Die wirkliche Performance der Multiplier kann also nur ausgenutzt werden
wenn direkt Eingangs- wie ausgangsseitig registert gearbeitet wird
(pipelining), je nach verwendeter Architektur kann die Verwendung von
Pipelinestufen innerhalb der Hardwaremultiplier nochmals einige hundert
Megaherz Gewinn bringen...
Gruß
Vanilla
Peter Z. schrieb:> Wenn ja, hätte dies> aber vermutlich den Nachteil, dass die Hardware für jeden Aufruf der> Funktion erzeugt werden muss, da ja der Funktionsaufruf prinzipiell> mehrfach gleichzeitig stattfinden könnte.
In Hardware wird nichts aufgerufen, sondern instanziert. Wenn du die
Funktion in drei Prozessen verwendest, wird den Multiplizierer dreimal
instanziert. Ob du nun einen Hardware-Multiplizierer verwendest oder
nicht, spielt keine Rolle.
Tom
Peter Z. schrieb:> Ich habe diese Funktion extra in ein Package ausgelagert,> um Redundanzen in Code der einzelnen Komponenten zu minimieren.
Bringt wie schon gesagt alles nichts. Wenn da im "Code" dreimal eine
Funktion mit a*b "aufgerufen" wird, dann werden im FPGA parallel 3
Multiplizierer eingebaut.
Okay, dann wird wohl die eleganteste Beschreibung eine separate
"Multiplizier-Komponente" sein, welche die Multiplikation und
Überlaufprüfung gepipelined durchführt. Diese wird einmal pro "nutzende"
Komponente instanziiert und in den entsprechenden Schritten mit Daten
versorgt.
Peter Z. schrieb:> Diese wird einmal pro "nutzende"> Komponente instanziiert und in den entsprechenden Schritten mit Daten> versorgt.
Wenn sie 3 mal instanziert wird, dann ist sie auch 3 vorhanden.
Du darfst sie nur einmal instanzieren !
> dass die Hardware für jeden Aufruf der> Funktion erzeugt werden muss
Hä ? Die Hardware wird nicht erzeugt. Die ist da und wird entweder
benutzt oder nicht. Wenn du in den Syntheseoptionene einstellst, daß er
Harwaremultiplizierer benutzen soll dan tut er das auch wenn du irgendwo
"*" hinschreibst. Wenn du die Option deaktiviert läßt dann liegen die
Hardwaremultiplizierer einfach brach und werden nicht benutzt. Ist doch
schade du hast dafür doch bezahlt. Also nutz die Dinger auch !
Uwe schrieb:> Die Hardware wird nicht erzeugt.> Die ist da und wird entweder benutzt oder nicht.
Wenn alle Multiplizierer verbraucht sind, dann bastelt sich die Synthese
einen aus LUTs, und der ist dann durchaus "erzeugt"...
> Wenn sie 3 mal instanziert wird, dann ist sie auch 3 vorhanden.> Du darfst sie nur einmal instanzieren !
Das ist mir klar. Ich meinte, dass ein Multiplizierer innerhalb der
jeweiligen Komponente erzeugt wird, mit dem dann nacheinander alle
Berechnungen ausgeführt werden.
Ich probiere das die Tage mal aus, aber dann scheint das die sinnvollste
Lösung zu sein.
Peter Z. schrieb:> Ich meinte, dass ein Multiplizierer innerhalb der> jeweiligen Komponente erzeugt wird, mit dem dann nacheinander alle> Berechnungen ausgeführt werden.
Wenn Du das so haben willst, muß da ein Multiplexer und eine
State-Machine drumrum.
Duke
>> Ich meinte, dass ein Multiplizierer innerhalb der>> jeweiligen Komponente erzeugt wird, mit dem dann nacheinander alle>> Berechnungen ausgeführt werden.> Wenn Du das so haben willst, muß da ein Multiplexer und eine> State-Machine drumrum
Jepp, aber das wird schwerlich zu vermeiden sein, wenn ich einen
Multiplizierer mehrfach nutze?!
Peter Z. schrieb:> Hardware-Multiplizierer habe ich bisher keine instanziiert, da ich>> Multiplikation nach diesem Schema an mehreren Stellen durchführe, und>> deshalb in eine Funktion ausgelagert habe.
Das hört sich für mich an, wie eine ausgelagerte Funktion in C die
mehrfach benutzt wird.
R. K. schrieb:> Das hört sich für mich an, wie eine ausgelagerte Funktion in C die> mehrfach benutzt wird.
Ja, nur dass man diese Denkweise aus der Software-Entwicklung bei FPGAs
ganz schnell komplett vergessen muss.
Peter Z. schrieb:> Hardware-Multiplizierer habe ich bisher keine instanziiert,
Bist Du sicher, dass Dir Q keinen reininstanziiert hat?
Das tut es nämlich bei DER Beschreibung.
Zusammenfassend gesagt: du musst die zusammengebaute MUL nicht händisch
realisieren, sondern sie nur hinschreiben und das timing einhalten
(lassen). Einmal registriert / pipelined und der Arria müsste das
können.