Forum: FPGA, VHDL & Co. Syntax Fragen for/case


von Mor F. (morphel)


Lesenswert?

Hallo zusammen,

ich möchte mir gerne das Codieren an einigen Stellen etwas vereinfachen 
und suche eine Möglichkeit, in VHDL folgende konstrukte zu 
implementieren:
1
for i in (1,4,6,13) loop
2
...
3
end loop;
1
case i is
2
  when 1 => ...
3
  when 2 => ...
4
  when 3-6 =>
5
  when other => NULL;
6
emd case;
Ist sowas möglich?

Lässt sich ausserdem folgendes Konstrukt in einer Zeile schreiben?
1
myStdLogicVector<= (others => '0');
2
myStdLogicVector(1)<= '1';
3
myStdLogicVector(3)<= '1';

Ich freu mich auf Eure Antworten.

Viele Grüße
  Morphel

von ElKo (Gast)


Lesenswert?

For-Schleifen gibt es nicht. Musst du mit einer "State-Machine" selbst 
machen.
Pseudo-Code:
1
if(rising_edge(clk)) then
2
   if(i = 10) then
3
      i <= 0;
4
   else
5
      i <= i + 1;
6
      case i is
7
        when 1 => ...
8
        when 2 => ...
9
        when 3-6 =>
10
        when other => NULL;
11
      end case;
12
   end if;
13
end if;

Mor F. schrieb:
> Lässt sich ausserdem folgendes Konstrukt in einer Zeile schreiben?
Das Stichwort heißt vhdl und concatenation. Einfach mal danach suchen.

von Markus F. (mfro)


Lesenswert?

Mor F. schrieb:
> Hallo zusammen,
>
> ich möchte mir gerne das Codieren an einigen Stellen etwas vereinfachen
> und suche eine Möglichkeit, in VHDL folgende konstrukte zu
> implementieren:
>
1
> for i in (1,4,6,13) loop
2
> ...
3
> end loop;
4
>
>
da wüsste ich jetzt auf Anhieb nichts.


>
1
> case i is
2
>   when 1 => ...
3
>   when 2 => ...
4
>   when 3-6 =>
5
6
    when 3|4|5|6 =>
ist durchaus gültiges VHDL. Die Möglichkeit, hier einen Range anzugeben 
gibt es aber m.W nicht.

> Lässt sich ausserdem folgendes Konstrukt in einer Zeile schreiben?
>
1
> myStdLogicVector<= (others => '0');
2
> myStdLogicVector(1)<= '1';
3
> myStdLogicVector(3)<= '1';
4
>
1
    myStdLogicVector <= (1 => '1', 3 => '1', others => '0');
(positional association). "others" muss immer die letzte Position sein.

von Markus F. (mfro)


Lesenswert?

ElKo schrieb:
> For-Schleifen gibt es nicht.

Selbstverständlich gibt es for-Schleifen.

von Christian R. (supachris)


Lesenswert?

Markus F. schrieb:
> ElKo schrieb:
> For-Schleifen gibt es nicht.
>
> Selbstverständlich gibt es for-Schleifen.

Die machen nur was komplett anderes als z.B. in C.

von Markus F. (mfro)


Lesenswert?

Christian R. schrieb:
> Markus F. schrieb:
>> ElKo schrieb:
>> For-Schleifen gibt es nicht.
>>
>> Selbstverständlich gibt es for-Schleifen.
>
> Die machen nur was komplett anderes als z.B. in C.

Die machen genau dasselbe wie in C.

Bloß eben bei der Erzeugung der Schaltungsbeschreibung und nicht in 
der "fertigen" Schaltung. Mach' dir klar, dass ein VHDL "Programm" 
keinen ablauffähigen Code, sondern eine Verhaltensbeschreibung erzeugt. 
Im weitesten Sinn wie ein (frühes) Malprogramm ("Strich(a, b)"). Im FPGA 
landet nicht dein "Programm", sondern das Ergebnis (das Bild).

Das ist praktisch genau dasselbe wie C++ Template-Metaprogramming - da 
wirst Du im "fertigen" Programm auch keine sequentielle Schleife finden.

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


Lesenswert?

Mor F. schrieb:
> ich möchte mir gerne das Codieren an einigen Stellen etwas vereinfachen
Da wäre es interessant, zu sehen, wie kompliziert diese Stellen gerade 
aussehen...

Mor F. schrieb:
> Lässt sich ausserdem folgendes Konstrukt in einer Zeile
> schreiben?
> myStdLogicVector<= (others => '0');
> myStdLogicVector(1)<= '1';
> myStdLogicVector(3)<= '1';
Es ist sogar eher so, dass du sowas ausschließlich in einem Prozess 
schreiben kannst, weil dort "die letzte Zuweisung gewinnt". Außerhalb 
eines Prozesses als nebenläufige (concurrent) Zuweisung hast du 
"multiple drivers" auf den beiden fraglichen Signalen.

: Bearbeitet durch Moderator
von Christian R. (supachris)


Lesenswert?

Markus F. schrieb:
> Die machen genau dasselbe wie in C.

Uiuiui, sowas einem ofensichtlichen Anfänger zu schreiben, ist gewagt.
In C macht eine for-Schleife einen sequenziellen Ablauf.
In VHDL ist eine for-Schleife eine etwas bequemere und evtl. 
übersichtlichere Art, parallel laufende (oder parallel instanziierte) 
Dinge zu beschreiben. Für einen sequenziellen Ablauf braucht man da eien 
State Machine, wie auch immer die aussieht.
Wenn, dann kann man in der Simulation eine zeitliche Sequenz über das 
loop Statement machen, das klappt aber dann halt nur in der Simulation.

von Mor F. (morphel)


Lesenswert?

@all. Vielen Dank für Eure Antworten, speziell an Markus F. für die 
ersten Lösungen.

Was mit for Schleifen in Hardware tatsächlich passiert, ist mir klar.

Lothar M. schrieb:
> Mor F. schrieb:
>> ich möchte mir gerne das Codieren an einigen Stellen etwas vereinfachen
> Da wäre es interessant, zu sehen, wie kompliziert diese Stellen gerade
> aussehen...

Den Code gibt es noch nicht, aber ich habe konkrete Beispiele im Sinn.
 - For loop:
In einer Simulation wollte ich meine Testbench mal schnell einen 
bestimmten Parameter variieren und habe somit eine for loop mit 
bestimmten Werten drumherum bauen wollen.
Natürlich funktioniert auch copy paste oder ein constantes Array, aus 
dem dann die aktuellen Parameter bezogen werden, die for loop wäre aber 
in dem Fall die schnellste Lösung gewesen.

 - case construkt:
Hier habe ich einen Adressdecoder im Sinn.
Case 3-6 füllt dabei bestimmte Felder eines Arrays. Ich habe mehrere 32 
Wort große Arrays, die durch einen Prozesser beschrieben werden können, 
aber auch einzelne Worte.
Abhilfe schafft hier beispielsweise ein if construct:
1
if ProcAddr >= Array1BaseAddr and ProcAddr <Array1BaseAddr +31 then
2
  Array1[addr-Array1BaseAddr]<=ProcData;
3
elsif ProcAddr >= Array2BaseAddr and ProcAddr <Array2BaseAddr +31 then
4
  Array2[addr-Array2BaseAddr]<=ProcData;
5
else
6
  case ProcAddr is
7
    when  Register1Adddr => 
8
      Register1 <= ProcData;
9
    ...
10
  end case;
11
end if;

Übersichtlicher fänd ich es jedoch, wenn alles in einer Case Anweisung 
enthalten ist, möchte aber nicht mehrfach 32 Adressen "verodern".

Bei der Zuweisung habe ich eine Instanziierung im Sinn, leider war mein 
Beispiel jedoch schlecht gewählt, da ich auch Bereiche angeben will. Ich 
habe so etwas
1
type tRegisterArray is array(0 downto 31) of std_logic_vector(15 downto 0);
2
type tProcessorArray is array(0 downto 511) of std_logic_vector(15 downto 0);
3
signal sParameter1 : tRegisterArray;
4
signal sParameter2 : tRegisterArray;
5
signal sProcessorData : tProcessorArray;
6
7
  AddressdecoderInst : entity work.Addressdecoder
8
    port map(
9
      -- clk, Rst, Processor signale  ...
10
      sProcessorData => ( 1 to 31 => sParameter1, 
11
                          64 to 95 => Parameter2, 
12
                          others=> (others => '0')
13
                        )
14
    );

Hierzu noch irgendwelche Ideen?

von Markus F. (mfro)


Lesenswert?

Christian R. schrieb:
> Uiuiui, sowas einem ofensichtlichen Anfänger zu schreiben, ist gewagt.

Erstens erschien mir (wie in der Antwort dann m.E. auch bestätigt wurde) 
die Frage keineswegs als "Anfänger-Frage" sondern eher in der Richtung, 
wie sich VHDL-Sprachkonstrukte besser nutzen lassen, als einfach nur 
stumpf "Drähte und Schalter" zu verlegen. Und das gefällt mir (da hat 
sich offensichtlich jemand Gedanken gemacht).

> In C macht eine for-Schleife einen sequenziellen Ablauf.
> In VHDL ist eine for-Schleife eine etwas bequemere und evtl.
> übersichtlichere Art, parallel laufende (oder parallel instanziierte)
> Dinge zu beschreiben. Für einen sequenziellen Ablauf braucht man da eien
> State Machine, wie auch immer die aussieht.

Selbst wenn man's gerade lernt, kann man's genausogut auch gleich 
richtig lernen.

In VHDL erzeugt eine for-Schleife genauso einen sequentiellen Ablauf wie 
in jeder anderer Sprache auch. Die Behauptung, das sei was anderes, ist 
m.E. genauso falsch wie die Behauptung, Variablen wären was völlig 
anderes als in anderen Sprachen. Die Hürde, die man gedanklich 
überspringen muss, ist lediglich, für wen oder was diese Statements wann 
"Code" erzeugen bzw. wann genau sie ablaufen.

VHDL erzeugt eine Beschreibung; dementsprechend laufen Schleifen (bzw. 
gelten Variablen) während der Erzeugung dieser Beschreibung, das 
Ergebnis ist das funktionale Äquivalent als Digitalschaltung. Wie sonst 
wollte man simpel erklären, dass ein report-statement in einer 
for-Schleife genau das tut, was ein Programmierer erwarten würde?

Wenn man den Knoten mal zerschlagen hat, ist der Rest eigentlich völlig 
logisch. M.E. viel logischer als zu behaupten, es gäbe da riesige 
Unterschiede.

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


Lesenswert?

Markus F. schrieb:
> es gäbe da riesige Unterschiede.
Naja, es ist eben irreführend, es überhaupt vergleichen und 
Gemeinsamkeiten finden zu wollen.

Wenn ich in der Sprache (A) ein Wort habe und in der Sprache (B) ein 
Wort, das genau gleich geschrieben wird, dann hat das evtl. trotzdem 
eine ganz unterschiedliche Bedeutung und Auswirkung. Ein (A) englisches 
Gift wäre mir z.B. bedeutend lieber als ein (B) deutsches Gift.

Und jetzt kommts: C und VHDL sind unterschiedliche Sprachen...

: Bearbeitet durch Moderator
von Markus F. (mfro)


Lesenswert?

Mor F. schrieb:
> type tRegisterArray is array(0 downto 31) of std_logic_vector(15 downto
> 0);
> type tProcessorArray is array(0 downto 511) of std_logic_vector(15
> downto 0);
> signal sParameter1 : tRegisterArray;
> signal sParameter2 : tRegisterArray;
> signal sProcessorData : tProcessorArray;
>
>   AddressdecoderInst : entity work.Addressdecoder
>     port map(
>       -- clk, Rst, Processor signale  ...
>       sProcessorData => ( 1 to 31 => sParameter1,
>                           64 to 95 => Parameter2,
>                           others=> (others => '0')
>                         )
>     );
>
> Hierzu noch irgendwelche Ideen?

Wenn ich richtig verstehe, möchtest Du mehrere kleine Arrays in ein 
grosses mappen?
Du könntest so was ähnliches machen:
1
    subtype l_arr_type is std_ulogic_vector(511 downto 0);
2
    signal l_arr    : l_arr_type := (others => '0');
3
    signal s_arr    : std_ulogic_vector(31 downto 0) := x"12345678";
4
    
5
begin   
6
    g_loop: for i in 0 to 15 generate
7
        constant l      : integer := s_arr'length;
8
    begin
9
        g_case: case i generate
10
            when 0 =>
11
            when 1|3|5|11|13 => l_arr(i * l + l - 1 downto i * l) <= s_arr;
12
            when others =>
13
        end generate;
14
    end generate;
15
16
...
17
18
  AddressdecoderInst : entity work.Addressdecoder
19
    port map(
20
      -- clk, Rst, Processor signale  ...
21
      sProcessorData => l_arr
22
    );

Ist aber erstens die Frage, ob das nicht mit Kanonen auf Spatzen usw. 
(im Beispiel sind das 10 Zeilen anstatt fünf) und zweitens, ob deine 
Tools das können (das "case ... generate" gibt es nur in VHDL 2008).

: Bearbeitet durch User
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.