mikrocontroller.net

Forum: FPGA, VHDL & Co. switch-case Problem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Johannes H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Forenmitglieder,

ich bin gerade dabei, mich in die VHDL-Welt anzutatsten. Aus diesem 
Grund schreibe ich gerade kleine simple VHDL-Programme und bin auch 
schon leider um stocken gekommen.

library IEEE; 
use IEEE.std_logic_1164.all;

entity col_row_buttons is 
  generic (COL_ROW_BUTTONS : natural := 4;
       KEYPAD_BUTTONS   : natural := 16);
  port (
    clk_i          : in std_logic;
    reset_i       : in std_logic;
    row_buttons_i    : in std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
    col_buttons_o    : out std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
    pressed_button_o   : out std_logic_vector (KEYPAD_BUTTONS - 1 downto 0)); 
end col_row_buttons;



architecture rtl of col_row_buttons is 
    signal s_column_buttons  : std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
    signal s_pressed_button  : std_logic_vector (KEYPAD_BUTTONS - 1 downto 0);
  
  p_column : process (clk_i, reset_i)
    variable var_column : natural in range 0 to 3;
  begin 
    if reset_i = '1' then 
      s_column_buttons <= x"F"; 
      var_column := 0;
    elsif clk_i = '1' and clk_i'event then 
      if s_presc_en = '1' then 
        if var_column = 0 then 
          s_column_buttons <= "1110";
        elsif var_column = 1 then 
          s_column_buttons <= "1101";
        elsif var_column = 2 then 
          s_column_buttons <= "1011"; 
        elsif var_column = 3 then 
          s_column_buttons <= "0111";
          var_column := 0; 
        end if;         
        var_column := var_column + 1; 
      end if; 
    end if; 
  end process p_column;
        
  col_buttons_o <= s_column_buttons;
  
  p_press_buttons : process (clk_i, reset_i)
    variable var_temp : std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
  begin 
    if reset_i = '1' then 
      s_pressed_button <= (others => '1');
    elsif clk_i = '1' and clk_i'event then 
      case s_column_buttons is -- hier gibt er mir die Fehlermeldung aus
        when "1110" => 
                         .....
      end case;
    end if; 
  end process; 
end architecture rtl;


Der Fehler liegt in der case Zeile. Wenn ich das in Modelsim kompeliere 
bekomme ich als Fehlermeldung: "Array type case expression must be of a 
locally static subtype" heraus. Mir ist klar, dass die die case 
Bedingung statisch sen muss, deshalb habe ich auh probiert, diese zuert 
in eine Variable zuzuweißen und die Variable als Bedingung abzufragen, 
jedach kamm hier auch die selbe Fehlermeldung :(

Ich hoffe ihr könnt mir da weiterhelfen.

Lg

Autor: Lars K. (mrlaush)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hi,

wo steht das Stichwort "switch"? oder brauch man das bei VHDL nicht?
Ich glaube im VHDL gibt es doch nur so ein "Case-statement" oder?

Viele Grüße

: Bearbeitet durch User
Autor: Johannes H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aso ups genau in vhdl braucht man switch nicht, habe es somit falsch im 
betreff geschrieben mein Fehler.

Autor: Curby23523 N. (nils_h494)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Warum lässt du denn ausgerechnet den Inhalt der Switch weg..?

: Bearbeitet durch User
Autor: Tobias B. (Firma: www.elpra.de) (ttobsen)
Datum:

Bewertung
4 lesenswert
nicht lesenswert
Johannes H. schrieb:
> Der Fehler liegt in der case Zeile. Wenn ich das in Modelsim kompeliere
> bekomme ich als Fehlermeldung: "Array type case expression must be of a
> locally static subtype" heraus. Mir ist klar, dass die die case
> Bedingung statisch sen muss, deshalb habe ich auh probiert, diese zuert
> in eine Variable zuzuweißen und die Variable als Bedingung abzufragen,
> jedach kamm hier auch die selbe Fehlermeldung :(

Hallo Johannes,

das Problem ist, dass die Länge deines Vektors s_column_buttons eine 
generische Länge hat (Längen hängt ab von COL_ROW_BUTTONS).

Ersetze bitte mal COL_ROW_BUTTONS durch die eigentliche Zahl und du 
wirst sehen, dass die Meldung verschwindet. Das macht in deinem Fall 
auch Sinn, weil die einzelnen Fälle auch eine fixe Länge haben, daher 
braucht auch der "Probant" eine fixe Länge. Dieses Verhalten ist 
übrigens in der VHDL Spezifikation so definiert, wenn du mal tiefer 
einsteigen möchtest, kann ich empfehlen da mal einen kleinen Blick 
reinzuwerfen.

Du solltest mal folgendes probieren:
case s_column_buttons(3 downto 0) is

Damit ist die Abfrage genauso locally static, wie die einzelnen Fälle 
die du angibst.

Entsprechend solltest du noch die Generics einschränken, damit das bei 
Fehlkonfiguration nicht um die Ohren fliegt:
  generic (
       COL_ROW_BUTTONS : natural range 4 to 32 := 4;  -- 32 ist hier mal ein beliebiges Maximum
       KEYPAD_BUTTONS  : natural := 16
  );

Ich habe hier gerade kein Modelsim Zugriff, aber zumindest prinzipiell 
sollte es so korrekt sein.

Autor: Markus F. (mfro)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
in VHDL 2008 ist diese Beschränkung übrigens (sinnvollerweise) 
aufgehoben.

Wenn Du die VHDL-Version in den Compiler Settings auf "1076-2008" 
einstellst (und Du deine anderen Fehler noch korrigierst), wird Modelsim 
das Statement akzeptieren.

Autor: Johannes H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat wirklich geholfen vielen, vielen Dank :)

Jedoch habe ich diesen Absatz nicht ganz verstanden:

Tobias B. schrieb:
> Entsprechend solltest du noch die Generics einschränken, damit das bei
> Fehlkonfiguration nicht um die Ohren fliegt:
generic (
        COL_ROW_BUTTONS : natural range 4 to 32 := 4;  -- 32 ist hier mal 
 --ein beliebiges Maximum
        KEYPAD_BUTTONS  : natural := 16
   );

Von 3 downto 0 (also 4) ist mein eigentliches Signal, aber warum bis 32 
definieren und wozu eigentlich?

Autor: Tobias B. (Firma: www.elpra.de) (ttobsen)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Das ist einfach ein beliebiges Maximum. Du kannst auch 4 to 2**32-1 
schreiben. Solch einen breiten Datenbus wirst du allerdings selten 
brauchen. ;)

Ersetze einfach die 32 mit einem Wert deiner Wahl.

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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