Forum: FPGA, VHDL & Co. Erzeugen mehrerer Instanzen mit Generate; so richtig?


von noips (Gast)


Lesenswert?

Hallo,

habe mich etwas mit Generate-Statement beschäftigt und habe eine Frage. 
Wie im Code zu sehen, sollen 3 Instanzen von spi erzeugt werden. So 
sollte es ja gehen, nur mir gefällt nicht, dass die Signale, die 
eignetlich zu unterschiedlichen voneinander unabhängigen Instanzen 
gehören (z.B. MOSI_v(x)) in einem Vektor zusammengefasst werden. 
Gewöhnlich gehören alle Signale eines Vektors zu einer Einheit. Macht 
man das dann doch so wie gezeigt, oder gibt es eine andere Möglichkeit?

Danke!

1
component spi
2
  port (
3
      SS    : out std_logic;
4
      SCLK  : out std_logic;
5
      MOSI  : out std_logic;
6
      MISO  : in  std_logic);
7
end component;
8
9
signal SS_v   : std_logic_vector(1 to 3);
10
signal SCLK_v : std_logic_vector(1 to 3);
11
signal MOSI_v : std_logic_vector(1 to 3);
12
signal MISO_v : std_logic_vector(1 to 3);
13
14
for I in 1 to 3 generate
15
16
  spi_I : spi
17
    port map ( SS_v(I),
18
               SCLK_v(I),
19
               MOSI_v(I),
20
               MISO_v(I));
21
end generate;

von D. I. (Gast)


Lesenswert?

vollkommen in Ordnung so imo

von Duke Scarring (Gast)


Lesenswert?

noips schrieb:
> oder gibt es eine andere Möglichkeit?

Ja. records in Verbindung mit arrays :
1
type spi_out_t is
2
record
3
      SS    : std_logic;
4
      SCLK  : std_logic;
5
      MOSI  : std_logic;
6
end record;
7
8
type spi_in_t is
9
record
10
      MISO  : std_logic;
11
end record;
12
13
type spi_out_array_t is array(natural range<>) of spi_out_t;
14
type spi_in_array_t  is array(natural range<>) of spi_in_t;
15
16
component spi
17
  port (
18
      spi_in  : in  spi_in_t;
19
      spi_out : out spi_in_t);
20
end component;
21
22
23
signal spi_out_array : spi_out_array_t(1 to 3);
24
signal spi_in_array  : spi_in_array_t(1 to 3);
25
26
for I in 1 to 3 generate
27
  spi_I : spi
28
    port map ( spi_in_array(I),
29
               spi_out_array(I));
30
end generate;

Duke

von noips (Gast)


Lesenswert?

Und warum ist das sinnvoll? Ist es nicht noch unnötig komlizierter? Wen 
ich jetzt z.B. MOSI vom spi_3 ansprechen will, dann schreibe ich in 
diesem Fall spi_out_array(3).MOSI oder? Dagegen ist MOSI_v(3) einfacher? 
Vor allem noch ein record für MISO als einziges Signal???

von Andreas D. (Gast)


Lesenswert?

Du kannst natürlich genauso auch schreiben:
1
component spi
2
   port (
3
      SS    : out std_logic;
4
      SCLK  : out std_logic;
5
      MOSI  : out std_logic;
6
      MISO  : in  std_logic
7
   );
8
end component;
9
10
signal XXX_SS_v   : std_logic;
11
signal XXX_SCLK_v : std_logic;
12
signal XXX_MOSI_v : std_logic;
13
signal XXX_MISO_v : std_logic;
14
15
signal YYY_SS_v   : std_logic;
16
signal YYY_SCLK_v : std_logic;
17
signal YYY_MOSI_v : std_logic;
18
signal YYY_MISO_v : std_logic;
19
20
signal ZZZ_SS_v   : std_logic;
21
signal ZZZ_SCLK_v : std_logic;
22
signal ZZZ_MOSI_v : std_logic;
23
signal ZZZ_MISO_v : std_logic;
24
25
spi_XXX_I : spi
26
   port map ( 
27
      XXX_SS_v,
28
      XXX_SCLK_v,
29
      XXX_MOSI_v,
30
      XXX_MISO_v
31
   );
32
   
33
spi_XXX_I : spi
34
   port map ( 
35
      YYY_SS_v,
36
      YYY_SCLK_v,
37
      YYY_MOSI_v,
38
      YYY_MISO_v
39
   );
40
   
41
spi_XXX_I : spi
42
   port map ( 
43
      ZZZ_SS_v,
44
      ZZZ_SCLK_v,
45
      ZZZ_MOSI_v,
46
      ZZZ_MISO_v
47
   );

Wenn du die Signale getrennt haben willst.

Ist halt bisschen mehr Text. Kann aber manchmal sogar übersichtlicher 
sein, je nachdem was du mit den Signalen noch so vor hast.

von Duke Scarring (Gast)


Lesenswert?

Ich sortiere mal die Fragen etwas um:
noips schrieb:
> Wen ich jetzt z.B. MOSI vom spi_3 ansprechen will, dann schreibe ich in
> diesem Fall spi_out_array(3).MOSI oder?
Richtig.

> Dagegen ist MOSI_v(3) einfacher?
In diesem Fall vielleicht.

Aber was machst Du, wenn Du Deinen verschiedenen SPI-Schnittstellen 
echte Namen statt Nummern geben willst?
1
signal adc_spi_out  : spi_out_t;
2
signal dac_spi_out  : spi_out_t;
3
signal gain_spi_out : spi_out_t;

> Vor allem noch ein record für MISO als einziges Signal???
> Und warum ist das sinnvoll? Ist es nicht noch unnötig komlizierter?
In diesem Beispiel mit den SPI-Schnittstellen ist der Vorteil nicht so 
leicht zu sehen.

Ich bevorzuge diese Schreibweise u.a. weil:

- Bei Erweiterungen einer Portliste muß ich nicht mehr jede Entity 
anfassen, durch die das Signal geht, sondern nur noch die 
Typendefinition.
Die Typen stehen in einem gemeinsamen Package.

- Bei mir gibt es zu jedem Typ noch eine default-Konstante ala:
1
 constant default_spi_out_c : spi_out_t :=
2
      SS    => '0',
3
      SCLK  => '0',
4
      MOSI  => '0');
Ich habe dadurch nie Probleme mit nicht initialisierten Signalen, da bei 
der Initialisierung oder im Reset-Pfad grundsätzlich die 
default-Konstante zugewiesen wird. Der Compiler gibt Fehlermeldungen, 
wenn Typ und Konstantendefinition nicht zusammenpassen.

- records lassen sich wunderbar schachteln, dadurch lassen sich 
komplexe Signale sehr gut abbilden.

- Bei Signalen einer Entity verwende ich Instanzname_Portname als 
Namensschema. So sehe ich sofort wer das Signal treibt. (Da spart ein 
Editor mit Textvervollständigung viel Tippserei.)

- records funktioniert sehr gut im Zusammenhang mit der 
2-Prozess-Methode [1].

Etwas gewöhnungsbedürftig ist die Trennung mit dem _in und dem _out Typ. 
Das ist der Tatsache geschuldet, das die Richtung eines Signals am Port 
festgelegt wird und nicht im record.


Duke

[1] http://www.gaisler.com/doc/vhdl2proc.pdf

von noips (Gast)


Lesenswert?

@ Andreas D.

so habe ich bis jezt auch gemacht, aber wenn die Anzahl der Instanzen so 
bei 6 und mehr liegt, da will ich nicht unbedingt alles tippen bzw. 
kompieren-einfügen-anpassen. Außerdem wenn die Anzahl der Instanzen 
variabel sein soll, dann wird auch sehr unbequem.

@ Duke

OK! Danke für die ausführliche Erklärung!

von Andreas D. (Gast)


Lesenswert?

@noips

Klar bei 6 Instanzen ergibt das natürlich keinen Sinn mehr.

von berndl (Gast)


Lesenswert?

Duke Scarring schrieb:
> Aber was machst Du, wenn Du Deinen verschiedenen SPI-Schnittstellen
> echte Namen statt Nummern geben willst?

vielleicht mit ALIAS? Dann hast du beides...

von T. M. (xgcfx)


Lesenswert?

Duke Scarring schrieb:
> - Bei Erweiterungen einer Portliste muß ich nicht mehr jede Entity
> anfassen, durch die das Signal geht, sondern nur noch die
> Typendefinition.

Naja, das ist prinzipiell richtig, nur sind die Entities dann auch nur 
in dem speziellen Design verwendbar, in der das Package existiert. Und 
man kann an dem Port nicht mehr direkt erkennen, aus was er eigentlich 
besteht. Ich beschränke mich bei Ports deshalb immer auf 
std_logic(_vector). Lässt sich IMHO auch besser lesen.

> - records lassen sich wunderbar schachteln, dadurch lassen sich
> komplexe Signale sehr gut abbilden.

Gehen tut das schon, wird aber auch sehr komplex und dadurch für 
denjenigen, der den Code nicht selber geschrieben hat, ziemlich 
undurchschaubar.

> - Bei Signalen einer Entity verwende ich Instanzname_Portname als
> Namensschema. So sehe ich sofort wer das Signal treibt. (Da spart ein
> Editor mit Textvervollständigung viel Tippserei.)

Mit den Signalnamen halte ich es genauso :-)

> - records funktioniert sehr gut im Zusammenhang mit der
> 2-Prozess-Methode [1].

Naja, davon kann man halten was man will, ich mache bei einfachen 
Designs oft nur synchrone Processe und eine Handvoll nebenläufige 
kombinatorische Anweisungen.

von Vanilla (Gast)


Lesenswert?

Hallo @all

Solange Ihr reine VHDL Hirarchien habt spricht nichts gegen records, 
allerdings hoert das dann schnell auf, wenn Ihr mit VHDL/verilog 
Gemischen arbeiten (muesst)...

Gruss

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.