Forum: FPGA, VHDL & Co. VHDL: Dezimale Konstante auf unsigned zuweisen


von Jonas P. (jonassanoj)


Lesenswert?

Hallo,

ich scheitere gerade an dem banalen Wunsch, eine dezimale Konstante auf 
ein unsigned signal zuzuweisen:

Deklaration in der Port-Liste:
Tries_Idle          : BUFFER unsigned (15 DOWNTO 0);

Und so geht es leider nicht:
Tries_Idle <= to_unsigned(0, Tries_Idle'length);

Da wirft Quartus bei der Synthese den folgenden Fehler:
      Error (10511): VHDL Qualified Expression error at 
busfsm_fsm.vhd(173): TO_UNSIGNED type specified in Qualified Expression 
must match UNSIGNED type that is implied for expression by context


Als Workaround verwende ich jetzt (others => '0'), aber ich würde gerne 
verstehen was ich da falsch mache.


Viele Gruesse

Jonas

von Duke Scarring (Gast)


Lesenswert?

Ist ieee.numeric_std.all eingebunden?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jonas P. schrieb:
> Da wirft Quartus bei der Synthese den folgenden Fehler:
Mit welchem Code?
Die ersten paar Zeilen ab Zeile 1 wären da interessant.

Duke Scarring schrieb:
> Ist ieee.numeric_std.all eingebunden?
Und nur die ieee.numeric_std.all?

BTW:
Jonas P. schrieb:
> Deklaration in der Port-Liste:
> Tries_Idle          : BUFFER unsigned (15 DOWNTO 0);
Ist der Port tatsächlich ein Buffer oder ist das nur Schreibfaulheit?

: Bearbeitet durch Moderator
von Jonas P. (jonassanoj)


Lesenswert?

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.numeric_std.all;

Wenn ich die anderen beiden rauswerfe, gibt es den gleichen Fehler.

BUFFER verwende ich, weil ich das Signal in der übergeordneten 
Hierarchie auch noch benötige. Dafür ist es doch gedacht, oder?
Aber ich stelle gerade fest, dass man das seit VHDL 2008 gar nicht mehr 
machen muss :-)

: Bearbeitet durch User
von Kurz & Knapp (Gast)


Lesenswert?

Was man nicht im Kopf, achaut man auf  Quick reference card nach:
http://soc.eurecom.fr/EDC/lectures/vhdl/1164pkg.pdf

von Kurz & Knapp (Gast)


Lesenswert?

Jonas P. schrieb:
>Tries_Idle          : BUFFER unsigned (15 DOWNTO 0);
> Tries_Idle <= to_unsigned(0, Tries_Idle'length);

Achja ein attribut auf einen Port ist nicht dasselbe wie ein Attribute 
auf den Type vom Port ...

von Jonas P. (jonassanoj)


Lesenswert?

Kurz & Knapp schrieb:
> Was man nicht im Kopf, achaut man auf  Quick reference card nach:
> http://soc.eurecom.fr/EDC/lectures/vhdl/1164pkg.pdf

Danke, die kannte ich noch nicht.
Aber die hilft mir bei diesem Problem auch nicht weiter.

Ich gehe davon aus, dass wenn ich eine Zahl einfach so schreibe, ohne 
Anführungszeichen, dass das dann von VHDL als Integer interpretiert 
wird. Und dann müsste ich es doch wie in meinem Beispiel erst mal nach 
unsigned konvertieren, damit der Vergleich mit einem anderen unsigend 
funktioniert?

Oder liege ich da falsch?

von Jonas P. (jonassanoj)


Lesenswert?

Kurz & Knapp schrieb:
> Jonas P. schrieb:
>>Tries_Idle          : BUFFER unsigned (15 DOWNTO 0);
>> Tries_Idle <= to_unsigned(0, Tries_Idle'length);
>
> Achja ein attribut auf einen Port ist nicht dasselbe wie ein Attribute
> auf den Type vom Port ...


Das klingt kompliziert. Ist das relevant für mein banales Problem? Hab 
ich den Port falsch deklariert?

von Kurz & Knapp (Gast)


Lesenswert?

Jonas P. schrieb:
> Oder liege ich da falsch?

IMHO liegst du nicht dort falsch sondern bei der Angabe der Länge. 
Versuch mal:
Tries_Idle <= to_unsigned(0, 16);

Und dann kann man überlegen ob man nicht einen (sub-)type für den Port 
definieren muss um dann mit 'length zu arbeiten.


im Package:
Subtype T_Tries-Idle is unsigned(15 downot 0);

in der entity:
Tries_Idle          : BUFFER T_TRIES_IDLE;

in der Zuweisung:
Tries_Idle <= to_unsigned(0, T_Tries_Idle'length);

Siehe auch https://www.csee.umbc.edu/portal/help/VHDL/attribute.html

mglw. gibt es in neueren VHDL-Standards die Möglichkeit den type eines 
Ports "zu erfragen".

von Markus F. (mfro)


Lesenswert?

Die Fehlermeldung besagt, daß der rechte Typ (das Ergebnis von 
to_unsigned()) nicht zum linken paßt.

Hier dürfte die Ursache in den eingebundenen Libraries zu finden sein 
(möglicherweise/wahrscheinlich eine Vermischung von z.B. numeric_std und 
std_logic_arith).

Mehrere Libraries definieren denselben Typ (unsigned). Für VHDL sind 
aber (z.B.) numeric_std.unsigned und std_logic_arith.unsigned 
unterschiedliche Typen (auch wenn das nicht unbedingt offensichtlich 
ist). Daher die Fehlermeldung.

von Jonas P. (jonassanoj)


Lesenswert?

> IMHO liegst du nicht dort falsch sondern bei der Angabe der Länge.
> Versuch mal:
> Tries_Idle <= to_unsigned(0, 16);

Gibt leider den gleichen Fehler :-(

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jonas P. schrieb:
> USE ieee.std_logic_arith.all;
> USE ieee.numeric_std.all;
Nimm nur eine der Mathebibliotheken. Niemals beide! Auf keinen Fall!

Lass die alte obsolete std_logic_arith weg, die numeric_std hat alles, 
was du brauchst.

: Bearbeitet durch Moderator
von Jonas P. (jonassanoj)


Lesenswert?

> Hier dürfte die Ursache in den eingebundenen Libraries zu finden sein
> (möglicherweise/wahrscheinlich eine Vermischung von z.B. numeric_std und
> std_logic_arith).


Du hast Recht, in dem separaten Entity-File stand noch die 
std_logic_arith drin!
Ich hatte nur im Architecture-File geschaut...


Vielen Dank an alle, das war ja von Anfang an der Verdacht!

von Jonas P. (jonassanoj)


Lesenswert?

> Lass die alte obsolete std_logic_arith weg, die numeric_std hat alles,
> was du brauchst.

Danke!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?


von Markus F. (mfro)


Lesenswert?

Lothar M. schrieb:
> Nimm nur eine der Mathebibliotheken. Niemals beide! Auf keinen Fall!

Jonas P. schrieb:
> Und dann müsste ich es doch wie in meinem Beispiel erst mal nach
> unsigned konvertieren, damit der Vergleich mit einem anderen unsigend
> funktioniert?

Nochmal einen draufgesetzt, damit das Problem wirklich verstanden wird:

Das hast Du original geschrieben:
1
library ieee;
2
...
3
use ieee.std_logic_arith.all;
4
use ieee.numeric_std.all;
5
...
6
Tries_Idle          : BUFFER unsigned (15 DOWNTO 0);
7
...
8
Tries_Idle <= to_unsigned(0, Tries_Idle'length);

Tatsächlich steht da (wenn man die "use"-Statements ignoriert bzw. 
auflöst):
1
...
2
Tries_Idle          : BUFFER ieee.std_logic_arith.unsigned (15 DOWNTO 0);
3
...
4
Tries_Idle <= ieee.numeric_std.to_unsigned(0, Tries_Idle'length);

(in der std_logic_arith gibt's kein to_unsigned. Deswegen findet der 
Compiler die ieee.numeric_std.to_unsigned und die gibt ein 
ieee.numeric_std.unsigned zurück.

Nun gibt es aber keine gültige Konvertierung von 
ieee.numeric_std.unsigned nach ieee.std_logic_arith.unsigned - deswegen 
der Fehler.
Aber wir könn(t)en die Konvertierung auch selber schreiben, dann würde 
der Mix tatsächlich funktionieren:
1
library ieee;
2
...
3
-- use ieee.std_logic_arith.all;
4
-- use ieee.numeric_std.all;
5
6
...
7
8
function nu2au(nu : ieee.numeric_std.unsigned) return ieee.std_logic_arith.unsigned is
9
        variable au : ieee.std_logic_arith.unsigned(nu'range);
10
    begin
11
        for i in nu'range loop
12
            au(i) := nu(i);
13
        end loop;
14
        
15
        return au;
16
    end function nu2au;
17
begin
18
19
...
20
21
tries_idle <= nu2au(ieee.numeric_std.to_unsigned(0, tries_idle'length));

Wenn man die Typen sauber auseinanderhält, lassen sich die Libraries 
also auch mischen. Ob das im Einzelfall sinnvoll ist oder nicht (ich 
gehe davon aus - eher nicht), muß jeder selbst entscheiden.

: Bearbeitet durch User
von Jonas P. (jonassanoj)


Lesenswert?

Abgefahren, dann war das eigentliche Problem, dass ich in der Entity mit 
der Port-Deklaration die arith noch drin hatte, und in der 
architecture-datei eben nicht sondern stattdessen die numeric_std?!

Vielen Dank für die ausführliche Erklärung, ich wusste auch nicht, dass 
man die Libraries einfach vor die Funktion schreiben kann anstelle der 
use-Befehle.

Trotzdem war in der Entity ja von Anfang an auch die numeric_std drin, 
und wenn in der arith kein unsigned vorhanden ist, dann hätte es doch 
kein Problem geben dürfen?

Oder gibt es da halt auch ein unsigned, und das ist das Problem?
Unsigned aus zwei verschiedenen Bibliotheken, und daher auch die 
Möglichkeit mit Deiner nu2au-Funktion?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jonas P. schrieb:
> Unsigned aus zwei verschiedenen Bibliotheken
Ja, das ist es: doppelte Typdefinitionen.
Und das sind dann eben zwei unterschiedliche Typen, die man einander 
nicht so ohne Weiteres zuweisen kann. Oder eben, dass eine Funktion mit 
dem "unsigned" der anderen Bibliothek nichts anfangen kann...

: Bearbeitet durch Moderator
von Markus F. (mfro)


Lesenswert?

Jonas P. schrieb:
> Oder gibt es da halt auch ein unsigned, und das ist das Problem?
> Unsigned aus zwei verschiedenen Bibliotheken, und daher auch die
> Möglichkeit mit Deiner nu2au-Funktion?

Genau.

Um dich vollends zu verwirren: ich hätte die Funktion auch - statt nu2au 
- to_unsigned nennen können und alles würde trotzdem genauso 
funktionieren...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus F. schrieb:
> ich hätte die Funktion auch - statt nu2au - to_unsigned nennen können
> und alles würde trotzdem genauso funktionieren...
Das nennt sich "Überladen“ von Operatoren bzw. Funktionen.
Ungeschickt und verwirrend ist das dann, wenn es in zwei Bibliotheken 
jeweils gleich benannte überladene Operatoren/Funktionen mit den selben 
Datentypen gibt...  ?

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
Noch kein Account? Hier anmelden.