www.mikrocontroller.net

Forum: FPGA, VHDL & Co. simple Addition zweier bit_vector(2 downto 0)


Autor: Richard Kocsis (richardk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Ich wollte in VHDL zwei 3Bit Zahlen addieren.
Der Resultierende Vektor muss also 4Bit aufweisen damit
nichts verloren geht.

Hier mein Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-------------------------------------------------------------------------------

entity unsigdAdd is

  port (
    signal Din1 : in  bit_vector(2 downto 0);  -- add value 1
    signal Din2 : in  bit_vector(2 downto 0);  -- add value 2
    signal summ : out bit_vector(2 downto 0)   -- added summ
    );

end unsigdAdd;
-------------------------------------------------------------------------------

architecture behav of unsigdAdd is

  signal temp : unsigned(2 downto 0);   -- internal temp

  
begin  -- behav
  
  temp <= unsigned(to_stdlogicvector(Din1)) + unsigned(to_stdlogicvector(Din2));

  summ <= to_bitvector(std_logic_vector(temp));
  
end behav;

Mache ich nun mein "summ" 4Bit breit, dann meckert
Modelsim. So wie im obrigen Code verliere ich jedoch
das 4te Bit :-(

Wie macht man so eine einfache
Addition korrekt?

Das selber Problem begegnet mir bei der
Multiplikation 3x3Bit = 9Bit

Gruss Richard

Autor: Richard Kocsis (richardk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Sacht mal..  mein Problem an sich, habe ich nun gelöst.
Anbei die Lösung.

Das ist ja ziemlich hirnverbrannt, muss man das wirklich so
umständlich realisieren?

In der Literatur wird einem stets geraten möglichst wo es nur
geht bit und bit_vector zu verwenden. Das, ist aus meiner
Sicht die Konsequenz.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-------------------------------------------------------------------------------

entity unsigdAdd is

  port (
    signal Din1 : in  bit_vector(2 downto 0);  -- add value 1
    signal Din2 : in  bit_vector(2 downto 0);  -- add value 2
    signal summ : out bit_vector(3 downto 0)   -- added summ
    );

end unsigdAdd;

-------------------------------------------------------------------------------

architecture behav of unsigdAdd is

  signal intVer : integer range 0 to 15;  -- internal temp
  
  
begin  -- behav
  
  intVer <= to_integer(unsigned(to_stdlogicvector(Din1))) + to_integer(unsigned(to_stdlogicvector(Din2)));

  summ <= to_bitvector(std_logic_vector(to_unsigned(intVer, summ'length)));
  
end behav;

Gruss Richard

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> signal summ : out bit_vector(3 downto 0)
Kein Mensch verwendet den Typ bit_vector an der Schnittstelle.

Nimm std_logic_vector, dann sparst du dir eine Cast-Ebene.
Und mit Unsigned kannst du auch rechnen.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity unsigdAdd is
  port (
    signal Din1 : in  std_logic_vector(2 downto 0);  -- add value 1
    signal Din2 : in  std_logic_vector(2 downto 0);  -- add value 2
    signal summ : out std_logic_vector(3 downto 0)   -- added summ
    );
end unsigdAdd;

architecture behav of unsigdAdd is
begin  -- behav
  summ <= std_logic_vector(unsigned(Din1)+unsigned(Din2));
end behav;

> Das ist ja ziemlich hirnverbrannt, muss man das wirklich so
> umständlich realisieren?
Durch die strenge Typprüfung macht es Sinn, sich um die Schnittstellen 
zu kümmern, und dort geeignete Typen zu verwenden. Ganz einfach wärs so:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity unsigdAdd is
  port (
    signal Din1 : in  unsigned(2 downto 0);  -- add value 1
    signal Din2 : in  unsigned(2 downto 0);  -- add value 2
    signal summ : out unsigned(3 downto 0)   -- added summ
    );
end unsigdAdd;

architecture behav of unsigdAdd is
begin  -- behav
  summ <= Din1 + Din2;
end behav;
Dann hat auch die Entity ihren Namen verdient ;-)

Autor: Richard Kocsis (richardk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lothar

Vielen Dank für deinen Antwort.

Mit deiner Antwort habe ich nun ein wenig an
mir selbst gezweifelt, ich dachte mindestens deine
erste Version mit:
summ <= std_logic_vector(unsigned(Din1)+unsigned(Din2));

Hätte ich bereits schon selbst einmal getestet.
Nun habe ich beide deiner Versionen noch ausprobiert.
Entweder habe ich einen zweiten Fehler in der Toolchain
oder deine beiden Varianten funktionieren nicht?

Ich habe meine lauffähige Version an deine 1. angepasst.

Altera Quartus II (Standart Synthese Altera) meldet:
"Error expression has 3 elements, but must have 4 elements"

Und nein Quartus meint damit nicht etwa "summ" sondern die
beiden Din's. Passe ich summ auf (2 downto 0) an funktionierts.
Dann stimmt aber die Addition nicht mehr. 3bit vec + 3bit vec = 4bit vec

Nun gut...

Zur Sicherheit habe ich noch Synplify befragt:
"Error Width mismatch, location has width 4, value 3"

Dann konnte ich gar nix mehr glauben...
Zur Sicherheit habe ich Copy & Paste deine überarbeitete Version
aus dem Forum genommen. Fehlanzeige, auch deine zweite
Variante mit unsigned definierten Port's brachte das selbe
Resultat.

Hast du noch eine Idee, was da ev. in der Toolchain
fehlerhaft sein könnte?

Gruss Richard

PS. Xilinx ISE meldet keinen Error, nur eine Warning.
    Schlimm ist jedoch, das im RTL der summ Vector an GND
    angebunden wird! :-( Dann lieber ein klarer Error.

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut
http://www.eda.org/comp.lang.vhdl/FAQ1.html#4.8.1
unsigned add; length of result = max(length of 1st par, length of 2nd par)

Also musst Du noch ein Bit dranhängen, damit es klappt:
summ <= std_logic_vector(unsigned("0" & Din1) + unsigned("0" & Din2));

Duke

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dafür gibt's die Funktion "resize" !

Autor: Richard Kocsis (richardk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

summ <= std_logic_vector(unsigned("0" & Din1) + unsigned("0" & Din2));

Diese Verion gefällt mir!

Danke auch für den Link...


Gruss Richard

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> unsigned add; length of result = max(length of 1st par, length of 2nd par)
Demanch reicht also auch die Erweiterung nur eines Vektors:
summ <= std_logic_vector(unsigned('0' & Din1) + unsigned(Din2));
Ausprobiert:  Es geht ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.