Hallo Leute
welche Möglichkeiten, außer den folgenden, gibt es eine Zahl als
unsigned zu interpretieren? Ich kenne drei. Die erste ist ein wenig
krude:
1
positiv<='0'&unbekannt;
Die zweite ist, alle relevanten Größen grundsätzlich als "signed" oder
"unsigned" zu deklarieren.
Die dritte gehört eigentlich zur zweiten nämlich das casting unsigned().
Leider fallen die Möglichkeiten 2 und 3 bei mir aus, weil ich in
derselben Architecture auch signed-Operationen durchführe und ich nicht
IEEE.STD_LOGIC_ARITH.ALL und IEEE.STD_LOGIC_SIGNED.ALL verwenden kann.
Die erste finde ich persönlich 1. ein wenig krude, 2. würde es "positiv"
verbreitern, was auch unschön ist. (das soll nämlich später dividiert
werden)
danke für eure Hilfe, bitte schreibt mir auch ein paar Worte, wenn es
keine weiteren Möglichkeiten gibt.
Quecksilber schrieb:> und ich nicht> IEEE.STD_LOGIC_ARITH.ALL und IEEE.STD_LOGIC_SIGNED.ALL verwenden kann.
Das ist gut so.
Schmeiß diese alten Synopsys Libs STD_LOGIC_ARITH und ihre Anhänger
STD_LOGIC_SIGNED und STD_LOGIC_UNSIGNED raus. Denn für diese Probleme,
die du gerade hast, gibt es die NUMERIC_STD mit ihren Datentypen signed
und unsigend und jeder Menge passender Casts und Konvertierungen:
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html
ok mach ich, danke für den Tipp und Link. Dann hab ich aber nochmal ne
Frage: In welcher alternativen Lib sind die arithmetischen Operatoren
definiert? Nur mit der IEEE.NUMERIC_STD.ALL komm ich da nicht weit.
Ok, streiche die letzte Frage. Aber dafür hab ich ne neue: Würde es dann
nicht Sinn machen ausschließlich mit signed und unsigned zu arbeiten?
Welche Verwendung findet dann noch der std_logic_vector?
Queck Silber schrieb:> Aber dafür hab ich ne neue: Würde es dann nicht Sinn machen> ausschließlich mit signed und unsigned zu arbeiten?
Für Berechnungen: ja, und mit Integer.
> Welche Verwendung findet dann noch der std_logic_vector?
Der wird ganz gern als "Standard-Datenübergabeformat" an den Ports
verwendet.
ok das Prob scheint tatsächlich zu sein, dass "r" plötzlich ein 'U'
enthält, aber nur auf dem LSB. Das führt zu der Frage: Was genau machen
die Casts signed/ unsigned? Verändern die die Bits in irgendeiner Weise?
hmm ok konnte das Prob lösen, war für mich anfangs etwas verwirrend,
weil die alte Synopsis Lib immer meckert, wenn man ein 7 Bit breites
Signal einem 8 Bit breiten zuordnen will. Die neue hat einfach das LSB
auf 'U' gesetzt und den Rest zugeordnet.
Dennoch habe ich eine weitere Frage:
Angenommen ich habe:
1
signalt:signed(7downto0);
2
signalp:unsigned(7downto0);
3
signalr:unsigned(8downto0);
4
...
5
r<=t+p;
Dann sagt der Compiler, dass das nicht gehe. Wie kann ich also eine
negative Zahl mit einer Positiven addieren? (p = 251, das MSB ist also
'1')
PS:
ich hab auch schon das hier gefunden:
http://www.mikrocontroller.net/articles/Rechnen_in_VHDL#Besser:_Rechnen_mit_numeric_std
aber das funktioniert bei mir nicht. Die Fehlermeldung ist diesselbe:
Line 50: found '0' definitions of operator "+", cannot determine exact
overloaded matching definition for "+"
Es funktioniert nur, wenn ich eines der Signale entsprechend caste, aber
dann hab ich doch nen anderen Wert oder nicht?
Bei einem signed Summanden muss die Summe natürlich auch signed sein.
Wenn du sichergestellt hast, dass da kein negativer Anteil mehr drin
ist, kannst du die natürlich nach der Summenbildung wieder nach unsigned
casten. Außerdem müssen die Summanden die gleiche Breite haben wie die
Summer, also erst mit Resize entsprechend erweitern.
Christian R. schrieb:> Außerdem müssen die Summanden die gleiche Breite haben wie die> Summer, also erst mit Resize entsprechend erweitern.
Laut [1] reicht es, wenn ein Summand die nötige Breite aufweist:
1
length of result = max(length of 1st par, length of 2nd par)
Das mit der Addition/Subtraktion ist m.E. in VHDL unschön gelöst. Bei
der Multiplikation wird automatisch auf die richtige Bitbreite geachtet,
bei der Addition muß man selber Platz für den Überlauf schaffen.
Duke
[1] http://www.eda.org/comp.lang.vhdl/FAQ1.html#4.8.1
Christian R. schrieb:> Bei einem signed Summanden muss die Summe natürlich auch signed sein.
ja das ist klar, aber es funktioniert trotzdem nicht^^. Er meldet in der
Zeile mit dem y <= x + y : "found '0' definitions of operator "+",
cannot determine exact overloaded matching definition for "+""
PS: Ist das Absicht, dass du p signed castest und t unsigned oder hast
du das nur verwechselt?
Duke Scarring schrieb:> Was denn nun? x oder y oder p oder t?> Zeig bitte die Definition Deiner Signale, sowie die verwendeten> Bibliotheken.>> Duke
Nun, sowohl als auch, es ist eigentlich beides male das Gleich nur bei
der P-T-Geschichte ist das Ergebnis unsigned, bei der X-Y-Geschichte
signed. Dennoch funktionieren beide nicht.
Hier ist nochmal der gesamte Code der Test-Area:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entityarea51is
6
port(
7
clk:std_logic;
8
eins:outstd_logic_vector(3downto0);
9
zwei:outstd_logic_vector(3downto0)
10
);
11
endarea51;
12
13
architectureBehavioralofarea51is
14
signalx:unsigned(3downto0):="0101";-- Zahlenbereich: 0 bis 2**8-1
15
signaly:signed(3downto0):="1111";-- Zahlenbereich: -2**7 bis 2**7-1
Queck Silber schrieb:> begin>> x <= x + 1; --- Hoppala, eine kombinatorische Schleife....>> :> end Behavioral;
Das hast du aber nicht mit einer Testbench ausprobiert, oder?
> Dennoch funktionieren beide nicht.
Was funktioniert denn nicht? Was erwartest du?
> y <= x + y;
Das kann ja nur solange funktionieren, wie es bei der Addition nicht
zu einem Überlauf kommt. Denn die Addition und die Subtraktion ist
sowohl bei signed wie auch bei unsigned beides mal exakt die selbe, es
wird dabei auch das selbe Rechenwerk und die selben Rechenvorschriften
verwendet! Nur das Bitmuster des Ergebnisses wird anders
interpretiert...
Lothar Miller schrieb:> Queck Silber schrieb:>> begin>>>> x <= x + 1; --- Hoppala, eine kombinatorische Schleife....
Das stammt von hier:
http://www.mikrocontroller.net/articles/Rechnen_in_VHDL#Besser:_Rechnen_mit_numeric_std>> end Behavioral;> Das hast du aber nicht mit einer Testbench ausprobiert, oder?
doch hab ich, allerdings hab ich in der Zeile "y <= x + y" das x
gecastet.
>> Dennoch funktionieren beide nicht.> Was funktioniert denn nicht? Was erwartest du?Queck Silber schrieb:> ja das ist klar, aber es funktioniert trotzdem nicht^^. Er meldet in der> Zeile mit dem y <= x + y : "found '0' definitions of operator "+",> cannot determine exact overloaded matching definition for "+""
schon das compilen funktioniert nicht. Ich würde also erwarten, dass es
das zumindest mal tut.
Queck Silber schrieb:> Er meldet in der> Zeile mit dem y <= x + y : "found '0' definitions of operator "+",> cannot determine exact overloaded matching definition for "+""
Ok. x ist unsigned und y ist signed:
1
signed<=unsigned+signed;
In der numeric_std sind folgende Additionen (siehe [1]) definiert:
1
operator 1st par 2nd par return remarks
2
+ uns uns uns unsigned add; length of result = max(length of 1st par, length of 2nd par)
3
+ sgn sgn uns signed add (two's-complement); length of result = max(length of 1st par, length of 2nd par)
4
+ uns nat uns add an uns with a non-negative int; length of result = length of 1st par
5
+ nat uns uns add an uns with a non-negative int; length of result = length of 2nd par
6
+ sgn int sgn add a sgn with an int; length of result = length of 1st par
7
+ int sgn sgn add a sgn with an int; length of result = length of 2nd par
Genau das besagt die Fehlermeldung. Er findet keine Funktion um einen
signed mit einem unsigned zu addieren. Du kannst dem Compiler mit casts
oder konvertierungen auf die Sprünge helfen.
Duke
[1] http://www.eda.org/comp.lang.vhdl/FAQ1.html#4.8.1
-- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
4
-- Result: Adds two UNSIGNED vectors that may be of different lengths.
5
6
-- Id: A.4
7
function"+"(L,R:SIGNED)returnSIGNED;
8
-- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
9
-- Result: Adds two SIGNED vectors that may be of different lengths.
10
11
-- Id: A.5
12
function"+"(L:UNSIGNED;R:NATURAL)returnUNSIGNED;
13
-- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
14
-- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
15
16
-- Id: A.6
17
function"+"(L:NATURAL;R:UNSIGNED)returnUNSIGNED;
18
-- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
19
-- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
20
21
-- Id: A.7
22
function"+"(L:INTEGER;R:SIGNED)returnSIGNED;
23
-- Result subtype: SIGNED (R'LENGTH-1 downto 0).
24
-- Result: Adds an INTEGER, L (may be positive or negative), to a SIGNED
25
-- vector, R.
26
27
-- Id: A.8
28
function"+"(L:SIGNED;R:INTEGER)returnSIGNED;
29
-- Result subtype: SIGNED (L'LENGTH-1 downto 0).
30
-- Result: Adds a SIGNED vector, L, to an INTEGER, R.
Quelle:
http://www.csee.umbc.edu/portal/help/VHDL/packages/numeric_std.vhd
Und damit gibt es nur 2 Wege: überlade den Operator + so, dass er auch
signed+unsigned kann, oder machs, wie du es schon gemacht hast mit einem
Cast. Vorher würde ich dann aber noch einen resize() erwägen, damit du
nicht in die Bredoullie mit dem MSB kommst.
Denn es ist einfach so, dass du einen 4 Bit signed und einen 4 Bit
unsigned nicht so ohne weiteres miteinander addieren darfst. Einmal
ist "1111" ja ein Wert von 15 und das andere mal -1. Und was soll dann
bei einer Addition herauskommen? 14 oder -2? Kurz: solange du in diesen
4 Bit bleibst, kommt beides gleichzeitig heraus, es bleibt nur die
Frage, wie du das Ergebnis interpretierst...
EDIT: Pech, Zweiter... ;-)
Danke euch für eure Mühe und Hilfe, das hat mir sehr geholfen! und
gelernt hab ich auch gleich ne Menge! Da ich mich noch nicht so recht an
das Überladen von Funktionen in VHDL ran traue, hab ich das jetzt mit
Casts gelöst. Ist nicht an jeder Stelle elegant, funktioniert aber.
Soweit ich weiß, wird die Hälfte ja eh bei der Synthese rausoptimiert.^^
Wegen des Links:
Lothar Miller schrieb:>> Das stammt von hier:>> http://www.mikrocontroller.net/articles/Rechnen_in...> Aber sicher nicht ohne Takt!
Da hast du meiner Ansicht nach Recht. Ich wollte damit auch vielmehr
implizit auf einen möglichen Fehler aufmerksam machen, damit jemand, mit
mehr Ahnung als ich, diesen (sofern es denn einer ist) beheben kann.
Danke nochmals!