Hallo zusammen, ich hätte da mal eine VHDL-Frage: Gibt es eine elegante Möglichkeit, einen loop über Bedingungen zu machen? Also z.B. möchte ich folgenden Code (eleganter übersetzen), u.a. möchte ich eine generische Variable für die Anzahl der Bedingungen einführen und nicht jedes mal die (Anzahl) Bedingungen abändern: trg <= '1' when a(0) = '1' and a(1) = '1' and a(2) = '1' and... ...and a(15) = '1'; Ich möchte also auf etwa Folgendes hinaus (wobei N ein vorher festgelegtes integer ist): trg <= '1' when for i in 0 to N - 1 loop when a(i) = '1' end loop; (Das gibt mir natürlich so eine Fehlermeldung) Vielen Dank schon mal für eure Antworten!! Christoph
Ich mag mich irren, aber ich bezweifle, dass das irgendjemand will.
1 | trg <= '1' when a == "111111111111111"; |
oder wenn man zu faul ist selbst die Einsen zu zählen:
1 | trg <= '1' when to_integer(a) == 2^15-1; |
(Syntax möglicherweise fehlerhaft)
Ich verstehe das Problem eher so: In einem String "a" mit der Anzahl an Elementen "N" soll das erste Element mit dem Wert "1" gefunden werden, welches dann dem Index "i" entspricht.
Hi, sorry, dann hab ich mich glaube ich zu undeutlich ausgedrückt. Ich wollte eigentlich nur ein einfaches Beispiel wählen um meine Frage auszudrücken. Klar, da gibts bestimmt einfachere Lösungen. Ich wollte aber im Allgemeinen wissen, wie man einen Loop über Konditionen macht. Mal ein (hoffentlich besseres) Beispiel: Ich habe einen Multiplexer mit N (integer) Eingängen, der in Abhängigkeit von N den N-ten Eingang auf den Ausgang legt. Bisher habe ich das immer (unelegant) folgendermaßen gemacht: ausgang <= eingang0 when N = 0 else eingang1 when N = 1 else eingang2 when N = 2 else ... eingangNmax when N = Nmax; Also ich brauche 1. ziemlich viele Zeilen und 2. muss ich den Multiplexer immer wieder neu anpassen, wenn ich den Bereich für N (sprich Nmax) ändere.
Hallo , vielleicht hilft ja sowas ausgang <= eingang(N) ; dann must du nur zwei Signale anpassen. Mfg
1 | ausgang <= or ( (2**N) & {eingang0, eingang1, eingang2, .... }) ; |
Erzeugt einen Vektor der Eingänge und maskiert die unerwünschten raus, so dass nur genau das Bit im Vektor 1 sein kann, dass durch N beschireben wird. In diesem Vektor werden alle Bits verodert um sie einem Ausgang zuzuweisen. Ist eingangN 1, so wird ausgang 1 zugewiesen, sonst 0.
Ich mach das oft so:
1 | --! Generated OR-Gate to OR-ing all the read registers
|
2 | GenOr : Process(C2B_ReadData) |
3 | variable temp : std_logic_vector(31 downto 0); |
4 | Begin
|
5 | temp := C2B_ReadData(0); |
6 | for i in 1 to MAX_READ_REG loop |
7 | temp := temp or C2B_ReadData(i); |
8 | end loop; |
9 | C2B_DATA <= temp; |
10 | End Process; |
Klappt natürlich für Bits in einem Vektor genauso.
> ausgang <= eingang0 when N = 0 else > eingang1 when N = 1 else > eingang2 when N = 2 else > ... > eingangNmax when N = Nmax; Der Trick und das Problem ist aber vermutlich, dass der eingang0 und der eingang1 hier auch ganz anders heißen könnten, z.B. taster0 und schalter1 und geber2 und sensor3... Ich würde das Problem mit dem Trick über den zusammengesetzten Vektor angehen:
1 | -- erst einen Vektor basteln
|
2 | h <= sensor3 & geber2 & schalter1 & taster0; |
3 | -- und dann einen Mux dahinter
|
4 | ausgang <= h(N); |
In der Praxis sieht das dann so aus:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity InMux is |
6 | Port ( Ea : in STD_LOGIC; |
7 | Eb : in STD_LOGIC; |
8 | Ec : in STD_LOGIC; |
9 | Ed : in STD_LOGIC; |
10 | Ee : in STD_LOGIC; |
11 | Ef : in STD_LOGIC; |
12 | sel : in STD_LOGIC_VECTOR(3 downto 0); |
13 | Aa : out STD_LOGIC); |
14 | end InMux; |
15 | |
16 | architecture Behavioral of InMux is |
17 | signal h : std_logic_vector(5 downto 0); |
18 | begin
|
19 | h <= Ef & Ee & Ed & Ec & Eb & Ea; |
20 | Aa <= h(to_integer(unsigned(sel))); |
21 | end Behavioral; |
Maxx schrieb: > ausgang <= or ( (2**N) & {eingang0, eingang1, eingang2, .... }) ; > > Erzeugt einen Vektor der Eingänge und maskiert die unerwünschten raus, > so dass nur genau das Bit im Vektor 1 sein kann, dass durch N > beschireben wird. > > In diesem Vektor werden alle Bits verodert um sie einem Ausgang > zuzuweisen. Bis dahin stimmt es... > Ist eingangN 1, so wird ausgang 1 zugewiesen, sonst 0. Das leider nicht, denn es wird dem Ausgang ein Vektor zugewiesen, in dem das entsprechende Bit gesetzt ist. Das ist nicht ganz das, was gewünscht war... Man könnte bestenfalls mit der or_reduce() Funktion da ein wenig rumtricksen. Mehr dazu im http://www.vhdl.org/vhdlsynth/vhdl/reduce_pack.vhd
Lothar Miller schrieb: > Das leider nicht, denn es wird dem Ausgang ein Vektor zugewiesen, in dem > das entsprechende Bit gesetzt ist. Das ist nicht ganz das, was gewünscht > war... Da muss ich dir widersprechen. Mit VHDL-2008 ist "or" als unärer Operator vor einem Vektor die or_reduce Funktion. Ergebnis ist ein std_logic und kein Vektor mehr. Ich kannte den Operator aus Verilog und er existiert so seit 2008 zu VHDL wenn man Google glauben darf.
Maxx schrieb: > Mit VHDL-2008 ist "or" als unärer Operator vor einem Vektor die > or_reduce Funktion. Ergebnis ist ein std_logic und kein Vektor mehr. Ich finde so eine implizite Wandlung nicht unbedingt schön. Dadurch wird VHDL genau wie C. Dort liebe und hasse ich ich aber exakt diese "Hintenrumkonvertiererei" von und zu irgendwelchen Datentypen, die einem so manche Tipparbeit erspart, aber gleichzeitig einige Nachmittage kosten kann...
Maxx schrieb: > Lothar Miller schrieb: >> Das leider nicht, denn es wird dem Ausgang ein Vektor zugewiesen, in dem >> das entsprechende Bit gesetzt ist. Das ist nicht ganz das, was gewünscht >> war... > > Da muss ich dir widersprechen. > > Mit VHDL-2008 ist "or" als unärer Operator vor einem Vektor die > or_reduce Funktion. Ergebnis ist ein std_logic und kein Vektor mehr. > > Ich kannte den Operator aus Verilog und er existiert so seit 2008 zu > VHDL wenn man Google glauben darf. Interessant, benötigt mn dazu das reduce package? http://www.vhdl.org/vhdlsynth/vhdl/reduce_pack.vhd ? MfG,
Christian R. schrieb: > Ich mach das oft so: >
1 | > --! Generated OR-Gate to OR-ing all the read registers |
2 | > GenOr : Process(C2B_ReadData) |
3 | > variable temp : std_logic_vector(31 downto 0); |
4 | > Begin |
5 | > temp := C2B_ReadData(0); |
6 | > for i in 1 to MAX_READ_REG loop |
7 | > temp := temp or C2B_ReadData(i); |
8 | > end loop; |
9 | > C2B_DATA <= temp; |
10 | > End Process; |
11 | >
|
> > Klappt natürlich für Bits in einem Vektor genauso. Statt hangeschrieben kann man auch die Funktion or_reduce o.ä. aus dem package nehmen. http://www1.pldworld.com/@xilinx/html/technote/TOOL/MANUAL/15i_doc/fndtn/vhd/vhd10_3.htm MfG
Fpga Kuechle schrieb: > Interessant, benötigt mn dazu das reduce package? > http://www.vhdl.org/vhdlsynth/vhdl/reduce_pack.vhd Das kann ich dir leider nicht beantworten. Selbst entwickel ich mit dem Xilinx WebPack unter Verilog und kenn VHDL nur ganz grob. Daher musste ich auch Onkel Google dazu befragen ob es den Operator überhaupt gibt.
Lothar Miller schrieb: > Maxx schrieb: >> Mit VHDL-2008 ist "or" als unärer Operator vor einem Vektor die >> or_reduce Funktion. Ergebnis ist ein std_logic und kein Vektor mehr. > Ich finde so eine implizite Wandlung nicht unbedingt schön. Dann schreib das explizit aus, die Funktion or_reduce steht dir ja zur Verfügung:
1 | function or_reduce (L : BOOLEAN_VECTOR) return BOOLEAN; |
Da es ein VHDL-2008 Feature ist, soltest du das ohne Package nutzen können mit einer VHDL-2008 Tool-Chain. Mit den VHDL-2008 Support Library Packages kannst du das auch allen anderen Tools nachrüsten (Nicht alle VHDL-2008 Features lassen sich nachrüsten). Die gibts hier: http://www.eda.org/fphdl/
Christoph Z. schrieb: > kannst du das auch allen anderen Tools nachrüsten Ich möchte ja gar nicht, mir hat das explizite or_reduce() ja schon ganz gut gefallen. Da wird dann nicht mit dem simplen OR Operator auch gleichzeitig der Typ geändert. Ich werde es weiterhin umständlich schreiben. > Mit den VHDL-2008 Support Library Packages du das ... nachrüsten Gut zu wissen. Ein paar schöne Sachen sind ja dabei... ;-)
Christoph schrieb: > Hallo zusammen, > > ich hätte da mal eine VHDL-Frage: > > Gibt es eine elegante Möglichkeit, einen loop über Bedingungen zu > machen? > Also z.B. möchte ich folgenden Code (eleganter übersetzen), u.a. möchte > ich eine generische Variable für die Anzahl der Bedingungen einführen > und nicht jedes mal die (Anzahl) Bedingungen abändern: > > trg <= '1' when a(0) = '1' and a(1) = '1' and a(2) = '1' and... > ...and a(15) = '1'; > Im Package IEEE.std_logic_misc.all http://www.csee.umbc.edu/~squire/download/std_logic_misc.vhdl gibt es Funktionen wie and_reduce, or_reduce die kannst du dafür benutzen trg <= '1' when and_reduce (a); Tom
Warum nicht einfach klassisch mit einer Konstanten vergleichen, also z.B.:
1 | ...
|
2 | constant AND_COMPARE : std_logic_vector (GENERIC_WIDTH-1 downto 0) := (others => '1'); |
3 | ...
|
4 | ...
|
5 | trg <= '1' when a /= AND_COMPARE else '0'; |
6 | ...
|
Erspart einem das ganze Package-Gedoens und ist auch unabhaengig davon, was fuer Tools/Plattformen ich benutzen will
> trg <= '1' when a /= AND_COMPARE else '0';
muss natuerlich ... when a = AND_COMPARE sein...
BTW: das subject "Über Conditions loopen (VHDL)" ist mein canditate für den diesjährigen Denglisch-Contest des Forums ;-)
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.