Forum: FPGA, VHDL & Co. received Vektor als Status Vektor füllen


von Ralf (Gast)


Lesenswert?

Hallo zusammen,

ich habe gerade eine Denkblockade und hoffe sie mit Eurer Hilfe lösen zu 
können.

Ich bekomme Daten auf 16bit in einem bestimmten Adressraum gesendet. 
Dazu habe ich einen WR_VALID Puls.

Diesen Daten haben immer auf der Startadresse ein Statuspaket, auf den 
folgenden 0 bis 63 Adressen Datenpakete und dann noch ein weiteres 
Statuspaket.
Im ersten Statuspaket ist eine Information enthalten, wieviele 
Datenwörter gesendet werden, also auch auf welcher Adresse das letzte 
Statuspaket liegt.

Die Daten kommen in der korrekten Reihenfolge, also Status1 - Daten- 
Stauts2.

Nun muss ich eine Art "received vector" füllen, also welche Adresse bzw. 
welche Daten ich schon erhalten habe.
Der Vektor hat also 1+64+1 Bit, damit auch die maximal mögliche Anzahl 
an Datenpaketen erfasst werden kann.

Leider habe ich noch keine Möglichkeit gefunden, und genau da liegt 
meine Denkblockade, diese Vektorbits abhängig von einem Signal zu 
setzen. Signale dürfen nicht als Index eines anderen Vektors verwendet 
werden. Es sind nur konstante integer als RANGE zugelassen.

Sonst hätte ich wohl sowas gemacht (Syntax vielleicht nicht 100% 
korrekt, geht ja eh nicht!):
1
IF WR_VALID = '1' AND WR_ADDR = Startadresse THEN
2
  s_received(0) <= '1';
3
  s_status1_rec <= '1';
4
  s_data_length <= WR_DATA(5 DOWNTO 0);
5
END IF;
6
7
IF s_status1_rec = '1' AND WR_VALID = '1' AND WR_ADDR > startadresse AND WR_ADDR < startadresse + to_integer(unsigned(s_data_length + 1)) THEN
8
  s_received(WR_ADDR-startadresse) <= '1'; -- HIER liegt das Problem!
9
END IF;

Wenn die s_data_length immer konstant wäre, könnte ich eine case 
Anweisung mit 66 Zeilen schreiben und wäre fertig, nur leider ist es 
nicht konstant.

Hat jemand eine Idee, wie ich das Problem lösen könnte?

Vielen Dank!
Ralf :)

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


Lesenswert?

Ralf schrieb:
> Signale dürfen nicht als Index eines anderen Vektors verwendet werden.
Warum nicht? Ein jeder Multiplexer funktioniert so.

Dein Problem liegt woanders. Kann es sein, dass du da eine for-Schleife 
im Einsatz hast?

> Es sind nur konstante integer als RANGE zugelassen.
Wo taucht in dem Beispielcode ein Range auf?

> Hat jemand eine Idee, wie ich das Problem lösen könnte?
Ehrlich gesagt: ich werde aus deiner Beschreibung nicht ganz schlau. Da 
sind so viele "hausinterne" und "umgedeutete" Begriffe drin...

von Ralf (Gast)


Lesenswert?

Hallo Lothar,

Lothar Miller schrieb:
> Warum nicht? Ein jeder Multiplexer funktioniert so.
1
signal2 <= signal1;
2
signal3 <= input(signal2 downto 0);

So etwas meinte ich mit "Signale dürfen nicht als Index eines anderen 
Vektors verwendet werden". Also eine ähnliche Problemstellung wie in 
meinem Bespiel im ersten post.

Lothar Miller schrieb:
> Kann es sein, dass du da eine for-Schleife im Einsatz hast?

Bisher nicht... an eine for-Schleife hatte ich auch gedacht, aber leider 
ist mir noch nicht der passende Gedanke gekommen, wie mir diese helfen 
könnte. Zumindest nicht, ohne die Frage aus meinem ersten Post zu 
beantworten.

Lothar Miller schrieb:
> Wo taucht in dem Beispielcode ein Range auf?

Gar nicht. RANGE war nicht als VHDL Schlüsselwort gemeint, sondern eher 
als Wort um ein (x downto y) zu beschreiben. Sorry für die Verwirrung! 
:)

Die eigentliche Frage lautet:
Wie kann ich den Index von s_received abhängig von WR_ADDR und 
startadresse auswählen?
WR_ADDR und startadresse bestimmen also den ausgewählten Index.
Aber die Zuweisung
1
s_received(index) <= '1';
klappt meiner Ansicht nach nur, wenn der index sich nicht verändern 
kann, also quasi nur eine Konstante und kein Signal ist.

Habe ich an der Stelle noch einen Denkfehler?

Vielen Dank!
Ralf

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


Lesenswert?

Ralf schrieb:
> So etwas meinte ich mit "Signale dürfen nicht als Index eines anderen
> Vektors verwendet werden".
Wenn das "Signal" ein "Integer" ist, dann darf es das sehr wohl. Wenn 
das "Signal" ein "Vektor" ist (std_logic_vector oder unsigned/singend) 
dann nicht.
Du musst unbedingt die strengen Typkonvetionen von VHDL beachten, 
sonst landest du laufend auf der Nase.

> Gar nicht. RANGE war nicht als VHDL Schlüsselwort gemeint, sondern eher
> als Wort um ein (x downto y) zu beschreiben. Sorry für die Verwirrung!
Du darfst nicht reservierte Schlüsselwörter in deine Beschreibung 
einfließen lassen, ohne für unnötige Verwirrung zu sorgen.

> Aber die Zuweisungs_received(index) <= '1';
> klappt meiner Ansicht nach nur, wenn der index sich nicht verändern
> kann, also quasi nur eine Konstante und kein Signal ist.
Deine Sicht ist falsch. Das ist ein stinknormaler Multiplexer. Sowas 
wird weltweit zigmilliardenfach erfolgreich verwendet.

> Wie kann ich den Index von s_received abhängig von WR_ADDR und
> startadresse auswählen?
> WR_ADDR und startadresse bestimmen also den ausgewählten Index.
Du konvertierst/castest die Adressen vom Std_logic_vector-Signalen in 
Integer-Signale, addierst die zusammen und verwendest sie als Index für 
das Array...

: Bearbeitet durch Moderator
von VHDL hotline (Gast)


Lesenswert?

Du willst doch aber gar nicht per downto zuweisen, sondern immer nur ein 
Bit? Sowas sollte doch gehen
1
signal rx_vector : std_logic_vector(65 downto 0);
2
signal ct        : integer range 0 to 65;
3
...
4
5
rx_vector(ct) <= '1';
6
ct            <= ct + 1;

Man kann deinen Vektor auch über ein Schieberegister realisieren:
1
rx_vector(65 downto 0) <= rx_vector(64 downto 1) & '1';

von VHDL hotline (Gast)


Lesenswert?

Korrektur:
1
rx_vector(65 downto 0) <= rx_vector(64 downto 0) & '1';

von Ralf (Gast)


Lesenswert?

Hallo,

Lothar Miller schrieb:
> Du konvertierst/castest die Adressen vom Std_logic_vector-Signalen in
> Integer-Signale, addierst die zusammen und verwendest sie als Index für
> das Array...

Dann war ich wohl bisher auf dem Holzweg.
Ich hatte schon einmal eine ähnliche Fragestellung und bin dann über die 
Signale als Index gestolpert. Da hatte ich aber nicht nach integer 
gecastet/konvertiert. Das war wohl mein Fehler... Daraufhin hatte ich 
für mich abgespeichert, dass es so nicht geht... wieder was gelernt!

VHDL hotline schrieb im Beitrag #3963235:
> Man kann deinen Vektor auch über ein Schieberegister realisieren:

Vielen Dank!

Ich werde die Variante mit den integer mal testen. Ich bin echt 
gespannt, denn damit stellt sich mein Weltbild für den Index etwas auf 
den Kopf.

Vielen Dank!
Ralf

von peter (Gast)


Lesenswert?

Warum werden nicht diese vorgaben benutzt:
sll...srl...rol...ror...

signal wert_sll: unsigned(7 downto 0);
signal wert_srl: unsigned(7 downto 0);
signal wert_rol: unsigned(7 downto 0);
signal wert_ror: unsigned(7 downto 0);

wert_sll_u  <= wert_sll_u sll 2;
wert_srl_u  <= wert_srl_u srl 3;
wert_rol_u  <= wert_rol_u rol 3;
wert_ror_u  <= wert_ror_u ror 5;

-------------------------------------------------------

Und wenn man einen veränderten Wert nimmt, kann man es auch so 
hinstellen:

signal wert_u: unsigned(7 downto 0);
signal counter_u: unsigned(7 downto 0);

wertu  <= wert8u sll to_integer(counter_u(7 downto 0));

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


Lesenswert?

peter schrieb:
> wertu  <= wert8u sll to_integer(counter_u(7 downto 0));
Das ist aber schon etwas grundlegend anderes als das Ändern 
einzelner Bits.

So wie ich das sehe, soll hier eine "Anwesenheitsliste" geführt werden: 
wenn das Datenpaket vom Typ 33 gekommen ist, dann soll das Bit 33 
gesetzt werden. Wenn gleich danach das Datenpaket vom Typ 17 kommt, dann 
wird Bit 17 gesetzt...

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

counter_u

da drin befindet sich die Anwesenheitsliste.

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


Lesenswert?

peter schrieb:
> counter_u
> da drin befindet sich die Anwesenheitsliste.
Das kann gar keine Liste sein, sondern nur eine einzelne Nummer. So 
wird der Wert ja auch interpretiert...

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.