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


von Johannes H. (Gast)


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.
1
library IEEE; 
2
use IEEE.std_logic_1164.all;
3
4
entity col_row_buttons is 
5
  generic (COL_ROW_BUTTONS : natural := 4;
6
       KEYPAD_BUTTONS   : natural := 16);
7
  port (
8
    clk_i          : in std_logic;
9
    reset_i       : in std_logic;
10
    row_buttons_i    : in std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
11
    col_buttons_o    : out std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
12
    pressed_button_o   : out std_logic_vector (KEYPAD_BUTTONS - 1 downto 0)); 
13
end col_row_buttons;
14
15
16
17
architecture rtl of col_row_buttons is 
18
    signal s_column_buttons  : std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
19
    signal s_pressed_button  : std_logic_vector (KEYPAD_BUTTONS - 1 downto 0);
20
  
21
  p_column : process (clk_i, reset_i)
22
    variable var_column : natural in range 0 to 3;
23
  begin 
24
    if reset_i = '1' then 
25
      s_column_buttons <= x"F"; 
26
      var_column := 0;
27
    elsif clk_i = '1' and clk_i'event then 
28
      if s_presc_en = '1' then 
29
        if var_column = 0 then 
30
          s_column_buttons <= "1110";
31
        elsif var_column = 1 then 
32
          s_column_buttons <= "1101";
33
        elsif var_column = 2 then 
34
          s_column_buttons <= "1011"; 
35
        elsif var_column = 3 then 
36
          s_column_buttons <= "0111";
37
          var_column := 0; 
38
        end if;         
39
        var_column := var_column + 1; 
40
      end if; 
41
    end if; 
42
  end process p_column;
43
        
44
  col_buttons_o <= s_column_buttons;
45
  
46
  p_press_buttons : process (clk_i, reset_i)
47
    variable var_temp : std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
48
  begin 
49
    if reset_i = '1' then 
50
      s_pressed_button <= (others => '1');
51
    elsif clk_i = '1' and clk_i'event then 
52
      case s_column_buttons is -- hier gibt er mir die Fehlermeldung aus
53
        when "1110" => 
54
                         .....
55
      end case;
56
    end if; 
57
  end process; 
58
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

von Lars K. (mrlaush)


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
von Johannes H. (Gast)


Lesenswert?

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

von Curby23523 N. (Gast)


Lesenswert?

Warum lässt du denn ausgerechnet den Inhalt der Switch weg..?

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


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:
1
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:
1
  generic (
2
       COL_ROW_BUTTONS : natural range 4 to 32 := 4;  -- 32 ist hier mal ein beliebiges Maximum
3
       KEYPAD_BUTTONS  : natural := 16
4
  );

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

von Markus F. (mfro)


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.

von Johannes H. (Gast)


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:
1
generic (
2
        COL_ROW_BUTTONS : natural range 4 to 32 := 4;  -- 32 ist hier mal 
3
 --ein beliebiges Maximum
4
        KEYPAD_BUTTONS  : natural := 16
5
   );

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

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


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.

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.