www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Warum funktioniert diese VHDL Funktion?


Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier eine VHDL Funktion und frage mich, warum diese 
funktioniert. Vielleicht könnt ihr mir helfen ;)

Die Funktion wandelt nen Busvektor in einen Integer Wert um.
function vec2int (v: std_logic_vector) return int is
  variable temp : integer := 0;
begin
  for i in v'range loop
   temp := temp * 2;
   if v(i) = '1' then
    temp := temp + 1;
   end if;
  end loop;
  return temp;
end vec2int;

Ich als C-Programmierer würde sagen - so kann das nicht funktionieren, 
da in C eine Schleife wie
  for (int i=0; i< v'length; i++)
von i=0 bis i=v'range-1 abgearbeitet wird. Wenn man das mal 
durchrechnet, also zB die Binärzahl 0101 wandeln will, käme als Ergebnis 
A statt 9 raus.

Das oben genannte VHDL Beispiel funktioniert aber nur dann, wenn VHDL 
die Schleife andersrum anfängt, und zwar beim MSB bgeinnt und mit dem 
LSB aufhört. So wie der Code geschrieben ist, ist es aber anscheinend 
egal, ob der Vektor v mit "to" oder "downto" deklariert wurde, VHDL 
müsste as LSB identifizieren und mit der Bearbeitung eben dieses LSBs 
beginnen.

Nehmen wir mal an, es ist wirklich so, dass dieser Code da oben wirklich 
funktioniert, weil VHDL sowas vom MSB zum LSB abarbeitet. Dann käme für 
die 4 Bit Zahl 0101 ja auch tatsächlich 9 raus.

Das führt aber zu einer weiteren Frage: Für die 8 Bit Zahl 0000 0101 
käme was völlig anderes raus obwohl das ja auch dezimal 9 entspricht. 
VHDL müsste also das MSB als höchstwertige 1 identifizieren und alle 
Nullen davor abschneiden.

Verarbeitet VHDL die Schleifen also tatsächlich genau andersrum als C? 
Oder ist der Code hier sinnfrei?

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, jetzt bin ich selbst durcheinander gekommen. Hier nochmal die 
richtige Version:

"Das oben genannte VHDL Beispiel funktioniert aber nur dann, wenn VHDL
die Schleife andersrum anfängt, und zwar beim MSB bgeinnt und mit dem
LSB aufhört. So wie der Code geschrieben ist, ist es aber anscheinend
egal, ob der Vektor v mit "to" oder "downto" deklariert wurde, VHDL
müsste das MSB identifizieren und mit der Bearbeitung eben dieses MSBs
beginnen."

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oder ist der Code hier sinnfrei?
Nein, durch
> v'range
nimmt die Funktion genau die Definition des Vektors und wandelt die von 
links beginnend in einen Integer um.

Probier das mal mit
A)   v: std_logic_vector(5 downto 0)
B)   v: std_logic_vector(0 to 31)
C)   v: std_logic_vector(79 downto 63)
D)   v: std_logic_vector(56 to 89)

Die Funktion nimmt an, dass das linke Bit als das MSB gilt.
Das kommt dabei raus:
>  for i in v'range loop
-->
A)   for i in (5 downto 0) loop
B)   for i in (0 to 31) loop
C)   for i in (79 downto 63) loop
D)   for i in (56 to 89) loop

> Verarbeitet VHDL die Schleifen also tatsächlich genau andersrum als C?
VHDL verarbeitet die Schleifen genau wie VHDL.

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nein, durch v'range nimmt die Funktion genau die Definition des Vektors und 
wandelt die von links beginnend in einen Integer um.

Hm aha - und dabei werden also auch führende Nullen gestrichen, zB wird 
aus 0000 0110 einfach eine 110? Egal wie breit das Signal eigentlich 
definiert ist?

Und zweite Frage - nur zum Verständnis - wie mache ich dann eine 
Schleife, bei der das rechte, als das LSB, zuerst abgearbeitet werden 
soll?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dabei werden also auch führende Nullen gestrichen, zB wird
> aus 0000 0110 einfach eine 110?
Die werden eigentlich nicht gestrichen. Das Ignorieren führender 
Nullen ergibt sich einfach aus der Berechnung 0 * 0 = 0.
  :
  variable temp : integer := 0;    --<<< Defaultwert 0
begin
  for i in v'range loop
   temp := temp * 2;               --<<< 0 * 0 = 0
   :

> wie mache ich dann eine Schleife, bei der das rechte, als das LSB,
> zuerst abgearbeitet werden soll?
Ganz einfach: umgekehrt   ;-)
  :
  for i in v'reverse_range loop
   :

EDIT:
Zum Nachschlagen das hier
http://www.eda.org/rassp/vhdl/guidelines/vhdlqrc.pdf

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für deine Hilfe!

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.