mikrocontroller.net

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


Autor: Mor Fel (morphel)
Datum:

Bewertung
0 lesenswert
nicht 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:
for i in (1,4,6,13) loop
...
end loop;
case i is
  when 1 => ...
  when 2 => ...
  when 3-6 =>
  when other => NULL;
emd case;
Ist sowas möglich?

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

Ich freu mich auf Eure Antworten.

Viele Grüße
  Morphel

Autor: ElKo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
For-Schleifen gibt es nicht. Musst du mit einer "State-Machine" selbst 
machen.
Pseudo-Code:
if(rising_edge(clk)) then
   if(i = 10) then
      i <= 0;
   else
      i <= i + 1;
      case i is
        when 1 => ...
        when 2 => ...
        when 3-6 =>
        when other => NULL;
      end case;
   end if;
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.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht 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:
>
> for i in (1,4,6,13) loop
> ...
> end loop;
> 
>
da wüsste ich jetzt auf Anhieb nichts.


>
> case i is
>   when 1 => ...
>   when 2 => ...
>   when 3-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?
>
> myStdLogicVector<= (others => '0');
> myStdLogicVector(1)<= '1';
> myStdLogicVector(3)<= '1';
> 
    myStdLogicVector <= (1 => '1', 3 => '1', others => '0');
(positional association). "others" muss immer die letzte Position sein.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ElKo schrieb:
> For-Schleifen gibt es nicht.

Selbstverständlich gibt es for-Schleifen.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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
Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mor Fel (morphel)
Datum:

Bewertung
0 lesenswert
nicht 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:
if ProcAddr >= Array1BaseAddr and ProcAddr <Array1BaseAddr +31 then
  Array1[addr-Array1BaseAddr]<=ProcData;
elsif ProcAddr >= Array2BaseAddr and ProcAddr <Array2BaseAddr +31 then
  Array2[addr-Array2BaseAddr]<=ProcData;
else
  case ProcAddr is
    when  Register1Adddr => 
      Register1 <= ProcData;
    ...
  end case;
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
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?

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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
Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht 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:
    subtype l_arr_type is std_ulogic_vector(511 downto 0);
    signal l_arr    : l_arr_type := (others => '0');
    signal s_arr    : std_ulogic_vector(31 downto 0) := x"12345678";
    
begin   
    g_loop: for i in 0 to 15 generate
        constant l      : integer := s_arr'length;
    begin
        g_case: case i generate
            when 0 =>
            when 1|3|5|11|13 => l_arr(i * l + l - 1 downto i * l) <= s_arr;
            when others =>
        end generate;
    end generate;

...

  AddressdecoderInst : entity work.Addressdecoder
    port map(
      -- clk, Rst, Processor signale  ...
      sProcessorData => l_arr
    );

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

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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.