www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Subtrahieren bei STD_LOGIC_VECTOR


Autor: B. U. (peggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte zwei STD_LOGIC_VECTOR Variablen voneinander abziehen.
Das Programm dazu sieht wie folgt aus:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity DeTiSub1 is
port (   TimReq : in std_logic_vector(17 downto 0);
  MTimReq : out std_logic_vector (17 downto 0);
  ct20us : in integer range 0 to 2047
  );
end DeTiSub1;

architecture DeTiSubE of DeTiSub1 is
  signal detimm: std_logic_vector (17 downto 0);
begin
  detimm <= "0000000" & conv_std_logic_vector(ct20us,11);
  MTimReq <= TimReq - detimm;
end DeTiSubE;

Es lässt sich auch ohne Probleme komplieren und so.
Aber was passiert wenn detimm größer wird als TimReq? Leider finde ich 
nicht, warum das subtrahieren überhaupt funktioniert... in welcher 
Library steht das? Da es sich, wie die Variablennamen schon verraten um 
Zeiten handelt, ist dieser Fall schon wichtig.
Sollte man das ganze besser mit numeric_std machen? wie sieht das 
Programm dann aus?

Weiß einer hier ein Buch, vorzugsweise auf Deutsch, in dem die ganzen 
Librarys mit Ihren Funktion erklärt werden? Also schon zum Nachschlagen, 
ähnlich dem Kernighan and Ritchie für C?
Schon mal vielen Dank für Eure Hilfe,

Lg Peggy

Autor: jm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon in die
ieee.std_logic_arith.all;
geschaut?

Einfach mal simulieren, dann siehst du was passiert. Vermutlich wird das 
Ergebnis im zweierkomplement negativ wenn der subtrahend größer ist.

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

Bewertung
0 lesenswert
nicht lesenswert
> Sollte man das ganze besser mit numeric_std machen?
Ja, wäre wohl grundsätzlich besser, die
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
zu vergessen, und auf die herstellerunabhängige numeric_std 
umzuschalten. Dann gibt es nämlich nur noch 1 Library, in der du nach 
Rechenoperationen schauen mußt.
Und dann sieht das in etwa so aus:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity DeTiSub1 is
port (   TimReq  : in  unsigned(17 downto 0);
         MTimReq : out unsigned(17 downto 0);
         ct20us  : in integer range 0 to 2047
  );
end DeTiSub1;

architecture DeTiSubE of DeTiSub1 is
  signal detimm: unsigned(17 downto 0);
begin
  detimm  <= to_unsigned(ct20us,detimm'length);
  MTimReq <= TimReq-detimm;
end DeTiSubE;

Ungeachtet dessen bleibt dir der pragmatische Weg mit der Simulation 
nicht nicht versperrt. Der instatiierte Subtrahierer wird detimm auch 
dann abziehen, wenn es größer ist als TimReq.
Wenn du das nicht willst, mußt du das händisch abfangen:
  MTimReq <=  TimReq-detimm when TimReq>detimm else 0;



> ... zum Nachschlagen, ähnlich dem Kernighan and Ritchie für C?
Im K&R werden auch nicht alle Funktionen irgendwelcher Libraries 
erklärt. Zum Beispiel ist da keine einzige Fkt zum Ansteuern eines LCD 
näher erläutert... ;-)

Autor: Morin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber was passiert wenn detimm größer wird als TimReq?

Dann gibts es einen "wrap-around", soll heißen bei einem vector (17 
downto 0) ist 0 dasselbe wie 2^18 und eine negative Zahl wird 
entsprechend auf eine "große" Zahl abgebildet, z.B. -1 auf 2^18-1, -2 
auf 2^18-2 usw.

> Vermutlich wird das
> Ergebnis im zweierkomplement negativ wenn der subtrahend größer ist.

Nein, denn
use ieee.std_logic_unsigned.all;

gibt an, dass vorzeichenlos gerechnet wird. Mit "...signed" hättest du 
recht.

> und auf die herstellerunabhängige numeric_std umzuschalten.

Gefragt war, was in der "...unsigned" Bibliothek passiert, nicht welche 
Bibliothek besser ist.

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

Bewertung
0 lesenswert
nicht lesenswert
Morin wrote:
> use ieee.std_logic_unsigned.all;
> gibt an, dass vorzeichenlos gerechnet wird. Mit "...signed" hättest du
> recht.
Ist es nicht so, dass die Rechnung (Subtraktion) immer dieselbe ist, nur 
das Ergebnis anders interpretiert wird, z.B. bei einem Vergleich?


>> und auf die herstellerunabhängige numeric_std umzuschalten.
> Gefragt war, was in der "...unsigned" Bibliothek passiert, nicht welche
> Bibliothek besser ist.

Oh, habe ich die ursprüngliche Frage sooo falsch interpretiert ;-)
>>> Sollte man das ganze besser mit numeric_std machen?

Autor: Morin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist es nicht so, dass die Rechnung (Subtraktion) immer dieselbe ist, nur
> das Ergebnis anders interpretiert wird, z.B. bei einem Vergleich?

Ja, zumindest ein "ja" in dem Sinne wie du es meinst: Soweit es das 
Bitmuster betrifft, ist die Operation die selbe, soweit es die 
Interpretation als Zahl betrifft, eine andere.

> Oh, habe ich die ursprüngliche Frage sooo falsch interpretiert ;-)

Ich bitte tausendmal um Verzeihung, das hatte ich überlesen schäm

Autor: B. U. (peggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für Eure Hilfe!

Werd das dann gleich mal fleißig simulieren ;-)

Autor: B. U. (peggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hab jetzt simuliert, geht so wie´s soll. Also Wrap Around mit Einsen 
dann
 00 0000 0000 0000 0000
-00 0000 0010 0101 1000
______________________
 11 1111 1101 1010 1000

also alles prima ;-)

Trotzdem musste ich noch mehr casten, weil ich an den Ausgängen auch 
unbedingt den Datentyp std_logic_vector brauche:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity DeTiSub1 is
port (   TimReq  : in  std_logic_vector(17 downto 0);
         MTimReq : out std_logic_vector(17 downto 0);
         ct20us  : in integer range 0 to 2047
  );
end DeTiSub1;

architecture DeTiSubE of DeTiSub1 is
  signal detimm: unsigned(17 downto 0);
  signal TimReqM: unsigned(17 downto 0);
  signal MTimReqM: unsigned (17 downto 0);  

begin
  TimReqM <= unsigned (TimReq); --Cast des Eingangs zu unsigned
  detimm  <= to_unsigned(ct20us,detimm'length); --Cast der Konstante Datentyp integer=>unsigned
  MTimReqM <= TimReqM-detimm;
  MTimReq <= std_logic_vector (MTimReqM);--Cast zu std_logic_vector fuer Ausgang
end DeTiSubE;

oder weiß jemand was besseres?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht gut aus. Du kannst Deine Signale etwas generischer generieren:
  signal detimm, TimReqM: unsigned(TimReq'range);
  signal MTimReqM: unsigned(MTimReq'range);  

Duke

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

Bewertung
0 lesenswert
nicht lesenswert
> Trotzdem musste ich noch mehr casten, weil ich an den Ausgängen auch
> unbedingt den Datentyp std_logic_vector brauche
> :
> oder weiß jemand was besseres?
Nein, nicht mit Standard-Libs, VHDL ist da ein wenig geschwätzig ;-)

Natürlich könntest du selber die Operatoren überladen. Aber wenn du 
"nur" an den Schnittstellen std_logic_vector verwendest, hält sich der 
Cast-Aufwand in Grenzen.

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.