performance eines Multipliers lässt sich nicht "improven"

Gast #2481248
Lesenswert?

Xilinx liefert im advisor, dass die performance des multipliers 
blahblahblah improved werden kann, wenn man nur noch ein register level 
addieren würde. Zunächst hatte er 2 Register vorgeschlagen, die ich auch 
implementiert habe. Nun will er immer wieder noch ein weiteres, obwohl 
ich inzwischen schon 3 FF stages dahin geklebt habe.

Ist das nun nur noch eine Phantonmeldung oder mache ich was falsch?

Der ominöse multiplier ist Teil eines Konstrukts in einer pipeline:
1
value_s3 <= std_logic_vector (unsigned (point_s2 & '0') * (unsigned (maxi & "10") - unsigned (point_s2 & '1')));
2

3
value_s4  <= value_s3;
4
value_s5  <= value_s4;
5
value_s6  <= value_s5;

weiterverwurstet wird nur der s6 - extra geprüft.

Bekommt er das wegen der Subtraktion nicht gebacken?
Gast #2481394
Lesenswert?

Jaromir schrieb:
> Ist das nun nur noch eine Phantonmeldung oder mache ich was falsch?
Das liegt daran, das in den DSP-Slices diese Register schon vergraben 
sind. Durch die weiteren Register (die ja eigentlich schon da sind) läßt 
sich (in Abhängigkeit vom restlichen Design) die Taktfrequenz erhöhen. 
Allerdings muß das Design auch mit der zusätzlichen Latenz klarkommen.

Wenn mein Design langsam ist (Größenordnung: 50 MHz), dann lass ich die 
Registerstufen weg. Wenn es schnell sein muß (ab 100 MHz), dann versuche 
ich die Pipelineregistern zu verwenden.

Duke
Moderator (Firma: Titel) Persönliche Seite #2482192
Lesenswert?

Jaromir schrieb:
> Bekommt er das wegen der Subtraktion nicht gebacken?
Probiers doch einfach mal aus: lass die Multiplikation getaktet auf ein 
Zwischenregister los. Viel Aufwand ist das ja nicht:
1
value_s3b <= unsigned(point_s2 & '0'); 
2
value_s3a <= unsigned(maxi & "10") - unsigned (point_s2 & '1');
3
value_s4  <= value_s3a * value_s3a;
4
value_s5  <= value_s4;
5
value_s6  <= std_logic_vector(value_s5);
Natürlich müssen jetzt die Datentypen für die Pipeline (zumindest 
teilweise) als unsigned agelegt werden...


Und/Oder such mal nach "Register-Balancing"....
Gast #2482926
Lesenswert?

Jaromir schrieb:
> Bekommt er das wegen der Subtraktion nicht gebacken?
Das ist möglich. Im UG389 findet sich die angehängte Grafik.
Da könnte er für die Subtraktion den Pre-Adder verwenden.

Wenn Du maximale Performance brauchst, kannst Du den DSP48-Slice auch 
von Hand instanziieren. Ansonsten würde ich es bei einer lesbaren, 
architekturunabhängigen Schreibweise belassen.

Duke
Angehängte Dateien:
Gast #2483077
Lesenswert?

Aber genau wegen des adders im DSP-slice sollte es ihm doch möglich 
sein, die SUB auszuführen und danach die MUL. Hinter der MUL ist nichts 
formuliert, daher gibt es da nichts, woran er sich stören kann.

Register balancing habe ich drin. Aber das ist ja ein aufwändiger 
Process.
Gast #2483173
Lesenswert?

Jaromir schrieb:
> Aber genau wegen des adders im DSP-slice sollte es ihm doch möglich
> sein, die SUB auszuführen und danach die MUL. Hinter der MUL ist nichts
> formuliert, daher gibt es da nichts, woran er sich stören kann.
Wenn's ein DSP48 werden soll, muß man sich an die Vorgaben halten. Die 
stehen z.B. im UG687 (v13.3) auf Seite 201: Pre-Adder Description With 
Explicit Data Extensions Coding Example

Hier scheint die Breite des Adders (resize) und der Datentyp (signed) 
relevant zu sein.

Mit diesem Code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5

6
entity infer_dsp48 is
7
    port (
8
        clk      : in  std_logic;
9
        point_s2 : in  std_logic_vector(6 downto 0);
10
        maxi     : in  std_logic_vector(5 downto 0);
11
        value_s6 : out std_logic_vector(15 downto 0)
12
    );
13
end entity infer_dsp48;
14

15
architecture rtl of infer_dsp48 is
16

17
    signal a     : signed( 7 downto 0);
18
    signal b     : signed(17 downto 0);
19
    signal c     : signed(15 downto 0) := (others => '0');
20
    signal d     : signed(17 downto 0);
21

22
    signal pre   : signed(17 downto 0);
23
    signal m     : signed(25 downto 0);
24
    signal p     : signed(25 downto 0);
25

26
begin
27

28
    a <= signed (point_s2 & '0');
29
    b <= resize( signed (point_s2 & '1'), 18);
30
    d <= resize( signed (maxi & "10"), 18);
31
    
32
    process
33
    begin
34
        wait until rising_edge( clk);
35
        pre <= d - b;
36
        m   <= pre * a;
37
        p   <= m + c;
38
    end process;
39
        
40
    value_s6  <= std_logic_vector( resize( p, 16));
41

42
end architecture rtl;
packt er - wie gewünscht - alles in DSP-Slice.
Ich hoffe ich habe Deine Signalnamen nicht verwechselt.

Duke
Angehängte Dateien:
Gast #2484190
Lesenswert?

D,h, man muss beim Xilinx die DSP slices manuell instanziieren, wenn man 
sicherstellen möchte, dass er es optimal baut?

Das ist aber tödlich, wenn man den Code portieren will. Ich kenne den 
Unsinn ja vom System Generator her, mit dem man immer genau 
Xilinx-Primtiven instanziert bekommt und sonst nichts. Die Katastrophe 
dabei ist, dass das System nicht mehr skaliert werden kann.

Bei meinen Designs möchte ich mal ein Bit hinzufügen und über die 
generics automatisch berechnen lassen. Das wird total verunmöglicht, 
wenn es durch die Grafiken oder die exzessive Nutzung der Primitiven 
eingefroren wird.

Ich habe den Thread nochmals durchgeblättert: Der TE hat doch nur eine 
Subtraktion vor der Multiplikation stehen. Ich verstehe noch nicht, 
warum das nicht einfach so wie in der ersten Zeichung von Duke 
angeschlossen wird. Das wäre es doch schon.
Gast #2484289
Lesenswert?

Na, wenn einem die slices so langsam ausgehen, wird das schon 
interessant. Wenigstens die Adder sollte man schon nutzen können und das 
mit full speed.

Andererseits ist dies nicht der einzig Fall, wo eine Xilinx Synthese 
einen Chip nicht optimal nutzt. In einem parallelen thread wird ja davon 
bereichtet, dass andere tools schneller lauffähigen code generieren 
können sollen. Ich habe leider keinen Zugriff auf Synplify o.ä. dass ich 
das mal austesten könnte. Wäre mal interessant, zu wissen, wie so ein 
Tool mit den standard HDL-Konstrukten wie oben umgeht und ob er die 
slices besser ausnutzt.
Gast #2484872
Lesenswert?

Frager schrieb:
> Der TE hat doch nur eine
> Subtraktion vor der Multiplikation stehen. Ich verstehe noch nicht,
> warum das nicht einfach so wie in der ersten Zeichung von Duke
> angeschlossen wird. Das wäre es doch schon.
Naja, da hat der Synthesizer eben noch Potential für Optimierungen.
Wie gesagt, wenn man mit resize auf die richtige Bitbreite geht und 
signed verwendet, macht er ja auch das richtige draus. Und der Code 
sieht immernoch einigermaßen generisch aus. Ich finde es zumindest 
besser lesbar, als wenn man das DPS-Primitiv direkt instanziieren würde.

Christian R. schrieb:
> Hm, die Frage ist, ist es denn in dem Fall überhaupt nötig, den DSP48
> optimal auszureizen? Solange das Timing erreicht wird, besteht doch da
> eigentlich keine Veranlassung, und der Code kann generisch
> hingeschrieben werden. Ich bekomm diese Meldung auch immer.
So sehe ich das eigentlich auch. Es ist ein ziemlicher Aufwand den Code 
passend zu optimieren. Wenn dann die nächste Chip-Generation oder ein 
Herstellerwechsel kommt, fängt man wieder damit an :-/
Also, wenn's Timing (oder die Ressourcen) nicht drückt, dann einfach so 
lassen.

Duke

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