www.mikrocontroller.net

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


Autor: Martin R. (herki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Miteinander

Ich habe mehrere Generics
generic(
  gSPI_Breite        :  integer      :=8;    -- Variable zur Anpassung der Laenge der empfangenen Daten
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
  gAusgang_Resetzustand  :  std_logic_vector (gAnzahl_O - 1 downto 0) := X"00000"; -- Variable zur Anpassung des Resetzustandes
  gBefehlsbreite      :  integer      :=3;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes mit der Befehlsnummer
  gTelegramm_1_InfoBreite  :  integer      :=1;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Telegrammnummer
  gTelegramm_2_InfoBreite  :  integer      :=1;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Telegrammnummer
  gRX_Adressbreite    :  integer      :=7;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Adresse
  gRX_Befehlsbreite    :  integer      :=3;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für den Befehl
  gRX_Nutzdatenbreite    :  integer      :=4;    -- Variable zur Anpassung der Breite des zu übertragenden Datenfeldes für die Nutzdatenbreite
  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)
  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)
  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)
  );

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

Autor: Ulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe Deine Frage nicht verstanden

Autor: Björn Cassens (bjoernc) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
prc:PROCESS ( clk ) IS 
BEGIN
 IF clk'event AND ... THEN
   IF reset = '1' THEN
    regist_vector <= ( OTHERS => '0' );
  ELSE
   ...
  END IF;
 END IF;
END PROCESS;

Ich hoffe ich habe deine Frage richtig interpretiert.

Autor: Martin R. (herki)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin R. schrieb:
> Mein Compiler meckert nun wenn ich obenstehenden Code compilieren
> möchte
Ja, was meckert der denn?
Die Xilinx Synthese sagt:
Constraint expression for 'Top' is not valid in this context as it 
contains reference(s) to other interface objects 
(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:
A name that denotes an interface object must not appear in any interface 
declaration within the interface list containing the denoted interface 
object except to declare this object.

NOTE
The restriction mentioned in the previous sentence makes the 
following three interface lists illegal:
entity E is
  generic  (G1: INTEGER; G2: INTEGER := G1);    -- Illegal
  port     (P1: STRING;  P2: STRING(P1'RANGE)); -- Illegal
  procedure X (Y1, Y2: INTEGER; Y3: INTEGER range Y1 to Y2); -- Illegal
end E;

However, the following interface lists are legal:
entity E is 
  generic (G1, G2, G3, G4: INTEGER);
  port    (P1, P2: STRING (G1 to G2));
  procedure X (Y3: INTEGER range G3 to G4);
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:
generic(
  gSPI_Breite        :  integer      :=8;    -- Variable zur Anpassung der Laenge der empfangenen Daten
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
  gAusgang_Resetzustand  :  std_logic_vector := X"00000"; -- Variable zur Anpassung des Resetzustandes
  :
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):
generic(
  gSPI_Breite        :  integer      :=8;   -- Variable zur Anpassung der Laenge der empfangenen Daten
  gAnzahl_I        :  integer      :=25;    -- Variable zur Anpassung der I
  gAnzahl_O        :  integer      :=20;    -- Variable zur Anpassung der O
  : 
  :
 );
 :

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...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity top is
    Generic ( Breite : integer := 8;
              Top : std_logic_vector := x"84" -- = "10000100" Achtung: unconstrained vector --> range 0 to 7 !!!!
              );
    Port ( clk : in  STD_LOGIC;
           led : out  STD_LOGIC;
           x : out  STD_LOGIC
           );
end top;

architecture Behavioral of top is
signal counter : std_logic_vector (Breite-1 downto 0) := Top;
begin
   process (clk) begin
      if rising_edge(clk) then
         -- der Vergleich hier geht gut, weil einfach die Bits von links nach rechts miteinander verglichen werden
         -- also counter(7) mit Top(0), counter (6) mit Top(1) usw...
         if (counter = Top) then
            counter <= (others=>'0');
         else
            counter <= counter+1;
         end if;
      end if;
   end process;   
   led <= counter(counter'left);

   -- das x hier ist überraschenderweise '1',  weil Top'range = 0 to 7
   x <= Top(0);   
 
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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity top is
    Generic ( Breite : integer := 8;
              Top : std_logic_vector := x"084" -- = "000010000100" Achtung: unconstrained vector --> range 0 to 11 !!!!
              );
:
: -- Rest bleibt gleich

Oder hier:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity top is
    Generic ( Breite : integer := 6;
              Top : std_logic_vector := x"84" -- = "10000100" Achtung: unconstrained vector --> range 0 to 7 !!!!
              );
:
: -- Rest bleibt gleich


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

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.