Forum: FPGA, VHDL & Co. Variabler Index in einen Vektor?


von Michael F. (mifi)


Lesenswert?

Hallo,

auf einzelne Elemente eines Vektors kann man wie folgt zugreifen:
1
signal data    : std_logic_vector(15 downto 0);
2
signal element : std_logic;
3
4
element <= data(7);

Wie kann ich aber auf ein Element zugreifen wenn der Index variable ist?
1
signal data        : std_logic_vector(15 downto 0);
2
signal data16      : std_logic_vector(15 downto 0);
3
signal element     : std_logic;
4
signal bit_cnt_max : integer range 0 to 16;
5
6
element <= data(bit_cnt_max); -- OK
7
8
data16 <= data(bit_cnt_max-1 downto 0); -- Error

Auf ein einzelnes Element kann man zugreifen, aber wie geht es bei einem 
Bereich? bit_cnt_max wird zur Laufzeit verändert.

Hier bekommen ich folgende Fehlermeldung:
1
left bound of range must be a constant

Ich versuche gerade bei dem SPI Beispiel von Lothar die Breite zur
Laufzeit zu konfigurieren.

Viele Grüße,
Michael

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Michael Fischer schrieb:
> Wie kann ich aber auf ein Element zugreifen wenn der Index variable ist?
> signal data        : std_logic_vector(15 downto 0);
> signal data16      : std_logic_vector(15 downto 0);
> signal element     : std_logic;
> signal bit_cnt_max : integer range 0 to 16;
>
> element <= data(bit_cnt_max); -- OK
>
> data16 <= data(bit_cnt_max-1 downto 0); -- Error

So könnte es gehen
data16 (bit_cnt_max-1 downto 0) <= data (bit_cnt_max-1 downto 0);

Aber was willst du damit erreichen, du sparst damit keine Logik. 
Grundsätzlich bleiben aber alle Bits von data16 erhalten.

Tom

von Michael F. (mifi)


Lesenswert?

Hallo Tom,

>Aber was willst du damit erreichen, du sparst damit keine Logik.
Das Beispiel ist vielleicht nicht wirklich aussagekräftig.

Ich möchte die Breite eines SPI-Busses zur Laufzeit von der
CPU einstellen. Die maximale Breite beträgt 16Bit.
1
   signal tx_data     : std_logic_vector(15 downto 0) := (others => '0');

Die Breite kann ich dann über das Register bit_cnt_max verändern:
1
   signal bit_cnt_max : integer range 0 to 16 := 0;

Wenn ich nun das höchste Bit ausgeben möchte:
1
   MOSI <= tx_data(bit_cnt_max-2 downto 0) & MISO;

Bei einer Breite von 16 Bit sollte sich folgendes ergeben:
1
   MOSI <= tx_data(14 downto 0) & MISO;

Und bei einer Breite von 8 Bit:
1
   MOSI <= tx_data(6 downto 0) & MISO;

Man könnte hier natürlich auch ein "if" verwenden. Aber was macht man
wenn die Breite im Bereich von 1 bis 16 verstellbar sein soll?

Eine Alternative wäre z.B. die Daten linksbündig in tx_data
abzulegen. Aber das wollte ich vermeiden.

Gruß,
Michael

von Josef G. (bome) Benutzerseite


Lesenswert?

Ich würde mir zuerst überlegen, wie die fertige Hardware
aussehen soll, und erst danach, wie man diese Hardware
in VHDL beschreiben kann.

von Daniel M. (daniel__m)


Lesenswert?

Wieso ist das MOSI-Signal ein Vector? Das soll doch bestimmt der 
Output-Pin sein.

Das Interface zur CPU wird wahrscheinlich 16bit bleiben, nur werden die 
Daten "rechtsbündig" in das MOSI-Register eingetragen. Beim Senden 
werden diese ja rausgeshiftet und gleichzeitig die MISO-Daten 
eingeshiftet.

mein Vorschlag:
1
tx_data <= tx_data(14 downto 0) & MISO;
2
MOSI    <= tx_data(bit_cnt_max);

Es wird das komplette Sende-Register geschoben, aber je nach Busbreite 
an einer anderen Stelle zum Ausgeben abgegriffen.

von Michael F. (mifi)


Lesenswert?

Hallo,

@Josef,
>Ich würde mir zuerst überlegen, wie die fertige Hardware
>aussehen soll, und erst danach, wie man diese Hardware
>in VHDL beschreiben kann.
Es sollen maximal 16 Bit als Breite möglich sein. D.h. das
Schieberegister muss eine max. Breite von 16 Bit haben.
Gleichzeitig soll die Breite aber auch variable sein.

Deine Anmerkung finde ich nicht gerade hilfreich, aber Danke
für den Kommentar. Vielleicht kannst Du aber auch erklären
wo der Fehler in meiner Vorgehensweise ist?

@Daniel,
>Wieso ist das MOSI-Signal ein Vector? Das soll doch bestimmt der
>Output-Pin sein.
Ja war ein Fehler auf die Schnelle. Dein Vorschlag scheint die
Lösung zu sein. Da hat man mal wieder den Wald vor lauter Bäumen
nicht gesehen.

Danke,
Michael

von Josef G. (bome) Benutzerseite


Lesenswert?

Michael Fischer schrieb:
> Deine Anmerkung finde ich nicht gerade hilfreich, aber Danke
> für den Kommentar. Vielleicht kannst Du aber auch erklären
> wo der Fehler in meiner Vorgehensweise ist?

Sollte kein Kommentar sein, sondern ein ernst gemeinter
Vorschlag zur Vorgehensweise. Ich jedenfalls mache es so.
Es scheint ja auch hier so gewesen zu sein, dass das
Problem durch unklare Vorstellungen über die fertige
Hardware entstanden ist.

von Michael F. (mifi)


Lesenswert?

Hallo Josef,

>Es scheint ja auch hier so gewesen zu sein, dass das
>Problem durch unklare Vorstellungen über die fertige
>Hardware entstanden ist.
Vielleicht können wir das mal genau klären? Dann hilft
dies auch anderen Anwendern bei der Vorgehensweise.

Ich muss zugeben das ich hier nicht in FlipFlops oder
Gattern gedacht habe, sondern ich bin von einem Schieberegister
ausgegangen mit eben den folgenden Eigenschaften:

"Es sollen maximal 16 Bit als Breite möglich sein. D.h. das
Schieberegister muss eine max. Breite von 16 Bit haben.
Gleichzeitig soll die Breite aber auch variable sein."

Da das MSB als erstes Bit rausgeschoben werden soll habe ich erkannt
das es hier Probleme gibt wenn das Datum eine kleinere Breite hat
als 16 Bit und rechtsbündig in tx_data geschrieben wird.

Darum war meine erste Idee nur so viele Bits zu schieben wie
auch die eingestellte Bitbreite ist/war. Dies war aber ein
Denkfehler.

Wie hätte man jetzt Deiner Meinung nach die Aufgabe
lösen sollen?

Viele Grüße,
Michael

von Josef G. (bome) Benutzerseite


Lesenswert?

Vorab eine Frage: Ist das Problem durch den Vorschlag von
Daniel M. bereits gelöst, so dass es nur noch ums Prinzip gehen
soll, oder soll wirklich noch eine Lösung gefunden werden?

von Josef G. (bome) Benutzerseite


Lesenswert?

Michael Fischer schrieb:
> "Es sollen maximal 16 Bit als Breite möglich sein. D.h. das
> Schieberegister muss eine max. Breite von 16 Bit haben.
> Gleichzeitig soll die Breite aber auch variable sein."

Das ist keine Beschreibung einer fertigen Hardware, sondern ein
Soll-Verhalten einer Hardware, die erst noch gefunden werden muß.

Die fertige Hardware besteht aus einem 16 Bit breiten Schieberegister
und einem Multiplexer, welcher die 16 Bit als Dateneingänge und
vier Adresseingänge hat.

Daniel M. schrieb:
> Das Interface zur CPU wird wahrscheinlich 16bit bleiben, nur werden die
> Daten "rechtsbündig" in das MOSI-Register eingetragen. Beim Senden
> werden diese ja rausgeshiftet und gleichzeitig die MISO-Daten
> eingeshiftet.
>
> mein Vorschlag:
> tx_data <= tx_data(14 downto 0) & MISO;
> MOSI    <= tx_data(bit_cnt_max);
>
> Es wird das komplette Sende-Register geschoben, aber je nach Busbreite
> an einer anderen Stelle zum Ausgeben abgegriffen.

Daniel M. ist genau so vorgegangen, dass er sich erst die
Hardware überlegt hat und danach die VHDL-Codierung
(Allerdings fehlt hier noch der Takt).

von Michael F. (mifi)


Lesenswert?

Hallo Josef,

>Vorab eine Frage: Ist das Problem durch den Vorschlag von
>Daniel M. bereits gelöst, so dass es nur noch ums Prinzip gehen
>soll, oder soll wirklich noch eine Lösung gefunden werden?
Das Problem ist gelöst, es ging hier nur noch um das Prinzip.

Gruß,
Michael

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


Lesenswert?

Michael Fischer schrieb:
> data16 <= data(bit_cnt_max-1 downto 0); -- Error
> Hier bekommen ich folgende Fehlermeldung:
> left bound of range must be a constant
Und das ist nur die Spitze des Eisbergs. Denn gleich darauf würdest du 
diese Meldung vorgesetzt bekommen: "Vektorbreiten passen nicht 
zusammen!", weil ja bit_cnt_max sehr wahrscheinlich auch mal kleiner als 
16 sein sollte...

Du könntest es durchaus mit zwei variablen Ranges probieren:
  data16(bit_cnt_max-1 downto 0) <= MSIO & data(bit_cnt_max-1 downto 1);
Mit dieser Schreibweise bist du allerdings ganz vorn dabei bei der 
Entwicklung des Synthesizers: Manche könnens, manche nicht...
Beitrag "Re: Signal initialisieren"

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.