Forum: FPGA, VHDL & Co. Über Conditions loopen (VHDL)


von Christoph (Gast)


Lesenswert?

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

von Hululu (Gast)


Lesenswert?

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)

von Hululu (Gast)


Lesenswert?

Das warn ja 16 Bits, nicht 15. Also entsprechend erweitern.

von Stephan (Gast)


Lesenswert?

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.

von Hululu (Gast)


Lesenswert?

>Ich verstehe das Problem eher so:

Dann verstehst Du es falsch.

von Christoph (Gast)


Lesenswert?

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.

von dennis (Gast)


Lesenswert?

Hallo ,
vielleicht hilft ja sowas

ausgang <= eingang(N) ;

dann must du nur zwei Signale anpassen.

Mfg

von Maxx (Gast)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Christoph (Gast)


Lesenswert?

Danke, ihr habt mir sehr geholfen!!

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


Lesenswert?

> 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

von Maxx (Gast)


Lesenswert?

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.

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


Lesenswert?

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...

von Fpgakuechle K. (Gast)


Lesenswert?

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,

von Fpgakuechle K. (Gast)


Lesenswert?

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

von Maxx (Gast)


Lesenswert?

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.

von Christoph Z. (christophz)


Lesenswert?

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/

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


Lesenswert?

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...  ;-)

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

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

von berndl (Gast)


Lesenswert?

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

von berndl (Gast)


Lesenswert?

> trg <= '1' when a /= AND_COMPARE else '0';

muss natuerlich ... when a = AND_COMPARE sein...

von Leonard Lebewohl (Gast)


Lesenswert?

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