Forum: FPGA, VHDL & Co. Ein von einem anderen Generic abhängiger Generic


von Martin (Firma: Angestellt) (herki)


Lesenswert?

Hallo Miteinander

Ich habe mehrere Generics
1
generic(
2
  gSPI_Breite        :  integer      :=8;    -- Variable zur Anpassung der Laenge der empfangenen Daten
3
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
4
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
5
  gAusgang_Resetzustand  :  std_logic_vector (gAnzahl_O - 1 downto 0) := X"00000"; -- Variable zur Anpassung des Resetzustandes
6
  gBefehlsbreite      :  integer      :=3;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes mit der Befehlsnummer
7
  gTelegramm_1_InfoBreite  :  integer      :=1;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Telegrammnummer
8
  gTelegramm_2_InfoBreite  :  integer      :=1;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Telegrammnummer
9
  gRX_Adressbreite    :  integer      :=7;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Adresse
10
  gRX_Befehlsbreite    :  integer      :=3;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für den Befehl
11
  gRX_Nutzdatenbreite    :  integer      :=4;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Nutzdatenbreite
12
  gTX_Alle_I_uebertragen  :  integer      :=4;    -- Variable die angibt wieviele Telegramme zur Uebertragung der Eingänge notwendig sind. Diese besteht aus Startadresse + n*8Bit Daten; Beispiel: 32 Eingänge --> 5 (CRC muss nicht mit angegeben werden)
13
  gTX_Alle_O_uebertragen  :  integer      :=10;    -- Variable die angibt wieviele Telegramme zur Uebertragung der Ausgänge notwendig sind. Diese besteht aus Startadresse + n*8Bit Daten; Beispiel: 32 Ausgänge --> 5 (CRC muss nicht mit angegeben werden)
14
  gTX_Alle_IO_uebertragen  :  integer      :=10    -- Variable die angibt wieviele Telegramme zur Uebertragung der IO notwendig sind. Diese besteht aus Startadresse + n*8Bit Daten; Beispiel: 32 IO --> 5 (CRC muss nicht mit angegeben werden)
15
  );

Ich möchte den Resetzustand via Generic festlegen. Da aber die Anzahl 
der Ausgangspins variabel ist muss auch der Generic mit den Resetwerten 
der Ausgänge variabel lang sein.

Meine Frage ist nun:
Ist es überhaupt möglich das so zu machen wie in dem Generic oder kann 
ich mein Vorhaben nur über Konstanten erreichen?


Über eine Antwort freue ihc mich wie immer :)

Viele Grüße

Martin

von Ulf (Gast)


Lesenswert?

Habe Deine Frage nicht verstanden

von Björn C. (bjoernc) Benutzerseite


Lesenswert?

Jetzt einfach mal ins Blaue gerade wenn du etwas resetten möchtest zB. 
das SPI Register, welches eine variable Bitbreite hat, kannst du dies 
mittel others realisieren das sieht dann in etwa so aus:
1
prc:PROCESS ( clk ) IS 
2
BEGIN
3
 IF clk'event AND ... THEN
4
   IF reset = '1' THEN
5
    regist_vector <= ( OTHERS => '0' );
6
  ELSE
7
   ...
8
  END IF;
9
 END IF;
10
END PROCESS;

Ich hoffe ich habe deine Frage richtig interpretiert.

von Martin (Firma: Angestellt) (herki)


Lesenswert?

Hallo

Entschudigt bitte die unkalre Fragestellung

Ich habe ein Generic welches die Breite des Ausgangsregister (gAnzahl_O) 
parametriert.
Und dann habe ich noch ein Generic welches die Resetzustände festlegen 
soll (gAusgang_Resetzustand). Die Länge dieses Generics ist abhängig von 
der Breite des Ausgangsregister.

Mein Compiler meckert nun wenn ich obenstehenden Code compilieren 
möchte, dass erst auf ein Generic refernziert werden kann wenn die 
Generic-Liste abgeschlossen ist.

Das mit dem Others ist mir bekannt.
Ich wollte nur wissen, ob es überhaupt möglich ist ein von einem anderen 
Generic abhängigen Generic zu erzeugen.

Ich hoffe, dass meine Frage nun verständlich ist.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Martin R. schrieb:
> Mein Compiler meckert nun wenn ich obenstehenden Code compilieren
> möchte
Ja, was meckert der denn?
Die Xilinx Synthese sagt:
1
Constraint expression for 'Top' is not valid in this context as it 
2
contains reference(s) to other interface objects 
3
(VHDL IEEE 1076-2000 LRM 4.3.2.1)
Also das Kapitel 4.3.2.1 im 
http://www.scribd.com/doc/7206001/Ieee-2004-Vhdl-Ref-Manual aufgemacht. 
Und dort steht:
1
A name that denotes an interface object must not appear in any interface 
2
declaration within the interface list containing the denoted interface 
3
object except to declare this object.
4
5
NOTE
6
The restriction mentioned in the previous sentence makes the 
7
following three interface lists illegal:
8
entity E is
9
  generic  (G1: INTEGER; G2: INTEGER := G1);    -- Illegal
10
  port     (P1: STRING;  P2: STRING(P1'RANGE)); -- Illegal
11
  procedure X (Y1, Y2: INTEGER; Y3: INTEGER range Y1 to Y2); -- Illegal
12
end E;
13
14
However, the following interface lists are legal:
15
entity E is 
16
  generic (G1, G2, G3, G4: INTEGER);
17
  port    (P1, P2: STRING (G1 to G2));
18
  procedure X (Y3: INTEGER range G3 to G4);
19
end E

Martin R. schrieb:
> Ist es überhaupt möglich das so zu machen wie in dem Generic oder kann
> ich mein Vorhaben nur über Konstanten erreichen?
Du könntest es so machen:
1
generic(
2
  gSPI_Breite        :  integer      :=8;    -- Variable zur Anpassung der Laenge der empfangenen Daten
3
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
4
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
5
  gAusgang_Resetzustand  :  std_logic_vector := X"00000"; -- Variable zur Anpassung des Resetzustandes
6
  :
Aber dabei mußt du auf die Bitreihenfolge aufpassen, denn ein 
unconstrained std_logic_vector zählt die Bits von links nach rechts.
Da könnte eine Indizierung wie z.B. gAusgang_Resetzustand(3) in die Hose 
gehen... :-/

Du könntest es aber auch so machen (du willst ja sowieso eine 
Konstante):
1
generic(
2
  gSPI_Breite        :  integer      :=8;   -- Variable zur Anpassung der Laenge der empfangenen Daten
3
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
4
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
5
  : 
6
  :
7
 );
8
 :
9
10
constant gAusgang_Resetzustand  :  std_logic_vector (gAnzahl_O - 1 downto 0) := (others=>'0');

BTW:
>  -- Variable zur Anpassung der Laenge der empfangenen Daten
>  :
>  -- Variable zur Anpassung des Resetzustandes
Diese Kommentare sind ja wohl MAXIMAL missglückt.
An diesen Werten soll ja gerade nichts variabel sein!
Die werden einmal definiert und fertig.


BTW2:
> Ich habe mehrere Generics
Wozu brauchst du so viele gleiche/ähnliche/unnötige Generics?
Ich glaube nicht, dass du deine Beschreibung tatsächlich sooooo 
generisch gestalten wirst, dass du an jeder dieser Schrauben beliebig 
drehen kannst...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Aber dabei mußt du auf die Bitreihenfolge aufpassen, denn ein
> unconstrained std_logic_vector zählt die Bits von links nach rechts.
Hier ein kleines Beispiel:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity top is
7
    Generic ( Breite : integer := 8;
8
              Top : std_logic_vector := x"84" -- = "10000100" Achtung: unconstrained vector --> range 0 to 7 !!!!
9
              );
10
    Port ( clk : in  STD_LOGIC;
11
           led : out  STD_LOGIC;
12
           x : out  STD_LOGIC
13
           );
14
end top;
15
16
architecture Behavioral of top is
17
signal counter : std_logic_vector (Breite-1 downto 0) := Top;
18
begin
19
   process (clk) begin
20
      if rising_edge(clk) then
21
         -- der Vergleich hier geht gut, weil einfach die Bits von links nach rechts miteinander verglichen werden
22
         -- also counter(7) mit Top(0), counter (6) mit Top(1) usw...
23
         if (counter = Top) then
24
            counter <= (others=>'0');
25
         else
26
            counter <= counter+1;
27
         end if;
28
      end if;
29
   end process;   
30
   led <= counter(counter'left);
31
32
   -- das x hier ist überraschenderweise '1',  weil Top'range = 0 to 7
33
   x <= Top(0);   
34
 
35
end Behavioral;

Und dazu die RTL-Schematic im Anhang.
Man sieht: x wird hart auf Vcc verdrahtet.

Und ganz lustig wird es, wenn da ein paar Bits zuviel angegeben werden. 
Was passiert basierend auf dem obigen Code z.B. hier:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity top is
7
    Generic ( Breite : integer := 8;
8
              Top : std_logic_vector := x"084" -- = "000010000100" Achtung: unconstrained vector --> range 0 to 11 !!!!
9
              );
10
:
11
: -- Rest bleibt gleich

Oder hier:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity top is
7
    Generic ( Breite : integer := 6;
8
              Top : std_logic_vector := x"84" -- = "10000100" Achtung: unconstrained vector --> range 0 to 7 !!!!
9
              );
10
:
11
: -- Rest bleibt gleich


BTW:
Ich würde hier allerdings üblicherweise statt dem std_logic_vector den 
Datentyp unsigned zum Rechnen verwenden...

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.