Aber das bringt mir den Fehler:
[Synth 8-944] 5 definitions of operator "&" match here
["D:/vhdl/Spartan7_revc/Spartan7_revc.srcs/sources_1/AD9747.vhd":203]
Verstehe ich nicht und bitte um Erklärung.
Für mich ist das eigentlich klar, & verkettet die drei SLVs und
unsigned() macht daraus ein Unsigned.
Zusätzliche Klammern helfen auch nicht.
Gustl B. schrieb:> [Synth 8-944] 5 definitions of operator "&" match here> ["D:/vhdl/Spartan7_revc/Spartan7_revc.srcs/sources_1/AD9747.vhd":203]>
zeig' mal deine 'use' clauses.
Was da jetzt aber genau die Begruendung kann ich nicht sagen. Muesste
man sich mal die Casting Regeln anschauen, aber dazu bin ich jetzt echt
etwas zu faul. :-(
Ich finde ehrlich gesagt sogar deine Version mit den drei Unsigneds
unlogischer. Denn das sind ja dann Zahlen und da finde ich das komisch
dass man die überhaupt verketten kann. Was ist denn 7 & 9? Ja, hier geht
das weil noch klar ist wie viele Bits das sind und so, aber das
Verketten von SLVs und die nachträgliche Interpretation als Unsigned
macht für mich mehr Sinn.
Gustl B. schrieb:> STEP <= unsigned(DAC_Regs(18) & DAC_Regs(17) & DAC_Regs(16));
Ich bin mir nicht sicher, aber ich denke, das hat was mit dem Array zu
tun. Er weiß nicht, ob es ein 24 Bit Vector werden soll, oder 1 Array
aus 3x 8 Bit.
Gustl B. schrieb:> [Synth 8-944] 5 definitions of operator "&" match here
Welche sind es denn?
grüße
Daniel M. schrieb:> Er weiß nicht, ob es ein 24 Bit Vector werden soll, oder 1 Array> aus 3x 8 Bit.
OK, ja sehe ich ein. Wobei ja Array() ein SLV zurückliefert(?) und SLV &
SLV wieder ein SLV wird.
Daniel M. schrieb:> Welche sind es denn?
Wie kann ich das sehen/herausfinden?
Dein &-Operator ist einfach mehrdeutig. Das Ergebnis kann ein längerer
std_logic_vector sein, oder ein array von std_logic_vector
(Rom20x1Byte).
Du kannst VHDL auf die Spünge helfen, welchen Ergebnistyp du haben
möchtest:
STEP <= unsigned(std_logic_vector'(DAC_Regs(18) & DAC_Regs(17) &
DAC_Regs(16)));
Das Stichwort heißt "type qualifier".
Gustl B. schrieb:> Wie kann ich das sehen/herausfinden?
Modelsim z.B. müsste das mitteilen. Keine Ahnung, welchen Simulator du
nutzt. Die Student-Edition würde dafür z.B. funktionieren.
GHDL sagt z.B.:
> error: can't resolve overload for operator "&"> error: possible interpretations are:> error: array type "rom20x1byte"
und Modelsim
> ** Error: test.vhd(17): Ambiguous type in infix expression; Rom20x1Byte or> ieee.std_logic_1164.STD_LOGIC_VECTOR.> ** Error: test.vhd(17): (vcom-1583) Illegal type converson from 'unknown' to> 'ieee.NUMERIC_STD.UNSIGNED' (operand type is not known).
Doch das ist richtig. Dein Problem ist unabhängig davon, dass du sowas
wie 'DAC_Regs(18) & DAC_Regs(17)' als Input an den & Operator gibt. Du
kannst das gleiche Phänomen erzeugen wenn du richtige
std_logic_vectoren, wie "10" & "01" an der Stelle versuchst.
Man muss dazu wissen, dass bei VHDL ein Array immer implizit zwei &
Operatoren mit bekommt. Also zu jedem Array-Typ der deklariert wird,
gibt es implizit 2 & Operatoren dazu. Einer nimmt einzelne Elemente und
baut daraus das Array zusammen. Der andere nimmt 2 Arrays und baut
daraus ein größeres Array des gleichen Typs. Nehmen wir deinen Fall mal
genauer auseinander:
Du hast 2 Arraytypen in deiner Datei verfügbar.
1) Im Package ieee.std_logic_1164 ist std_logic_vector deklariert, und
zwar als array von std_logic.
2) Du hast Rom20x1Byte deklariert als array von std_logic_vector.
Damit Ergeben sich die folgenden Operatoren:
Aus 1):
- std_logic & std_logic = std_logic_vector
- std_logic_vector & std_logic_vector = std_logic_vector
Aus 2)
- std_logic_vector & std_logic_vector = Rom20x1Byte
- Rom20x1Byte & Rom20x1Byte = Rom20x1Byte
Nun siehst du, dass es 2 Operatoren gibt die std_logic_vector als Input
bekommen, aber unterschiedliche Typen zurück geben. Und genau das ist
das Problem. VHDL versucht dann anhand des erwarteten Ergebnisses den
richtigen Operator auszuwälen. Wenn du also das Ergebniss von
DAC_Regs(18) & DAC_Regs(17) direkt einem Signal zuweist, wird der Typ
des Signals genommen. Da du das Ergebniss aber weiterreichst an
unsigned(), funktioniert das nicht. Mit dem Type Qualifier gibst du dem
Compiler dann den expliziten Hinweis, welchen Typen du an unsigned
übergeben möchtest.
Vielen Dank!
Wenn ich
STEP <= unsigned(x"000" & x"111");
schreibe bekomme ich
[Synth 8-1731] cannot convert type bit_vector to type unsigned
["D:/vhdl/Spartan7_revc/Spartan7_revc.srcs/sources_1/AD9747.vhd":203]
als Fehler.
Da D. schrieb:> 2) Du hast Rom20x1Byte deklariert als array von std_logic_vector.
Bedeutet das, dass sobald ich ein Array aus SLV deklariere in meinem
Code keine SLV mehr verketten kann ohne explitzit einen type qualifier
zu verwenden?
Oh, sorry, das mit dem Bitvector hab ich übersehen.
Doch, du kannst du std_logic_vector noch verketten. Nur nicht
gleichzeitig mit der Umwandlung nach nach unsigned. Wenn der Compiler
anhand der Zuweisung zu einem signal erkennen kann, welcher Typ benötigt
wird, geht es ohne Type Qualitfier.
1
signalin1:std_logic_vector;
2
signalin2:std_logic_vector;
3
4
signala:std_logic_vector;
5
signalb:Rom20x1Byte;
6
signalc:unsigned;
7
8
-- das geht, der Operator mit dem Ergebniss std_logic_vector wird verwendet
9
a<=in1&in1;
10
11
-- das geht, der Operator mit dem Ergebniss Rom20x1Byte wird verwendet
12
b<=in1&in1;
13
14
-- das geht nicht, da der Compiler hier nicht aus der Zuweisung erkennen kann, welcher Typ als Ergebniss vom & erwartet wird.
15
c<=unsigned(in1&in1);
16
17
-- so weiß der Compiler es wieder
18
c<=unsigned(std_logic_vector'(in1&in2));
(ich hab der Einfachheit halber die Ranges weggelassen)
nur der Vollständigkeit halber: es gibt noch eine weitere Möglichkeit,
dem Compiler bezüglich des gewünschten Verkettungs-Operators auf die
Sprünge zu helfen.
Binäre Operatoren sind in VHDL ja als Funktionen mit zwei Parametern
definiert, deshalb kann man auch (ohne cast) explizit den
Concat-Operator aus ieee.std_logic_1164 rufen (den wollen wir ja):
... und wenn wir schon mal dabei sind. Man kann den Sermon auch noch
einem anderen (noch nicht mehrdeutig belegten) Operator als
Function-Alias aufprägen:
Markus F. schrieb:> Zugegeben, ist auch nicht schöner ;)
(-:
Markus F. schrieb:> Man kann den Sermon auch noch> einem anderen (noch nicht mehrdeutig belegten) Operator als> Function-Alias aufprägen:
Den man hiermit mehrdeutig belegt. Ich finde das generell nicht gut wenn
Operatoren unterschiedliche mehrdeutige Dinge tun. Wir haben doch sehr
viele mögliche Zeichen und wenn die ausgehen könnte man doch auch einen
Namen vergeben. Da finde ich dann ieee.std_logic_1164."&"() besser weil
eindeutig wobei ich das dann kürzer benennen würde, &slv z. B.
Gustl B. schrieb:> Wir haben doch sehr> viele mögliche Zeichen und wenn die ausgehen könnte man doch auch einen> Namen vergeben
In VHDL kannst Du Funktionen und (existierende) Operatoren (als
Funktionen) überladen. Man kann aber keine neuen Operatoren definieren
(muß also für so was das nehmen, was da ist).
Natürlich kann man den Cast nach unsigned noch mit in der Funktion
verstecken (der "&"-Concat-Operator, der zwei std_logic_vector-Variablen
aneinanderhängt und ein unsigned zurückgibt, ist noch frei):
Ja, ne, vielen Dank, aber sowas lass ich lieber bleiben. Meine
Einstellung ist, dass Code lesbar sein soll. Und zwar lieber lesbar als
kurz. Wenn ich also immer ieee.std_logic_1164."&"(a, b) schreiben muss
ist mir das lieber weil für mich schneller verstehbar als eine eigene
Definition von & zu verwenden.