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
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.
> Sollte man das ganze besser mit numeric_std machen?
Ja, wäre wohl grundsätzlich besser, die
1 | use ieee.std_logic_arith.all; |
2 | 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:
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity DeTiSub1 is |
6 | port ( TimReq : in unsigned(17 downto 0); |
7 | MTimReq : out unsigned(17 downto 0); |
8 | ct20us : in integer range 0 to 2047 |
9 | );
|
10 | end DeTiSub1; |
11 | |
12 | architecture DeTiSubE of DeTiSub1 is |
13 | signal detimm: unsigned(17 downto 0); |
14 | begin
|
15 | detimm <= to_unsigned(ct20us,detimm'length); |
16 | MTimReq <= TimReq-detimm; |
17 | 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:
1 | 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... ;-)
> 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
1 | 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.
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?
> 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
Vielen Dank für Eure Hilfe! Werd das dann gleich mal fleißig simulieren ;-)
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:
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity DeTiSub1 is |
6 | port ( TimReq : in std_logic_vector(17 downto 0); |
7 | MTimReq : out std_logic_vector(17 downto 0); |
8 | ct20us : in integer range 0 to 2047 |
9 | );
|
10 | end DeTiSub1; |
11 | |
12 | architecture DeTiSubE of DeTiSub1 is |
13 | signal detimm: unsigned(17 downto 0); |
14 | signal TimReqM: unsigned(17 downto 0); |
15 | signal MTimReqM: unsigned (17 downto 0); |
16 | |
17 | begin
|
18 | TimReqM <= unsigned (TimReq); --Cast des Eingangs zu unsigned |
19 | detimm <= to_unsigned(ct20us,detimm'length); --Cast der Konstante Datentyp integer=>unsigned |
20 | MTimReqM <= TimReqM-detimm; |
21 | MTimReq <= std_logic_vector (MTimReqM);--Cast zu std_logic_vector fuer Ausgang |
22 | end DeTiSubE; |
oder weiß jemand was besseres?
Sieht gut aus. Du kannst Deine Signale etwas generischer generieren:
1 | signal detimm, TimReqM: unsigned(TimReq'range); |
2 | signal MTimReqM: unsigned(MTimReq'range); |
Duke
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.