Forum: FPGA, VHDL & Co. Datentyp in VHDL


von Tobias Danz (Gast)


Lesenswert?

Hallo zusammen, ich hoffe mir kann jemand helfen und bedanke mich schon
mal im voraus für eure Hilfen. Ich habe ein PAckage definiert, das wie
folgt aussieht:

package showdisplay is
  type T_ANZEIGE is array (2 downto 0) of integer range 0 to 10;
  type T_DISPLAY is array (2 to 0) of std_ulogic_vector (6 downto 0);
end showdisplay;

so ich verwende diese Typen dann für eine Sieben segment Anzeige in
einer CAse Anweisung, die wie folgt aussieht:

 for i in 0 to 2 loop
    case display_photo is
  when 0 => display <= "0111111";
  when 1 => display <= "0000011";
  when 2 => display <= "1101101";
  when 3 => display <= "1100111";
  when 4 => display <= "1010011";
  when 5 => display <= "1110110";
  when 6 => display <= "1111110";
  when 7 => display <= "0100011";
  when 8 => display <= "1111111";
  when 9 => display <= "1110111";
  when others => display <= "0000000";
    end case;
 end loop;

Wenn ich das synthetisieren will, kommt immer folgende Meldung:

TYPE of display is incompatible with type 0111111??

und diese fehlermeldung sieht für alle so aus. Dazu muß man sagen, daß
dislay als T_DISPLAY definiert ist
und display_photo als T_ANZEIGE?


kennt jemand dieses Problem?

von T.M. (Gast)


Lesenswert?

Du definierst 2-dimensionale Arrays und übergibts aber nur
1-dimensionale Vectoren an das Array. Das wird wohl ein Fhler sein,
dann wird wohl eher stimmen:

case display_photo(i) is
when 0 => display(i) <= "......";
....

sonst ergibt ja auch die loop Schleife keinen Sinn.

Grüße
T.M.

von FPGA-User (Gast)


Lesenswert?

das ist ganz einfach:

wenn display_photo als array deklariert ist, dann musst Du es
auch als solches behandeln, sprich Du musst ein Element
des arrays in der case-Anweisung referenzieren, z.B.

case display_photo(i) is ...

mit display sieht es genauso aus, Du kannst nicht dem array
einen einzelnen Wert zuweisen, hier fehlt wiederum die Angabe
des Array-Indexes ,also z.B. display(i).

T_Display würde ich übrigens so deklarieren:

type T_DISPLAY is array (2 downto 0) of std_logic_vector (6 downto 0);

oder

type T_DISPLAY is array (0 to 2) of std_logic_vector (6 downto 0);

noch schöner wäre es, eine Funktion, z.B. bcd_to_7_seg() zu schreiben
und diese dann anstelle der Case-Anweisung zu verwenden.
Eine solche Funktion wäre universell und könnte von Dir in jedem
Projekt unverändert verwendet werden (Design - to - ReUse)

von FPGA-User (Gast)


Lesenswert?

uups war wieder einer schneller mit eintippen, doppelt hält besser

von Tobias Danz (Gast)


Lesenswert?

Danke, Danke, ich habe den Fehler im Moment auch gefunden. Ich arbeite
das erste Mal mit mehrdimensionalen Feldern, deswegen hatte ich
Probleme. Trotzdem danke für eure Unterstüzung.

MfG Tobias

von Tobias Danz (Gast)


Lesenswert?

@FPGA-User:

wie sähe denn so eine Funktion aus? Ich ahbe noch nicht mit einer
Funktion gearbeitet. Kannst du mir auf die Sprünge helfen?

von FPGA-User (Gast)


Lesenswert?

OK, wenn Du noch keine Funktionen verwendet hast, hier ein
Beispiel:

Im Package deklarierst Du die Funktion :
----------------------------------------

   function bcd_to_7seg( cnt : std_logic_vector(3 downto 0))
      return std_logic_vector;

Und im Package Body kommt dann die Implementierung :
-----------------------------------------------------


   function bcd_to_7seg( cnt : std_logic_vector(3 downto 0))
      return std_logic_vector
   is
      variable res : std_logic_vector(6 downto 0);
   begin
      case cnt is
         when x"0" => res := "1111110";
         when x"1" => res := "0110000";
         when x"2" => res := "1101101";
         when x"3" => res := "1111001";
         when x"4" => res := "0110011";
         when x"5" => res := "1011011";
         when x"6" => res := "0011111";
         when x"7" => res := "1110000";
         when x"8" => res := "1111111";
         -- Decodierung > 9 wird nicht benoetigt,
         -- kostet aber auch keine extra Ressourcen
         when x"9" => res := "1110011";
         when x"A" => res := "1110111";
         when x"B" => res := "0011111";
         when x"C" => res := "1001110";
         when x"D" => res := "0111101";
         when x"E" => res := "1001111";
         when x"F" => res := "1000111";
         when others => res := "1111111"; -- nur fuer Simulation
      end case;
      return res;
   end;

Der Aufruf könnte dann so aussehen:

LED1 <= bcd_to_7seg(counter_1);

wobei LED1 : std_logic_vector(6 downto 0) ist

Abhängig vom Typ (gem. Anode / Kathode) muss evt. invertiert
werden, was Du sicher selbst hinbekommst.

Funktionen verstanden?

von Tobias Danz (Gast)


Lesenswert?

Ja verstanden, habe ich es, cnt is einfach ein Eingangsport, wo die BCD
Werte reinkommen?

von FPGA-User (Gast)


Lesenswert?

prinzipiell ja, es ist auch ähnlich wie in C, also
die Funktion bekommt einen Wert übergeben - in diesem
Fall ein 4 bit vector und liefert ein Ergebnis zurück,
hier ein 7-bit vector. Das funktioniert natürlich auch mit
anderen Datentypen, z.B. Integer, Signed, Unsigned usw.

In Hardware kann man sich das so Vorstellen:
Ein Schaltung hat 4 Eingänge und 7 Ausgänge, dazwischen
liegt der 7-Seg Decoder

Aber Vorsicht, "Funktion" kann hier missverstanden werden,
das ist kein Programmteil, der mehrfach aufgerufen wird, sondern
die entspr. Hardware (also praktisch ein 7447 IC) wird für
jedes Ausgangssignal neu implementiert.

cnt kann übrigens auch input oder eingang heißen, das ist nur
die interne Bezeichnung für den 4-bit Eingangsvektor.

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.