Forum: FPGA, VHDL & Co. [Xilinx Webpack]: Wie symbole aus einem "schematic" in VHDL fassen


von Heiko L. (drcaveman)


Lesenswert?

Hallo!

Wenn ich im Webpack ISE als Hardwarebeschreibung einen Schaltplan 
anlege, dann kann ich zum Beispiel ein Symbol namens ADSU8 platzieren, 
welches in "Spartan-3 Libraries Guide for Schematic Designs" erklärt 
wird- ich denke mal, dass diese "Konstrukte" sehr gut synthetisiert 
werden können ;).

Das ist ein Addierer/Subtrahierer mit Carry in/out und overflow out.
Ich will so etwas in VHDL beschreiben- aber es wird bei mir nur ein 
Addierer mit carry in und ein Addierer/Subtrahierer ohne carry 
synthetisiert.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity mod is
6
  Port
7
      (
8
        in_a : in  STD_LOGIC_VECTOR (7 downto 0);
9
        in_b : in  STD_LOGIC_VECTOR (7 downto 0);
10
        out_c : out  STD_LOGIC_VECTOR (7 downto 0);
11
        i_add : in  STD_LOGIC;
12
        i_addc : in  STD_LOGIC;
13
        i_sub : in  STD_LOGIC;
14
        carry_in : in  STD_LOGIC;
15
        carry_out : out  STD_LOGIC
16
      );
17
end mod;
18
19
architecture Behavioral of mod is
20
21
signal t_out : unsigned(8 downto 0);
22
signal t_ina : unsigned(8 downto 0);
23
signal t_inb : unsigned(8 downto 0);
24
signal t_carry_in : unsigned(0 downto 0);
25
26
begin
27
28
t_ina <= unsigned("0" & in_a);
29
t_inb <= unsigned("0" & in_b);
30
t_carry_in(0) <= carry_in;
31
32
t_out <=
33
          t_ina + t_inb + t_carry_in when i_addc = '1' else
34
          t_ina + t_inb when i_add = '1' else
35
          t_ina - t_inb when i_sub = '1' else
36
          "000000000";
37
          
38
carry_out <= t_out(8);
39
              
40
out_c <= std_logic_vector(t_out(7 downto 0));
41
42
end Behavioral;

Wie bekomme ich es mit VHDL hin, dass er mir das oben genannte Symbol 
synthetisiert.
Der Grund warum ich das möchte: ich denke mal, dass diese 
"vorgefertigten Module" ziemlich optimiert sein werden.

Danke!

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


Lesenswert?

Heiko L. schrieb:
> Wie bekomme ich es mit VHDL hin, dass er mir das oben genannte Symbol
> synthetisiert.
Wie etwas optimal zu beschreiben ist, steht im Synthesis Guideline. Das 
ist bei Xilinx der XST.pdf (in der jeweils aktuellen Version)

von Heiko L. (drcaveman)


Lesenswert?

Lothar Miller schrieb:

> Wie etwas optimal zu beschreiben ist, steht im Synthesis Guideline. Das
> ist bei Xilinx der XST.pdf (in der jeweils aktuellen Version)

Ah, wunderbar, Danke!

Dem PDF zufolge gibt es keinen fertigen Addierer/Subtrahierer mit carry 
in/out und overflow.

Ich werden mich mal durch die Schaltplaneingabe quälen und schauen was 
er denn da synthetisiert wenn ich den Baustein einbinde.

Selbst das neueste PDF nutzt auch noch "IEEE.STD_LOGIC_UNSIGNED".

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


Lesenswert?

Heiko L. schrieb:
> Selbst das neueste PDF nutzt auch noch "IEEE.STD_LOGIC_UNSIGNED".
Ja, blöd, sowas.  :-/

> Dem PDF zufolge gibt es keinen fertigen Addierer/Subtrahierer mit carry
> in/out und overflow.
Du kannst davon ausgehen, dass solche Elementaren Konstrukte auch aus 
eine HDL-Beschreibung (z.B. aus a+b) optimal implementiert werden. Denn 
genau solche Addierer kommen ja tagtäglich vor.

von Jan S. (jan_s)


Lesenswert?

Lothar Miller schrieb:
>> Selbst das neueste PDF nutzt auch noch "IEEE.STD_LOGIC_UNSIGNED".
> Ja, blöd, sowas.  :-/
Ich weis die Frage ist leicht OT, aber kann jemand einem totalen 
Synthese Anfänger mal erklären, warum das blöd ist?

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


Lesenswert?

Jan S. schrieb:
> Ich weis die Frage ist leicht OT, aber kann jemand einem totalen
> Synthese Anfänger mal erklären, warum das blöd ist?
Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Und besonders kriminell wird es, wenn (mit dem Argument: die ist nötig) 
zusätzlich die numeric_std mit eingebunden wird. Dann sind ein paar 
Datentypen und Casts doppelt definiert und es hagelt ganz seltsame 
Fehlermeldungen...
Noch ein paar Beiträge zum Thema:
Beitrag "Re: Maximum suchen"
Beitrag "Re: Syntaxfehler bei Simulation, kein Syntaxfehler bei Synthese"

von Jan S. (jan_s)


Lesenswert?

Danke Lothar! Lese ich mir mal durch.

von Heiko L. (drcaveman)


Lesenswert?

Lothar Miller schrieb:

> Du kannst davon ausgehen, dass solche Elementaren Konstrukte auch aus
> eine HDL-Beschreibung (z.B. aus a+b) optimal implementiert werden. Denn
> genau solche Addierer kommen ja tagtäglich vor.

Macro Statistics
# Adders/Subtractors                                   : 2
 9-bit adder carry in                                  : 1
 9-bit addsub                                          : 1

Da muss ich ja wohl noch n bisschen basteln ;)
Das Schaltplansymbol wird übrigens in HDL durch ganz viele 
Standardgatter beschrieben :(

von berndl (Gast)


Lesenswert?

Bloede Frage: Warum willst du das eigentlich?

Du schreibst oben, dass du eine bestimmte Komponente des FPGA als 
optimal gefunden hast. Dann instanzier die halt direkt!

Ob dir das mittel-/langfristig was bringt, wage ich mal zu bezweifeln. 
Eine andere/neuere Toolchain, ein Wechsel auf eine andere FPGA 
Technologie und erst recht ein Wechsel auf einen anderen Hersteller 
moegen ganz andere Ergebnisse bringen. Bei den 'grossen' lassen sich 
durch bestimmte VHDL/Verilog Konstrukte die vorhandenen Bloecke (z.B. 
Multiplier, embedded SRAM, ...) ganz gut 'inferieren', aber eine 
Garantie gibt's dafuer eigentlich nicht.

Also, was stoert dich an dem output der Synthese? Wenn's akademisch ist, 
dann musst du halt auf die 'Assembler-Ebene' runter...

von Heiko L. (drcaveman)


Lesenswert?

berndl schrieb:
> Bloede Frage: Warum willst du das eigentlich?

Ich weiß, dass das Synthesewerkzeug diese Komponente kennt, aber ich 
bekomme es mit VHDL nicht hin es nachzubilden, das wurmt mich.
Ich fange auch gerade mal wieder mit VHDL an (irgendwie kommt immer 
etwas dazwischen) und da finde ich, dass das auch eine gute Übung ist 
sich mit dem Zeug auseinander zu setzen. Ist doch kein schlechtes 
Zeichen wenn ich mich so Ausdrücken kann, dass das Synthesewerkzeug 
direkt erkennt was ich meine und es daraufhin optimieren kann.

> Du schreibst oben, dass du eine bestimmte Komponente des FPGA als
> optimal gefunden hast. Dann instanzier die halt direkt!

Ich bin mir nicht Sicher, dass das eine "Hardwarekomponente" des 
Spartan-3e ist. Ich weiß nur, dass es beim Synthesewerkzeug in der 
Schaltplanebene eine derartige Komponente gibt.
Anhand dem "XST User Guide" weiß ich nun zumindest, dass das 
Synthesewerkzeug zumindest einen "Unsigned 8-Bit Adder With Carry In and 
Carry Out" und einen "Unsigned 8-Bit Adder/Subtractor" erkennen müsste.

> Ob dir das mittel-/langfristig was bringt, wage ich mal zu bezweifeln.
> Eine andere/neuere Toolchain, ein Wechsel auf eine andere FPGA
> Technologie und erst recht ein Wechsel auf einen anderen Hersteller
> moegen ganz andere Ergebnisse bringen. Bei den 'grossen' lassen sich
> durch bestimmte VHDL/Verilog Konstrukte die vorhandenen Bloecke (z.B.
> Multiplier, embedded SRAM, ...) ganz gut 'inferieren', aber eine
> Garantie gibt's dafuer eigentlich nicht.

Das weiß ich, aber wenn ich von Anfang an lerne wie man etwas 
"Synthesefreundlich" schreibt kann das ja für später nicht schlecht sein 
oder?
Gut, ich könnte ja auch gerade auf einen der unzähligen Xilinx- Bugs 
rein fallen...

> Also, was stoert dich an dem output der Synthese?

Das sie "zu viel" erkennt.

von Heiko L. (drcaveman)


Lesenswert?

Also es liegt wohl irgendwie an der ISE im Zusammenspiel mit 
numeric_std.

Folgender Code aus dem "XST User Guide" erzeugt einen "8-bit adder carry 
in/out"
1
--
2
-- Unsigned 8-bit Adder with Carry In and Carry Out
3
--
4
library ieee;
5
use ieee.std_logic_1164.all;
6
use ieee.std_logic_arith.all;
7
use ieee.std_logic_unsigned.all;
8
9
entity adders_4 is
10
  port
11
      (
12
        A,B : in std_logic_vector(7 downto 0);
13
        CI : in std_logic;
14
        SUM : out std_logic_vector(7 downto 0);
15
        CO : out std_logic
16
      );
17
end adders_4;
18
19
architecture archi of adders_4 is
20
21
  signal tmp: std_logic_vector(8 downto 0);
22
23
begin
24
  tmp <= conv_std_logic_vector((conv_integer(A) + conv_integer(B) + conv_integer(CI)),9);
25
  SUM <= tmp(7 downto 0);
26
  CO <= tmp(8);
27
end archi;

Number of Slices: 4
Number of 4 input LUTs: 8
Number of bonded IOBs: 26
Maximum combinational path delay: 7.831ns

Wenn ich das nun auf numeric_std umbaue, dann kommt nur noch ein "8-bit 
adder carry in" und die Warnung "Width mismatch. <tmp> has a width of 9 
bits but assigned expression is 8-bit wide" heraus:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity adders_4 is
6
  port
7
      (
8
        A,B : in std_logic_vector(7 downto 0);
9
        CI : in std_logic;
10
        SUM : out std_logic_vector(7 downto 0);
11
        CO : out std_logic
12
      );
13
end adders_4;
14
15
architecture archi of adders_4 is
16
17
  signal c_u: unsigned(0 downto 0);
18
  signal tmp: std_logic_vector(8 downto 0);
19
20
begin
21
  c_u(0) <= CI;
22
  tmp <= std_logic_vector(unsigned(A) + unsigned(B) + c_u);
23
  SUM <= tmp(7 downto 0);
24
  CO <= tmp(8);
25
end archi;

Number of Slices: 4
Number of 4 input LUTs: 8
Number of bonded IOBs: 26
Maximum combinational path delay: 7.831ns

Am Ende scheint ja wohl doch das gleiche heraus zu kommen.

Wobei ich mich auch noch frage wie ich das temporäre Signal c_u und die 
Warnung vermeiden kann.

von Jan S. (jan_s)


Lesenswert?

Heiko L. schrieb:
> Macro Statistics
> # Adders/Subtractors                                   : 2
>  9-bit adder carry in                                  : 1
>  9-bit addsub                                          : 1
>
> Da muss ich ja wohl noch n bisschen basteln ;)

Ich würde jetzt mal als Anafänger sagen, so lange du in deinem 
Behavioral mit 9 Bit Vektoren rechnest, entspricht das Ergebnis deiner 
Beschreibung.

von Jan S. (jan_s)


Lesenswert?

Wie sieht es damit aus?
Man möge mir nachsehen wenn das total falsch ist, evtl. lerne ich was 
dabei. ;)
1
architecture archi of adders_4 is
2
3
  signal c_u: unsigned(0 downto 0);
4
  signal tmp: unsigned(8 downto 0);
5
6
begin
7
  c_u(0) <= CI;
8
  tmp <= unsigned(A) + unsigned(B) + c_u;
9
  SUM <= std_logic_vector(tmp(7 downto 0));
10
  CO <= tmp(8);
11
end archi;

von Heiko L. (drcaveman)


Lesenswert?

Die Warnung besteht da weiterhin- unsigned(A) und unsigned(B) sind ja 
immer noch 8 bit breit.

von Christian R. (supachris)


Lesenswert?

Mach mal ein resize auf 9 Bit bei allen Summanden.

von Jan S. (jan_s)


Lesenswert?

Hm ok, dann war dass eine doofe Idee.
Wie geht man in VHDL dann vor, wenn man eine Summe berechnen will, 
welche größer als die Maximalwerte der Operanden sein kann?

von Heiko L. (drcaveman)


Lesenswert?

Christian R. schrieb:
> Mach mal ein resize auf 9 Bit bei allen Summanden.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity adders_4 is
6
  port
7
      (
8
        A,B : in std_logic_vector(7 downto 0);
9
        CI : in std_logic;
10
        SUM : out std_logic_vector(7 downto 0);
11
        CO : out std_logic
12
      );
13
end adders_4;
14
15
architecture archi of adders_4 is
16
17
  signal c_u: unsigned(0 downto 0);
18
  signal a_u: unsigned(8 downto 0);
19
  signal b_u: unsigned(8 downto 0);
20
  signal tmp: unsigned(8 downto 0);
21
22
begin
23
  c_u(0) <= CI;
24
  a_u <= unsigned("0" & A);
25
  b_u <= unsigned("0" & B);
26
  
27
  tmp <= a_u + b_u + c_u;
28
  SUM <= std_logic_vector(tmp(7 downto 0));
29
  CO <= tmp(8);
30
end archi;

Dann baut er (wie ganz oben) "9-bit adder carry in" (wird wohl auch aufs 
gleiche hinaus laufen, aber irgendwie schon komisch).

Number of Slices: 4
Number of 4 input LUTs: 8
Number of bonded IOBs: 26
Maximum combinational path delay: 7.831ns

von Christian R. (supachris)


Lesenswert?

Jan S.: So wie ich geschrieben habe. Die Summe muss so breit sein wie 
der maximal zu erwartende Wert incl. Vorzeichen. Die Summanden werden 
vor dem Summieren mit Resize auf die gleiche Breite gebracht.

Heiko L.:
0& klappt aber nur bei unsigned. Nimm lieber resize, das erweitert 
vorzeichenbehaftet.
Was ist am Ergebnis komisch? Ein Spartan 3 hat keine dedizierten 
Addierer, das wird eh in den LUTs abgebildet. Wo ist denn dein problem? 
Auch der Addirer aus dem Schematic wird in LUTs umgesetzt. Und das meist 
sogar schlechter als VHDL, ich hab jedenfalls signifikante Ressourcen- 
und Geschwindigkeits-Gewinne erzielen können, als ich ein Design, was 
komplett in Schematics war, von einem Kollegen übernommen und in VHDL 
umgesetzt habe.

von Heiko L. (drcaveman)


Lesenswert?

Christian R. schrieb:

> 0& klappt aber nur bei unsigned. Nimm lieber resize, das erweitert
> vorzeichenbehaftet.

Ok, danke.

> Was ist am Ergebnis komisch? Ein Spartan 3 hat keine dedizierten
> Addierer, das wird eh in den LUTs abgebildet. Wo ist denn dein problem?

Weil der je nachdem andere "Grundkomponenten" erkennt:

8-bit adder carry in/out
8-bit adder carry in
9-bit adder carry in

Gut, am Ende kommt das Gleiche dabei raus, aber so ganz vertrauenswürdig 
finde ich das jetzt nicht.
Eine Testbench ist wohl wirklich immer angesagt.

> Auch der Addirer aus dem Schematic wird in LUTs umgesetzt.

Ja und das ist wohl für die verschiedenen FPGAs schon fix und fertig 
angelegt.

> Und das meist
> sogar schlechter als VHDL, ich hab jedenfalls signifikante Ressourcen-
> und Geschwindigkeits-Gewinne erzielen können, als ich ein Design, was
> komplett in Schematics war, von einem Kollegen übernommen und in VHDL
> umgesetzt habe.

Da die "Schaltplanübersetzungen" schon fix und fertig vorliegen sollte 
der compiler bei VHDL auch mehr Freiheiten haben.

von Christian R. (supachris)


Lesenswert?

Heiko L. schrieb:
> Weil der je nachdem andere "Grundkomponenten" erkennt:

Naja....der sagt nur, was er erkannt hat. Bei mir erkennt er 1-of-64 
decoder, Multiplexer, 20-Bit Schieberegister usw. aber die gibts auf 
einem FPGA genauso wenig wie Addierer.

> Gut, am Ende kommt das Gleiche dabei raus, aber so ganz vertrauenswürdig
> finde ich das jetzt nicht.

Was ist daran nicht vertrauenswürdig? Der implementiert das, was du 
beschreibst.

> Eine Testbench ist wohl wirklich immer angesagt.

Das steht außer Frage, bei jedem Projekt.

>> Auch der Addirer aus dem Schematic wird in LUTs umgesetzt.
>
> Ja und das ist wohl für die verschiedenen FPGAs schon fix und fertig
> angelegt.

Naja, das sind die Standard-Lösungen mit Gattern. Die existieren in 
keinem FPGA. Die haben immer LUTs, mit 4 oder 6 Eingängen bei Xilinx. 
zusätzlich dazu gibts die Carry-Leitungen, die in verschiedenen Arten 
implementiert sind.

Mit den Schematics würd ich nicht mehr anfangen. Der Editor und auch die 
Symbole da sind aus dem vorigen Jahrtausend und sehr...."suboptimal".

von Heiko L. (drcaveman)


Lesenswert?

Christian R. schrieb:
>
> Naja....der sagt nur, was er erkannt hat. Bei mir erkennt er 1-of-64
> decoder, Multiplexer, 20-Bit Schieberegister usw. aber die gibts auf
> einem FPGA genauso wenig wie Addierer.

So allgemein kann man das jetzt nicht sagen, IMHO gibt es FPGAs mit 
Addierern.

> Was ist daran nicht vertrauenswürdig? Der implementiert das, was du
> beschreibst.

Aus meiner Sicht beschreibe ich immer das Gleiche und er erkennt 
verschiedene Sachen- nur das, was er erkennen soll erkennt er nicht ;)

> Mit den Schematics würd ich nicht mehr anfangen. Der Editor und auch die
> Symbole da sind aus dem vorigen Jahrtausend und sehr...."suboptimal".

Hatte ich auch nicht vor.

von Christian R. (supachris)


Lesenswert?

Heiko L. schrieb:
> So allgemein kann man das jetzt nicht sagen, IMHO gibt es FPGAs mit
> Addierern.

Stimmt, verallgemeinern kann man das nicht. Aber du hast vom Startan 3 
angefangen, und der hat keine dedizierten Addierer.

> Aus meiner Sicht beschreibe ich immer das Gleiche und er erkennt
> verschiedene Sachen- nur das, was er erkennen soll erkennt er nicht ;)

Hmm....ich hab den Sinn dahinter immer noch nicht kapiert. Je nach 
Optimierungseinstellungen kann das schon wieder ganz anders aussehen. 
Wichtig ist die Funktion die rauskommt. Und wenn man A+B hinschreibt, 
wird A+B realisiert. Auf was genau willst du denn mit deinen 
"Untersuchungen" hinaus?

von Heiko L. (drcaveman)


Lesenswert?

Christian R. schrieb:

> Wichtig ist die Funktion die rauskommt. Und wenn man A+B hinschreibt,
> wird A+B realisiert. Auf was genau willst du denn mit deinen
> "Untersuchungen" hinaus?

Ich wollte eigentlich nur wissen was ich falsch mache, weil eben nicht 
der 8 Bit Addierer mit Carry in/out erkannt wird. Aber scheinbar ist das 
nun mal so.

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


Lesenswert?

Heiko L. schrieb:
> Ich wollte eigentlich nur wissen was ich falsch mache, weil eben nicht
> der 8 Bit Addierer mit Carry in/out erkannt wird.
Evtl. ist eine dir komplizierter erscheinende Konfiguration universeller 
und braucht gleich viel Ressourcen. Und warum sollte dann ein 
reduziertes Modell verwendet werden?

> Aber scheinbar ist das nun mal so.
Ja, das wird die Toolchain schon richtig machen. Ein Addierer ist keine 
allzu ungewöhnliche Funktion... ;-)

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.