Division mit verschiedenen Werten

Gast #1430776
Lesenswert?
• ▲
▼
Hi

Arbeite gerade an einen Design in dem ich abhängig von einen Counterwert 
2 verschiedene Werte zusammenaddieren muss und diese dann durch 2 
Rechnen muss. Eigentlich wäre dafür ja eine shift operation perfekt 
allerdings ist der Wert ein signed. Daher mache ich eine normale 
division durch 2. Nun ist meine Frage ob es besser ist das ich die zwei 
werte zuerst zusammenzähle und in eine Variable schreibe die ich nacher 
dividiere oder kann ich für jeden fall einen mittels if abfrage 
unterscheiden und in jeden zweig eine Division machen? Was ist vorallem 
in Bezug auf synthese besser?

Fall 1:

if i = 1 then
  result <= ((zahl1 + zahl2) / 2)
if i = 2 then
  result <= ((zahl1 + zahl3) / 2)
if i = 2 then
  result <= ((zahl2 + zahl3) / 2)
end if

oder

Fall 2:

if i = 1 then
  tmp := ((zahl1 + zahl2) / 2)
if i = 2 then
  tmp := ((zahl1 + zahl3) / 2)
if i = 2 then
  tmp := ((zahl2 + zahl3) / 2)
end if
result <= (tmp / 2)

Vielleicht weiß jemand von euch welcher der beiden Fälle besser für die 
HW.

MFG Gast
Gast #1430782
Lesenswert?
• ▲
▼
Simulier und synthetisier es doch einfach mal und guck was hinterher 
rauskommt.

DAS könnte jedenfalls interessant werden ;) :

if *i = 2* then
  tmp := ((zahl1 + zahl3) / 2)
if *i = 2* then
  tmp := ((zahl2 + zahl3) / 2)
Gast #1430790
Lesenswert?
• ▲
▼
Das die if abfrage zweimal 2 abfragt ist natürlich ein tippfehler. Kommt 
durch copy and paste. Gibt es sonst eine Möglichkeit die Division in 
VHDL zu machen oder ist das eh der Standard weg um einen signed typ zu 
dividieren?
Gast #1430820
Lesenswert?
• ▲
▼
Hi

Was ich vorher vergessen habe die Zahlen Zahl1, Zahl2 und Zahl3 sind 
std_logic_vector die mit Hilfe von signed fürs rechnen umgewandelt 
werden. Das Ergebnis ist wieder ein std_logic_vector. tmp ist eine 
Variable die ebenfalls std_logic_vector ist. Kann ich davon ausgehen das 
beide Varianten das Ergebnis innerhalb eines Taktzyklus haben oder kann 
es da auch unterschiede geben. Suche eigentlich die Variante die am 
wenigsten Logic braucht.
DANKE

Hatte noch einen Fehler in Fall 2

Fall 2:

if i = 1 then
  tmp := (zahl1 + zahl2)
if i = 2 then
  tmp := (zahl1 + zahl3)
if i = 3 then
  tmp := (zahl2 + zahl3)
end if
result <= (tmp / 2)


MFG Gast
Gast #1430881
Lesenswert?
• ▲
▼
hmmm...
tmp := (zahl1 + zahl2)

Pass auf, dass tmp breit genug ist, sonst bekommst du schnell einen 
Überlauf bei größeren Summanden.

Das beste Syntheseergebnis bekommst du meist nur durch testen raus.
Kannst gerne posten, was die Synthese dir als Resultat ausgibt und dann 
kann man ans optimieren denken. Jedes Synthesewerkzeug hat seine 
"Eigenheiten".
Probieren geht über studieren.

Der Besucher
Gast #1430939
Lesenswert?
• ▲
▼
Wenn es sich um signed-Division handelt und du möchtest das 
syntethisieren, dann nimm lieber dann shifte lieber (arithmetisch 
natürlich - dann ist das kein Problem).

Siehe mein Posting von letzter Wochen:
Beitrag "right_shift und "/" liefern unterschiedliche Ergbnisse"

Synthesiere doch einfach mal beide Varianten (also Shift und Division) 
und stell deine Syntheseergebnisse hier rein. Würde mich mal 
interessieren...
Gast #1430952
Lesenswert?
• ▲
▼
Hi

Habe das ganze nun mal getestet und folgende ergebnisse bekommen

Fall 1(division in jeden Zweig)

 Minimum period: 14.499ns (Maximum Frequency: 68.970MHz)

 Number of Slices:                      834  out of  20480     4%
 Number of Slice Flip Flops:            305  out of  40960     0%
 Number of 4 input LUTs:               1596  out of  40960     3%
 Number of IOs:                         175
 Number of bonded IOBs:                 132  out of    333    39%
 Number of GCLKs:                         1  out of      8    12%

Fall 2(einmalige Division am Ende)

 Minimum period: 16.059ns (Maximum Frequency: 62.272MHz)

 Number of Slices:                      820  out of  20480     4%
 Number of Slice Flip Flops:            343  out of  40960     0%
 Number of 4 input LUTs:               1576  out of  40960     3%
 Number of IOs:                         175
 Number of bonded IOBs:                 132  out of    333    39%
 Number of GCLKs:                         2  out of      8    25%

Fall 3 (shiften um 1 nach rechts und oberstes Bit setzen damit negative 
Werte richtig sind und kleinstes Bit setzen damit richtig abgerundet 
wird ei negativen Werten)

 Minimum period: 14.534ns (Maximum Frequency: 68.802MHz)

 Number of Slices:                      871  out of  20480     4%
 Number of Slice Flip Flops:            341  out of  40960     0%
 Number of 4 input LUTs:               1673  out of  40960     4%
 Number of IOs:                         175
 Number of bonded IOBs:                 132  out of    333    39%
 Number of GCLKs:                         2  out of      8    25%

Welches würdet ihr nun als beste Variante bezeichnen. Eigentlich doch 
die Variante mit der Division in jeden Zweig oder?

MFG Gast
Gast #1432076
Lesenswert?
• ▲
▼
Ich wuerde die if statements noch durch ein switch/case ersetzen. Die if 
statements verursachen je nach Synthese einen Priority-Tree vor den 
Arithmetik-Einheiten, den Du nicht(?) brauchst. switch/case erzeugt 
einen Balanced-Tree und erlaubt einfacheres Ressource-Sharing von 
Addierern und Dividierern.
Moderator (Firma: Titel) Persönliche Seite #1433144
Lesenswert?
• ▲
▼
1
 :
2
 Number of Slices:                      834  out of  20480     4%
3
 Number of Slice Flip Flops:            305  out of  40960     0%
4
 Number of 4 input LUTs:               1596  out of  40960     3%
5
 :
Da ist aber offenbar noch einiges mehr im Spiel...


Hier meine Erkenntnisse:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity SignalVsVariable is
6
    Port ( z1 : in  STD_LOGIC_VECTOR (7 downto 0);
7
           z2 : in  STD_LOGIC_VECTOR (7 downto 0);
8
           z3 : in  STD_LOGIC_VECTOR (7 downto 0);
9
           res : out STD_LOGIC_VECTOR (7 downto 0);
10
           s  : in  STD_LOGIC_VECTOR (1 downto 0));
11
end SignalVsVariable;
12

13
architecture Behavioral of SignalVsVariable is
14
signal zahl1 : integer range -128 to 127;
15
signal zahl2 : integer range -128 to 127;
16
signal zahl3 : integer range -128 to 127;
17
signal result : integer range -128 to 127;
18
signal i : integer range 1 to 3;
19
begin
20
   zahl1 <= to_integer(signed(z1));
21
   zahl2 <= to_integer(signed(z2));
22
   zahl3 <= to_integer(signed(z3));
23
   i     <= to_integer(unsigned(s));
24
   
25
   --  21 Slices, 37 Luts, Maximum combinational path delay: 15.656ns
26
   process (zahl1,zahl2,zahl3,i)
27
   variable tmp : integer range -256 to 255;
28
   begin
29
      case i is
30
      when 1      => tmp := (zahl1 + zahl2);
31
      when 2      => tmp := (zahl1 + zahl3);
32
      when others => tmp := (zahl2 + zahl3); -- Defaultzuweisung
33
      end case;
34
      result <= tmp/2;
35
   end process;
36

37
   -- 57 Slices, 103  Luts, Maximum combinational path delay:  16.236ns
38
   process (zahl1,zahl2,zahl3,i)
39
   begin
40
      case i is
41
      when 1      => result <= ((zahl1 + zahl2) / 2);
42
      when 2      => result <= ((zahl1 + zahl3) / 2);
43
      when others => result <= ((zahl2 + zahl3) / 2); -- Defaultzuweisung
44
      end case;
45
   end process;
46
   
47
   -- 62 Slices,  107 Luts
48
   process (zahl1,zahl2,zahl3,i)
49
   begin
50
      result <= ((zahl2 + zahl3) / 2); -- Defaultzuweisung
51
      if i = 1 then  result <= ((zahl1 + zahl2) / 2);  end if;
52
      if i = 2 then  result <= ((zahl1 + zahl3) / 2);  end if;
53
   end process;
54

55
   -- 62 Slices,  107 Luts
56
   process (zahl1,zahl2,zahl3,i) 
57
   begin
58
      if    i = 1 then  result <= ((zahl1 + zahl2) / 2);  
59
      elsif i = 2 then  result <= ((zahl1 + zahl3) / 2);  
60
      else              result <= ((zahl2 + zahl3) / 2);  
61
      end if;
62
   end process;
63

64
   -- 46 Slices,  81 Luts, Maximum combinational path delay: 16.187ns
65
   process (zahl1,zahl2,zahl3,i) 
66
   begin
67
      result <= 0; -- Defaultzuweisung gegen Latches
68
      if i = 1 then  result <= ((zahl1 + zahl2) / 2);  end if;
69
      if i = 2 then  result <= ((zahl1 + zahl3) / 2);  end if;
70
      if i = 3 then  result <= ((zahl2 + zahl3) / 2);  end if;
71
   end process;
72

73
   -- 46 Slices,  81 Luts, Latches!!!!
74
   process (zahl1,zahl2,zahl3,i) 
75
   begin
76
      if i = 1 then  result <= ((zahl1 + zahl2) / 2);  end if;
77
      if i = 2 then  result <= ((zahl1 + zahl3) / 2);  end if;
78
      if i = 3 then  result <= ((zahl2 + zahl3) / 2);  end if;
79
   end process;
80

81
   -- ohne Defaultzuweisung: 27 Slices, 47 Luts, Maximum combinational path delay: 18.129ns
82
   -- mit Defaultzuweisung:  19 Slices, 33 Luts, Maximum combinational path delay: 13.144ns
83
   process (zahl1,zahl2,zahl3,i)
84
   variable tmp : integer range -256 to 255;
85
   begin
86
      tmp := 0; -- Defaultzuweisung
87
      if i = 1 then  tmp := (zahl1 + zahl2);  end if;
88
      if i = 2 then  tmp := (zahl1 + zahl3);  end if;
89
      if i = 3 then  tmp := (zahl2 + zahl3);  end if;
90
      result <= tmp/2;
91
   end process;
92
   
93
   res <= std_logic_vector(to_signed(result,8));
94
   
95
end Behavioral;
Bitte selber bewerten ;-)
Gast #1433223
Lesenswert?
• ▲
▼
@Lothar

Was sagt deine Synthese zu folgendem?
Hier ist der Fall i=0 und i=3 zusammengefasst.
Aber i ist auch nur im Bereich von 1 bis 3 definiert. Merkt das 
Sythesewerkzeug, das i=0 don't care ist?

Der Besucher


   process (zahl1,zahl2,zahl3,i)
   variable tmp : integer range -256 to 255;
   begin
      tmp := (zahl2 + zahl3); -- Defaultzuweisung
      if i = 1 then  tmp := (zahl1 + zahl2);  end if;
      if i = 2 then  tmp := (zahl1 + zahl3);  end if;
      result <= tmp/2;
   end process;
Moderator (Firma: Titel) Persönliche Seite #1433234
Lesenswert?
• ▲
▼
Das kommt dabei raus:
1
   -- 21 Slices,  37 Luts,  Maximum combinational path delay: 15.656ns
2
   process (zahl1,zahl2,zahl3,i)
3
   variable tmp : integer range -256 to 255;
4
   begin
5
      tmp := (zahl2 + zahl3); -- Defaultzuweisung
6
      if i = 1 then  tmp := (zahl1 + zahl2);  end if;
7
      if i = 2 then  tmp := (zahl1 + zahl3);  end if;
8
      result <= tmp/2;
9
   end process;

Insgesamt scheint mir das Beispiel ziemlich vertrakt, u.a. auch wegen 
des Index, der erst bei 1 losgeht...
Und dann natürlich wegen der Latches, die es im Original-Post Fall 1 
gibt.
Gast #1433248
Lesenswert?
• ▲
▼
Und was ist hiervon zu halten? Hier werden die Eingänge gemultiplext.
Ausserdem wird ausserdem ausgenutzt, dass a+b=b+a ist.

   process (zahl1,zahl2,zahl3,i)
   variable summand1 : integer range -128 to 127;
   variable summand2 : integer range -128 to 127;
   begin
      summand1 := zahl2; -- Defaultzuweisung
      summand2 := zahl3; -- Defaultzuweisung
      if i = 1 then  summand2 := zahl1; end if;
      if i = 2 then  summand1 := zahl1; end if;
      result <= (summand1 + summand2)/2;
   end process;
Gast #1433598
Lesenswert?
• ▲
▼
@ Lothar:

Könntest du bitte noch mal prüfen, ob dieser Code (mit Shift anstelle 
Division) noch weniger verbraucht:
1
   process (zahl1,zahl2,zahl3,i)
2
   variable tmp : integer range -256 to 255;
3
   begin
4
      tmp := 0; -- Defaultzuweisung
5
      if i = 1 then  tmp := (zahl1 + zahl2);  end if;
6
      if i = 2 then  tmp := (zahl1 + zahl3);  end if;
7
      if i = 3 then  tmp := (zahl2 + zahl3);  end if;
8
      result <= shift_right(tmp,1);
9
   end process;

Danke!
Moderator (Firma: Titel) Persönliche Seite #1433617
Lesenswert?
• ▲
▼
Klar, was dabei herauskommt:
1
    shift_right can not have such operands in this context.
Ok, also etwas hin- und herkonvertiert:
1
      result <= to_integer(shift_right(to_signed(tmp,9),1));
Und dann das Ergebnis
   -- 17 Slices,  30 Luts, Maximum combinational path delay:   12.988ns

Aber bei negativen Zahlen ist  /  nicht das selbe wie  shift_right
Beitrag "Re: right_shift und "/" liefern unterschiedliche Ergbnisse"
Gast #1440100
Lesenswert?
• ▲
▼
@dose
benötigst du wirklich jeden Takt ein Rechenergebnis?
Wenn nicht, ist es auch möglich eine Multicycle-Rechenoperation 
durchzuführen. Man muss den entsprechenden Pfad nur der Synthese 
mitteilen und der Rechenoperation soviele Takte zugestehen, wie sie 
benötigt. Alles ohne zusätzliche Register.
Und wenn jeden Takt ein Ergebnis benötigt wird, kann man immer noch 
mehrere Multicycle-Rechenwerke parallel aufbauen, die zeitversetzt 
arbeiten.

Der Besucher

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.