Forum: FPGA, VHDL & Co. Abschätzung/Optimierung f_max einer Multiplikation


von Peter Z. (starkstrompeter)


Lesenswert?

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
1
...
2
3
signal d_in       : std_logic_vector(31 downto 0);
4
signal par_factor : std_logic_vector(31 downto 0);
5
signal res_mult   : std_logic_vector(31 downto 0);
6
7
...
8
9
case state is
10
   when MULT =>
11
      if trig_in = '1' then      
12
         -- Multiply with scaling factor
13
         res_mult <= mult(d_in, par_factor);
14
      end if;  
15
   ...
16
end case;
17
18
...
19
20
function mult (a, b : signed) return signed is
21
   variable temp     : signed((a'length * 2) - 1 downto 0);
22
   variable ov_check : signed((a'length / 2) downto 0); 
23
   variable ret      : signed(a'range);
24
begin
25
   -- Multiply
26
   temp := a * b;    
27
   
28
   -- Check for overflow
29
   ov_check := temp(temp'left downto temp'left - (a'length / 2));
30
   if (ov_check = 0) or (ov_check = -1) then
31
   -- No overflow occured, resize   
32
      ret := temp(temp'left) & temp(temp'left - (a'length / 2) - 1 downto (a'length / 2));
33
   elsif(ov_check(ov_check'left) = '0') then
34
      ret := '0' & ((ret'left - 1) downto 0 => '1');
35
   else
36
      ret := '1' & ((ret'left - 1) downto 0 => '0');
37
   end if;
38
39
   return ret;
40
end function;

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

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

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

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


Lesenswert?

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
entity Multiply32x32 is
2
    Port ( a : in  STD_LOGIC_VECTOR (31 downto 0);
3
           b : in  STD_LOGIC_VECTOR (31 downto 0);
4
           q : out  STD_LOGIC_VECTOR (31 downto 0);
5
           clk : in  STD_LOGIC);
6
end Multiply32x32;
7
8
architecture Behavioral of Multiply32x32 is
9
signal la,lb,lq : unsigned (31 downto 0);
10
begin
11
  la <= unsigned(a);
12
  lb <= unsigned(b);
13
14
  process begin
15
    wait until rising_edge(clk);
16
    lq <= la*lb;
17
    q <= std_logic_vector(lq);
18
  end process;
19
20
end Behavioral;

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?

von Peter Z. (starkstrompeter)


Lesenswert?

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.

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


Lesenswert?

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

von Peter Z. (starkstrompeter)


Lesenswert?

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

von Vanilla (Gast)


Lesenswert?

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

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

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

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


Lesenswert?

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.

von Peter Z. (starkstrompeter)


Lesenswert?

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.

von Klaus F. (kfalser)


Lesenswert?

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 !

von Uwe (Gast)


Lesenswert?

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

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


Lesenswert?

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

von Peter Z. (starkstrompeter)


Lesenswert?

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

von Duke Scarring (Gast)


Lesenswert?

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

von Peter Z. (starkstrompeter)


Lesenswert?

>> 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?!

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Dipl.-Ing. (TH) (Gast)


Lesenswert?

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.

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.