Integer Generic mit den Werten 1 oder 3

Gast #7241328
Lesenswert?

Hi,

ich möchte gerne einer Komponente ein Generic übergeben, welches nur 
bestimmte Integer Werte annehmen kann.

Den Bereich eines integer Generic kann ich ja auf einen Bereich 
beispielsweise 0-5 einschränken, aber gibt es auch eine Möglichkeit, nur 
die Werte 1,3,5 zuzulassen?
Mir ist nur der Weg über eine Enumeration aus einem Package eingefallen, 
aber dies möchte ich gerne vermeiden, da dann das Package auch in die 
Instanziierenden Module einbinden müsste.
Alternativ kann ich bei 2 oder 4 eine Assertion setzten, aber auch das 
ist für mich nur eine Notlösung. Vielleicht hat hier ja jemand noch eine 
andere Idee, es darf gern VHDL2008 sein.
(Firma: www.elpra.de) Persönliche Seite #7241517
Lesenswert?

Du kannst das ueber eine Assertion loesen. Beispiel:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity test is
6
  generic(
7
    TEST_GENERIC : integer
8
  );
9
  port(
10
    clk : in std_logic;
11
    rst : in std_logic
12
  );
13
end entity test;
14

15
architecture RTL of test is
16
  
17
begin
18

19
  assert TEST_GENERIC = 1 or TEST_GENERIC = 3 report "TEST_GENERIC is not valid!" severity failure;
20

21
end architecture RTL;

Die meisten Synthese Tools checken das und brechen mit entsprechender 
Fehlermeldung ab.
Gast #7241581
Lesenswert?

Morph schrieb:
> Mir ist nur der Weg über eine Enumeration aus einem Package eingefallen,

Das ist auf jeden Fall die sauberste Lösung. Da dein Generic keinen 
durchgegenden Wertebereich hat wie bei einem Subtyp von natural, 
erhältst du automatisch eine Enumeration, und sie solltest du auch 
explizit hinschreiben.

> aber dies möchte ich gerne vermeiden, da dann das Package auch in die
> Instanziierenden Module einbinden müsste.

Ja, aber was stört dich daran? Das ist common practice, dass man neue 
Typen in einem Package deklariert und das Package dann überall 
einbindet, wo der Typ benötgt wird.
Gast #7241584
Lesenswert?

vancouver schrieb:
> Ja, aber was stört dich daran? Das ist common practice, dass man neue
> Typen in einem Package deklariert und das Package dann überall
> einbindet, wo der Typ benötgt wird.

Könnte man auch in einem kleinen script a'la

cat files_needs_pkg.vhd >> file_mit_package.vhd

erledigen.
Gast #7241652
Lesenswert?

Vielen Dank für Eure Antworten. Ein Extra Datentypen erstellen um einen 
Wertebereich zu limitieren und diesen als Package einbinden zu müssen, 
finde ich für diesen Anwendungsfall übertrieben.
Ich werde es entweder über eine Umkodierung realisieren (es handelt sich 
hier um verschiedene Modes, die eine Nummer haben) oder eine 
entsprechende Assertion aufnehmen. Letztendlich sollte der Entwickler ja 
beim einbinden wissen, was er tut, das Modul wird ja gut dokumentiert.
Wahrscheinlich habe ich zuletzt zu viel python gescriptet und hoffte 
daher auf ein
gMyGeneric: integer in [1,3,5];
 :-)
(Firma: www.elpra.de) Persönliche Seite #7241757
Lesenswert?

vancouver schrieb:
> Das ist auf jeden Fall die sauberste Lösung. Da dein Generic keinen
> durchgegenden Wertebereich hat wie bei einem Subtyp von natural,
> erhältst du automatisch eine Enumeration, und sie solltest du auch
> explizit hinschreiben.

Es gibt durchaus Szenarien in denen das kein Sinn macht. Z.B. du hast 
ein Modul geschrieben, dass an ein Bussystem angeschlossen ist. Aus 
irengendeinem GRund unterstuetzt dein Modul z.B. nur 16 und 32 bit 
Busbreite. Diesen Fall wuerdest du auch mit einer Assertion loesen, da 
du z.B. die Busbreite garnicht zentral aus einem Package heraus in 
deinem kompletten Design bekannt machen kannst.

Es haengt stark davon ab was genau der TE ereichen moechte und was seine 
Rahmenbedingungen sind.
Gast #7243486
Lesenswert?

Tobias B. schrieb:
> ein Modul geschrieben, dass an ein Bussystem angeschlossen ist. Aus
> irengendeinem GRund unterstuetzt dein Modul z.B. nur 16 und 32 bit

Wobei das Bussystem im Allgemeinen auch nicht jede beliebige Breite 
annehmen kann. Idealerweise ist hier schon ein Aufzählungstyp definiert 
worden, von dem man dann einen Subtyp bilden könnte.
Aber du hast recht, eine Assertion wäre in diesem Fall einfacher.
(Firma: www.elpra.de) Persönliche Seite #7244104
Lesenswert?

Ein Aufzaehlungstyp ist in dem Fall schwierig. Du hast ja sowas wie:
1
entity super_toller_ip is
2
  generic(
3
    DATA_WIDTH : integer
4
  );
5
  port(
6
    clk : in std_logic;
7
    data_in : in std_logic_vector(DATA_WIDTH-1 downto 0)
8
  );
9
end entity test;

stehen. Auch wenn das DATA_WIDTH in einem Package steht, ein 
Aufzaehlungstyp hilft hier nicht weiter wenn du DATA_WIDTH auf z.B. 32 
oder 64 beschraenken willst.

Es braeuchte sowas wie bei den C++ Enums wo man mit den Initializern den 
Wert vorgeben kann. Vielleicht hat da VHDL 2019 was im Angebot?
#7245947
Lesenswert?

Tobias B. schrieb:
> Es braeuchte sowas wie bei den C++ Enums wo man mit den Initializern den
> Wert vorgeben kann. Vielleicht hat da VHDL 2019 was im Angebot?

Geht schon. Ist halt ein wenig sperrig:
1
package baudrates is
2
    type baud is (BD1200, BD2400, BD9600, BD19200);
3
    function to_integer(b : baud) return integer;
4
end package baudrates;
5

6
package body baudrates is
7
    type assoc is record
8
        bd : baud;
9
        bi : integer;
10
    end record;
11

12
    type assoc_array is array(integer range <>) of assoc;
13
    constant lut : assoc_array := ((BD1200, 1200),
14
                                   (BD2400, 2400),
15
                                   (BD9600, 9600),
16
                                   (BD19200, 19200));
17

18
    function to_integer(b : baud) return integer is
19
    begin
20
        for i in lut'low to lut'high loop
21
            if (lut(i).bd = b) then
22
                return lut(i).bi;
23
            end if;
24
        end loop;
25
    end function to_integer;

Aber wenn's mal im Package versteckt ist, sieht's ja keiner mehr:
1
entity b is
2
    generic (b : baud);
3
end entity b;
4
...
5
architecture rtl of b is
6
begin
7
    assert false report "b=" & work.baudrates.baud'image(b) severity note;
8
    assert false report "i=" & integer'image(to_integer(b)) severity note;
9
end architecture rtl;
10
...
11
b_i : entity work.b generic map(b => work.baudrates.BD2400);

@0ms:(assertion note): b=bd2400
@0ms:(assertion note): i=2400
Gast #7258656
Lesenswert?

Tobias B. schrieb:
> Was ich hiere lese ist aber, dass das nur in der Synthese klappt. Der
> Vivado Simulator hat da anscheinend immer noch Probleme. Weiss da jemand
> mehr?

Modelsim kann das wunderbar simulieren. Auch die Gratisversion. 
Vielleicht sogar auch der Vivado Simulator, man muss eben VHDL2008 
einstellen.
(Firma: www.elpra.de) Persönliche Seite #7260199
Lesenswert?

-gb- schrieb:
> Tobias B. schrieb:
>> Was ich hiere lese ist aber, dass das nur in der Synthese klappt. Der
>> Vivado Simulator hat da anscheinend immer noch Probleme. Weiss da jemand
>> mehr?
>
> Modelsim kann das wunderbar simulieren. Auch die Gratisversion.
> Vielleicht sogar auch der Vivado Simulator, man muss eben VHDL2008
> einstellen.

Das Modelsim das kann ist klar. Konnte das schon relativ frueh mit der 
ersten Charge VHDL-2008 Support IIRC.

XSim interessiert mich auch nur des Interesse wegen, weil das in den 
ersten Vivado Versionen sicher nicht geklappt hat. Da waere einfach nur 
der Progress interessant.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren