Halle Leute, ich habe ein kurze Frage. Ich bin noch recht neu in der VHDL Welt und soll einen 4 Bit Vergleicher entwerfen. Aus Internetauszügen bin ich auf folgenden Quelltext gestoßen. sum := 0; for i in 3 downto 0 loop if A(i) = '0' then sum := sum * 2; else sum := sum * 2 + 1; end if; end loop; Das ganze funktioniert auch in der Simulation. Aber ich glaube es bringt mir nichts, den Quelltext einfach so in mein Programm zu übernehmen, wenn ich den Vorgang nicht verstehe. Kann mir daher irgendjemand erklären, was genau in welche Zeile eigentlich passieren soll? A ist mein Eingang mit 4 Bits. Ich verstehe das Programm so: Ich schreibe zuerst in meine Variable sum die Zahl null. Da die Variable 16 bit groß ist, habe ich 16 mal die null. Dann öffne ich eine Schleife mit der Variblen i. Danach frage ich ab: Ist der Eingang A null? Ist dieser null (also alle 4 Eingang-Bits auf low) so nimmt er die null aus der Summe und multipliziert diese mit 2. Also bleibt in der Variablen sum eine null stehen. Aber dieser Zustand ändert sich ja eigentlich nicht. Also warum multipliziere ich mit 2??? Sobald sich die Eingangsbits ändern, gehe ich ja automatisch in den else-Zweig, da mein A ja nicht mehr null ist. Ich hoffe jemand sieht mein Problem und kann mir helfen. Viele Grüße Matze1992
Hmm, ich bin auch VHDL-Neuling, aber ich versuche mal zu antworten: Also ich habe schon ein Problem, weil ich garkeine Vergleicher sehe. Wo soll denn hier verglichen werden? Das Programm macht doch nicht anderes als die Bits von oben nach unten durch zu gehen, und wenn es eine Null ist das Ergebnis um eins nach links shiften, und sonst das Ergebnis um eins nach links shiften und inkrementieren. Das bedeutet letztendlich nichts anderes, als dass in sum ein Kopie von A steht. Vielleicht erklärst du noch einmal genau, was denn in der Simulation schon funktioniert, dann kann man vielleicht weiter helfen.
Hi, das ding Vergleicht doch nichts, bin auch nur neuling in VHDL aber es geht auf jeden fall etwas anderes. Meine Lösung wäre ein XOR mit vergleich mit Null MfG Shee2e
Matze1992 schrieb: > Ich verstehe das Programm so: Das ist dein Problem. Das was du da hast, ist kein Programm, sondern eine Hardwarebeschreibung. Du musst diese prozedurale "C-Denkweise" vergessen, in dieser Beschreibung passiert nichts "zuerst" und "dann", sondern es wird alles gleichzeitig geschehen. > Sobald sich die Eingangsbits ändern, gehe ich ja automatisch in den > else-Zweig, da mein A ja nicht mehr null ist. Weil dieser "Code" paralell da steht, ist die Hardware mit allen Vergleichern immer da, und du gehst immer und jederzeit bei jeder Änderung von A diese "Schleife" komplett durch. > was genau in welche Zeile eigentlich passieren soll? Da wäre es super, wenn du die VHDL Tags [ vhdl ] und [ /vhdl ] ohne die Leerzeichen um deinen Sourcecode setzen würdest, dann bekommst du nämlich Syntax-Highlighting geschenkt...
1 | -- hier fehlt der ganze Prozedur-Kopf...
|
2 | |
3 | sum := 0; -- Eine Variable namens sum vermutlich vom Typ integer wird auf 0 gesetzt |
4 | for i in 3 downto 0 loop -- eine Schleife wird mit einem Indesx i von 0..3 durchlaufen |
5 | if A(i) = '0' then -- Ein Bit eines Verktors mit unbestimmtem Typ wird auf '0' verglichen |
6 | sum := sum * 2; -- falls dieses Bit nicht gesetzt war, wird die Summe verdoppelt |
7 | else
|
8 | sum := sum * 2 + 1; -- falls es gesetzt war, wird auf die vorige Summe Verdoppelt und eins draufaddiert |
9 | end if; |
10 | end loop; -- das wars |
Man könnte das auch so schreiben:
1 | sum := 0; |
2 | for i in 3 downto 0 loop |
3 | sum := sum * 2; |
4 | if A(i) = '1' then |
5 | sum := sum + 1; |
6 | end if; |
7 | end loop; |
Und was macht das Ganze? Damit wird ein Vektor in eine Integer-Zahl umgerechnet. Man könnte diesen Ausschnitt z.B. so oder so ähnlich bei der Funktion to_integer() aus der numeric_std finden... EDIT: such einfach mal dort im letzten Drittel nach to_integer: http://www.ece.msstate.edu/~reese/EE8993/ieee_standards/numeric_std.vhd Und tatsächlich ist das da so ähnlich, nur wird nicht die Summe geschoben, sondern das, was auf die Summe aufaddiert wird:
1 | variable w : INTEGER:= 1; -- weight factor --> Gewichtung des aktuellen Bits |
2 | |
3 | for i in XARG'reverse_range loop -- von rechts her jedes Element des Vektors durchlaufen |
4 | if XARG (i) = '1' then -- wenn gesetzt, dann die aktuelle Gewichtung dazuaddieren |
5 | RESULT:= RESULT + w; |
6 | end if; |
7 | if (i /= XARG'left) then w := w + w; -- und solange nicht das linkeste Element erreicht ist, die Gewichtung verdoppeln |
8 | end if; |
9 | end loop; |
Fabio W. schrieb: > Das bedeutet letztendlich nichts anderes, als dass in sum ein Kopie von > A steht. Nein, denn sum ist ein Integer und A ist ein Vektor. Und das sind zwie grundlegend verschiedene Datentypen, auch wenn das jeweilige Bitmuster exakt gleich aussehen wird... Ach übrigens: in diesen Code sind 2 Dinge, die einen Anfänger problemlos ins Verderben bringen können: eine Variable und eine Schleife. Such einfach mal mit "Variable vs. Signal", da ist das mit der Variable ausgeführt...
:
Bearbeitet durch Moderator
-- hier fehlt der ganze Prozedur-Kopf... sum := 0; -- Eine Variable namens sum vermutlich vom Typ integer wird auf 0 gesetzt for i in 3 downto 0 loop -- eine Schleife wird mit einem Indesx i von 0..3 durchlaufen if A(i) = '0' then -- Ein Bit eines Verktors mit unbestimmtem Typ wird auf '0' verglichen sum := sum * 2; -- falls dieses Bit nicht gesetzt war, wird die Summe verdoppelt else sum := sum * 2 + 1; -- falls es gesetzt war, wird auf die vorige Summe Verdoppelt und eins draufaddiert end if; end loop; -- das wars Also es ist so, dass das gesamte Programm ein 4 Bit Vergleicher ist. Jedoch verstehe ich nur diesen Abschnitt nicht. Deshalb habe ich nur diesen Abschnitt euch gezeigt. Lothar Miller hat mein Problem denke ich so gut wie möglich versucht aufzugreifen. Eigentlich brauche ich nichts anderes, wie Kommentare hinter jeder Zeile, die mir das geschehen erklärt. Leider verstehe ich immer noch nicht ganz, was da passiert. Hier die Kopfzeile: vergleicher: process (A, B) is type int16 is range 0 to 15; variable a_int: int16; variable b_int: int16; variable i: int16; variable sum: int16; begin Ich verstehe einfach nicht, warum ich die Summe mal 2 nehme, wenn doch eh null drin steht. und sobald A ungleich Null ist, gehe ich ja in den else-Zweig. Damit wird der if-Zweig ja gar nicht mehr verwendet. Also warum mal 2, wenn es doch eh immer null ist? Beispiel: im Vektor A steht die binäre folge von :0110 Wir beginnen mit dem MSB also 0. Er geht in die if-Verzweigung und multipliziert die Summe 0 mit 2. Danach geht er auf die nächste Stelle also 1. Er geht in die else-Verzweigung und schreibt in die Summe 0*2+1 also ist die Summe jetzt 1. Danach an die nächste Stelle also wieder 1. Else-Verzweigung: Summe= 1*2+1 also 3. Danach die letzte Stelle 0 also wieder if-Verzweigung: Summe = 3*2 =6. Jetzt steht in der Summe 6. Und irgendwie wird mir jetzt gerade klar, was das Programm macht :D Ich habe verstanden! Ein ganz großes Dankeschön an alle! Ist mir jetzt fast ein bisschen peinlich! Ich hoffe ich habe niemandens Zeit verschwendet! Viele Grüße Matze1992
und warum so kompliziert wie wäre es mit (Vergleicht b mit c und das verglichene Ergebnis steht dann in a) a <= '1' when b = c else '0';
Lothar Miller schrieb: > Fabio W. schrieb: >> Das bedeutet letztendlich nichts anderes, als dass in sum ein Kopie von >> A steht. > Nein, denn sum ist ein Integer und A ist ein Vektor. Und das sind zwie > grundlegend verschiedene Datentypen, auch wenn das jeweilige Bitmuster > exakt gleich aussehen wird... Ja, sorry, das ist natürlich leicht falsch zu verstehen. Ich meinte viel mehr, dass an der Stelle überhaupt nichts verglichen wird, statt viel mehr den INHALT zu 'kopieren'. Natürlich sind die beiden Datentypen aber überhaupt nicht gleich. Matze1992 schrieb: > type int16 is range 0 to 15; Matze1992 schrieb: > Da die Variable 16 > bit groß ist, habe ich 16 mal die null. Das ist leider falsch. Die Variable ist nicht 16 bit groß, sie kann nur 16 verschiedene Zustände speichern. Das bedeutet, es sind log(16)bit=4 bit. Im Übrigen komme ich jetzt auch dahinter, was der Ausschnitt machen soll: to_integer und dann vergleichen...
Matze1992 schrieb: > Und irgendwie wird mir jetzt gerade klar, Na bitte, schrittweises Mitdenken hilft. > was das Programm macht :D Irgendwie scheinst du die wichtigste Anmerkung in meinem Post überlesen zu haben: Das ist kein Programm sondern eine Hardwarebeschreibung. user schrieb: > wie wäre es mit (Vergleicht b mit c und das verglichene Ergebnis steht > dann in a) > a <= '1' when b = c else '0'; Der gepostete VHDL-Code ist kein Vergleicher. Es sind nur "irgendwie" vier Vergleiche darin. Diese "Vergeleicher" werden in der Hardware aber nie aufgebaut. Es wird nur der selbe Vektor mit anderem Datentyp dargestellt...
Okay, bevor es noch mehr Missverständnisse zu meinem Post gibt, hier das vollständige Programm: -- Bibliotheken initialisieren: library ieee; use ieee.std_logic_1164.all; use work.all; -- ************************************************************************ ************** -- Eingaenge und Ausgaenge deklarieren: entity vergleicher is port ( A, B: in std_logic_vector (3 downto 0); GR, EQ, LE: out std_logic ); end entity vergleicher; -- ************************************************************************ ************** -- Hauptprogramm: architecture behavior of vergleicher is begin -- Prozess starten: -- Initialisierung der benötigten Variablen: vergleicher: process (A, B) is type int16 is range 0 to 15; variable a_int: int16; variable b_int: int16; variable i: int16; variable sum: int16; begin -- Umwandlung von Eingang A in Variable a_int sum := 0; for i in 3 downto 0 loop if A(i) = '0' then sum := sum * 2; else sum := sum * 2 + 1; end if; end loop; -- Umwandlung von Eingang B in Variable b_int a_int := sum; sum := 0; for i in 3 downto 0 loop if B(i) = '0' then sum := sum * 2; else sum := sum * 2 + 1; end if; end loop; -- Vergleicher von a_int und b_int if a_int > b_int then GR <= '1'; EQ <= '0'; LE <= '0'; end if; if a_int < b_int then GR <= '0'; EQ <= '0'; LE <= '1'; end if; if a_int = b_int then GR <= '0'; EQ <= '1'; LE <= '0'; end if; -- ************************************************************************ ************** end process vergleicher; -- ************************************************************************ ************** end architecture behavior; -- ************************************************************************ **************
Lothar Miller schrieb: > Da wäre es super, wenn du die VHDL Tags [ vhdl ] und [ /vhdl ] ohne die > Leerzeichen um deinen Sourcecode setzen würdest, dann bekommst du > nämlich Syntax-Highlighting geschenkt... Außerdem fehlt da meiner Meinung ein:
1 | b_int := sum; |
:
Bearbeitet durch User
>hier das vollständige Programm: Was für ein Programm? Mensch, Meier! Jetzt hat man Dir das schon zweimal im selben Thread geschrieben. Das ist kein Programm! Das ist eine Hardwarebeschreibung! Auch die extensive Verwendung von Sternchen ändert daran nichts. >-- Bibliotheken initialisieren: Sowas gibts nicht. Was da folgt, ist eine Deklaration von benutzten Bibliotheken. Sogenannte "use clauses". >VHDL Tags [ vhdl ] und [ /vhdl ] ohne die >Leerzeichen um deinen Sourcecode setzen würdest, dann bekommst du >nämlich Syntax-Highlighting geschenkt... Das ist wohl auch irgendwie an Deinen Gehirnwindungen vorbeigesaust. >Und was macht das Ganze? >Damit wird ein Vektor in eine Integer-Zahl umgerechnet. Man könnte >diesen Ausschnitt z.B. so oder so ähnlich bei der Funktion to_integer() >aus der numeric_std finden... Und das wohl auch! So. Jetzt das ganze nochmal. Aber richtig. Sonst gibts kein Abendbrot und Du musst mit Socken ins Bett.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.