Abschätzung/Optimierung f_max einer Multiplikation

OP #2732212
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
(Firma: abaxor engineering) #2732244
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
Moderator (Firma: Titel) Persönliche Seite #2732249
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?
OP #2732264
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.
Moderator (Firma: Titel) Persönliche Seite #2732268
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...
OP #2732292
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.
Gast #2732303
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
(Firma: abaxor engineering) #2732328
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
Gast #2732552
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 !
OP #2732609
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.
OP #2732613
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?!
Gast #2817667
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren