Forum: FPGA, VHDL & Co. Integer Generic mit den Werten 1 oder 3


von Morph (Gast)


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.

von Achim S. (Gast)


Lesenswert?

Du könntest in deinem Beispiel für das Generic n nur den Bereich 0..2 
zulassen und dann in deiner Komponente mit (2*n+1) arbeiten (ergibt die 
Werte 1,3,5).

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


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.

von Kritiker (Gast)


Lesenswert?

Der saubere Weg ist über einen eingeschränkten Datentypen.
Der wäre systemweit zu verwenden.

von vancouver (Gast)


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.

von Scriptstrolch (Gast)


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.

von Morph (Gast)


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];
 :-)

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


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.

von vancouver (Gast)


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.

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


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?

: Bearbeitet durch User
von Markus F. (mfro)


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

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


Lesenswert?

Kannst du das mal auf mein Beispiel adaptieren in dem ein Port eine 
Busbreite hat abhaengig vom Generic?

von modulo (Gast)


Lesenswert?

Wie wäre es mit modulo?
http://www.mathematik.net/IT-programmierlogik/log5s3.htm
Überprüfung auf Gerade oder Ungerade?

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


Lesenswert?

Tobias B. schrieb:
> Kannst du das mal auf mein Beispiel adaptieren in dem ein Port eine
> Busbreite hat abhaengig vom Generic?

Ahhh, habs geschnallt. Ja das wuerde gehen. :-)

von Markus F. (mfro)


Lesenswert?

VHDL 2008 hat da aber tatsächlich noch ein extra Schmankerl zu bieten: 
generic packages/generic types.

Damit kann man das Package universell für alle möglichen Lookups 
schreiben.

Leider ist mir kein Synthesetool bekannt, das VHDL 2008 dafür 
ausreichend beherrscht.

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


Lesenswert?

Markus F. schrieb:
> VHDL 2008 hat da aber tatsächlich noch ein extra Schmankerl zu bieten:
> generic packages/generic types.

Jep, zumindest keins von den FPGA Vendor. :-(

von Gustl B. (-gb-)


Lesenswert?

Vivado kann generic packages, Quartus Pro auch.

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


Lesenswert?

Gustl B. schrieb:
> Vivado kann generic packages, Quartus Pro auch.

Mittlerweile ja. Gut zu wissen. 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?

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Gustl B. schrieb:
> Quartus Pro auch

Leider weit ausserhalb jedes Hobby-Budgets

von Blechbieger (Gast)


Lesenswert?

Markus F. schrieb:
>> Quartus Pro auch
>
> Leider weit ausserhalb jedes Hobby-Budgets

Für den Cyclone 10 GX läuft es auch ohne Lizenz. Die größeren FPGA die 
eine Lizenz brauchen sind ja ebenfalls zu teuer für Hobby.

von -gb- (Gast)


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.

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


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.

: Bearbeitet durch User
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.