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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jonas P. (jonassanoj)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Ist ieee.numeric_std.all eingebunden?

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (lkmiller) (Moderator) Benutzerseite


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
> Lass die alte obsolete std_logic_arith weg, die numeric_std hat alles,
> was du brauchst.

Danke!

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert

von Markus F. (mfro)


Bewertung
2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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...  ?

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]
  • [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.