Variabler Index in einen Vektor?

#2811416
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
(Firma: abaxor engineering) #2811430
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
#2811475
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
#2811496
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.
#2811535
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
Persönliche Seite #2811557
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.
#2811592
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
Persönliche Seite #2811620
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).
#2811655
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
Moderator (Firma: Titel) Persönliche Seite #2811837
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"

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren