Forum: FPGA, VHDL & Co. VHDL Komponente, mehrfach instanziieren aber unterschiedlich bedaten.


von berndl (Gast)


Lesenswert?

Hallo allerseits,
ich bin bzgl. VHDL und Ausnutzung der Features eher konservativ 
unterwegs, haette da aber jetzt gerne mal ein Problem :o)

Ich habe verschiedene SPI-Interfaces mit identischen Chips oder 
zumindest Protokoll-kompatiblen Chips, aber jeweils unterschiedlicher 
Topologie:
* 2x ChipSelect mit 4-Kanal+AUX ADC
* 2x ChipSelect mit 3-Kanal ADC
* 4x ChipSelect mit 8-Kanal ADC

Also, die SPI-Master-FSM ist eigentlich immer die gleiche, aber die 
Kommandosequenzen sind in den 3 Faellen halt unterschiedlich.

Dazu habe ich mir (anstatt eines Logikgrabes) eine LUT-basierte 
FSM-Steuerung gebaut, sieht z.B. fuer einen der Faelle so aus (so im 
Package definiert):
1
type t_lut_cmd is array (0 to 39) of std_logic_vector (4+8+4-1 downto 0);
2
constant c_lut_cmd1 : t_lut_cmd := (
3
  0 => x"0_C0_F",
4
  1 => x"0_C4_0",
5
  2 => x"0_C8_1",
6
  3 => x"0_C8_2",
7
  4 => x"1_C0_F",
8
  5 => x"1_C4_0",
9
  6 => x"1_C8_1",
10
  7 => x"1_C8_2",
11
  others => x"0_00_E"
12
);
13
constant c_lut_cmd2 ....
Es gibt also verschiedene Varianten dieser "lut_cmd" die im Package 
definiert sind, halt noch mehrere 'constant' Eintraege. In meiner FSM 
bzw. der zugehoerigen VHDL-Beschreibung muesste ich jetzt einfach nur 
noch zwischen den 2/3/4/5/... "constant"-Zuweisungen umschalten koennen 
und ich haette eine Logikbeschreibung, die aber durch die selektive 
Initialisierung personifiziert.
In der VHDL-Beschreibung wuerde ich jetzt abhaengig von einem Parameter 
oder sonstwas gerne einen der beiden folgenden Faelle deklarieren 
koennen:
1
signal lut_cmd : t_lut_cmd := c_lut_cmd1  -- erste Variante, oder
2
signal lut_cmd : t_lut_cmd := c_lut_cmd2  -- 2. Variante, usw...
Preisfrage: Wie kann ich das machen? Mit 'generics' denke ich nicht. 
Aber den Code einfach zu duplizieren und nur die Initialisierung aendern 
(1 Character!) kanns ja nicht sein... Jede Aenderung in Zukunft muesste 
ich dann in allen Varianten nachziehen...

von Gustl B. (-gb-)


Lesenswert?

1
generate_LUTs:
2
if $signal = True generate
3
signal lut_cmd : t_lut_cmd := c_lut_cmd1;
4
else generate
5
signal lut_cmd : t_lut_cmd := c_lut_cmd2;
6
end generate;

berndl schrieb:
> Mit 'generics' denke ich nicht.

Das würde auch gehen wenn du Generics z. B. als Index für ein Array 
verwendest.

signal lut_cmd : t_lut_cmd := LUTARRAY(Generic);

: Bearbeitet durch User
von berndl (Gast)


Lesenswert?

ui, das ging ja schnell, danke!

Was ist:
1
$signal
 und woher kommt das?
Ich moechte ja die Komponente mehrfach einbauen, halt jeweils mit 
verschiedenen Initialisierungen ueber die 'constant' im Package.

Danke schon mal!

von berndl (Gast)


Lesenswert?

... andersrum gefragt: Kann ich einen 'generic' beim Instanziieren 
nehmen und den bei der Deklaration von Signalen verwenden? Das waer ja 
geil!

von berndl (Gast)


Lesenswert?

Gustl B. schrieb:
...
>
> berndl schrieb:
>> Mit 'generics' denke ich nicht.
>
> Das würde auch gehen wenn du Generics z. B. als Index für ein Array
> verwendest.
>
> signal lut_cmd : t_lut_cmd := LUTARRAY(Generic);

Hab' drueber nachgedacht, geht so aber denke ich nicht. Weil: Da wuerde 
ich ja ein viel groesseres Array anlegen, also eigentlich wuerde ich 
"alle" Instanzen ins Array packen und halt per Offset den passenden 
Eintrag auswaehlen. Das waere aber eine gewaltige 
Resourcenverschwendung...
Mir geht's darum: Eine VHDL-Komponente, die eine LUT anzieht. Diese LUT 
soll je nach Komponenteninstanziierung unterschiedlich mit Default-Daten 
befuellt werden.
Uebrigens: Die LUT soll natuerlich spaeter zur Laufzeit auch noch 
veraenderbar/beschreibbar sein, bietet sich fuer Testzwecke geradezu an

von Gustl B. (gustl_b)


Lesenswert?

berndl schrieb:
> Was ist:
> $signal

Damit meinte ich ein beliebiges Signal. Das darfst du dir ausdenken.

berndl schrieb:
> Kann ich einen 'generic' beim Instanziieren nehmen und den bei der
> Deklaration von Signalen verwenden?

Wie meinst du das genau?

berndl schrieb:
> Das waere aber eine gewaltige Resourcenverschwendung

Wieso? Da wird doch immer nur ein Index ausgewählt und dessen Inhalt 
landet im FPGA, der Rest des Arrays nicht.

von berndl (Gast)


Lesenswert?

Gustl B. schrieb:
...
> berndl schrieb:
>> Kann ich einen 'generic' beim Instanziieren nehmen und den bei der
>> Deklaration von Signalen verwenden?
>
> Wie meinst du das genau?
...

Moin, was ich versuche ist folgendes:
1
architecture dings of bumms is
2
    signal lut_cmd ; t_lut_cmd := c_lut_cmd1;
3
...
4
begin
5
...
in Abhaengigkeit eines Parameters entweder mit 'c_lut_cmd1' oder 
'c_lut_cmd2' oder ... zu initialisieren.
Wenn ich das richtig sehe, dann kann ich in dem Teil der architecture 
(also dem Deklarationsteil vor dem begin) kein generate verwenden.

Dein Vorschlag mit dem Index koennte funktionieren, probiere ich mal 
aus. Evtl. ginge auch Initialisierung per function und mitgegebenem 
Parameter/Generic beim Aufruf...

von berndl (Gast)


Lesenswert?

so, mit der Initialisierung per function scheints zu tun:
1
entity hier_steht_ein_name is
2
generic (C_LUT_INIT : integer := 1);
3
port (
4
    ...
5
);
6
end;
7
8
architecture dings of bumms is
9
    function init_lut (num : integer) return t_lut_cmd is
10
    begin
11
        if num = 1 then
12
            return c_lut_cmd1;
13
        elsif num = 2 then
14
            return c_lut_cmd2;
15
        else
16
            return c_lut_cmd3;
17
        end if;
18
    end function;
19
20
    signal lut_cmd : t_lut_cmd := init_lut (C_LUT_INIT);
21
    ...
22
begin
Ist schoen uebersichtlich. Danke fuer die Denkanstoesse. Vielleicht kann 
ja jemand anderes auch was damit anfangen...

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.