Forum: FPGA, VHDL & Co. Zuweisung eines einzelnen slv-Elements funktioniert inklusive den cast-Anweisungen nicht


von Michi (Gast)


Lesenswert?

Hallo zusammen,

ich habe eine Frage an euch VHDL-Experten :-)

Der folgende Programmcode verhält sich mit Lattice Diamond synthetisiert 
(Synplify Pro) und aktivierter VHDL2008 Option anders als von mir 
erwartet und anders als in der Simulation mit ActiveHDL - meine 
Erwartung stimmt mit der Simulation überein. Dabei verwende ich die 
numeric Bibliothek.
Alles sind voll einsynchronisierte Signale, von daher sind 
Metastabilitäten kein Thema.


Folgender Programcode funktioniert NICHT wie gewünscht:
-------------------------------------------------------
1
SIGNAL channel        : std_logic_vector( 2 downto 0);
2
SIGNAL finishedVector : std_logic_vector(10 downto 0);
3
4
PROCESS (clk)
5
   IF (rising_edge(clk)) THEN
6
      ...
7
      IF (x = '1') THEN
8
         -- Event greift, Setzen des entsprechenden Bits im std_logic_vector
9
         finishedVector(to_integer(unsigned(channel & '1'))) <= '1';

In der Simulation macht der Code genau das was ich erwarte, auf dem 
realen Target wird dies nicht wie erwartet synthetisiert, was sich unter 
anderem auch in den Synplify-LOGs zeigt:
@N: CL189 :"channels.vhd":512:8:512:9|Register bit finishedVector(10) is 
always 0.
@N: CL189 :"channels.vhd":512:8:512:9|Register bit finishedVector(9) is 
always 0.
...
@N: CL189 :"channels.vhd":512:8:512:9|Register bit finishedVector(0) is 
always 0.



Ich verstehe nicht, was an der Zuweisung nicht passt bzw. warum die 
Synthese alle Bits des Vektors "finishedVector" fix auf 0 setzt.


Eine kleine Erweiterung und der Abfrage eines expliziten Bits inklusive 
zugehöriger Zuweisung bringt die Verbesserung.


Folgender Programcode funktioniert wie gewünscht (OK):
------------------------------------------------------
1
SIGNAL channel        : std_logic_vector( 3 downto 0);
2
SIGNAL finishedVector : std_logic_vector(10 downto 0);
3
4
PROCESS (clk)
5
   VARIABLE index : integer; -- Zeile neu hinzugefügt
6
   IF (rising_edge(clk)) THEN
7
      ...
8
      IF (x = '1') THEN
9
         -- Event greift, Setzen des entsprechenden Bits im std_logic_vector
10
         index := to_integer(unsigned(channel & '1'));
11
         IF (index = 5) THEN
12
            finishedVector(5) <= '1';
13
         END IF;

Die Warnung in den Synplify-LOGs für finishedVector(5) ist weg und der 
Code funktioniert auf dem Target für dieses Bit wie gewünscht.

Daher die Frage an euch, was ist in der obigen Zuweisung fehlerhaft bzw. 
wie müsste sie geschrieben werden, damit sie wie gewünscht synthetisiert 
wird?
Ich hätte erwartet, dass die direkte Zuweisung 
slv(to_integer(unsigned(slv))) <= '1'; ebenso funktioniert wie slv(5) <= 
'1';

Ich freue mich über eure Rückmeldungen und vielleicht liest es auch 
Lothar Miller :-)

von Bitwurschtler (Gast)


Lesenswert?

finished vector hat als höchsten index 10; das wird aber bspw. f. 
channel = "111" & '1'  überschritten.


Simu findet solche fehler nicht wenn range checking deaktiviert ist.

von Michi (Gast)


Lesenswert?

Beim slv "channel" steckt etwas Logik dahinter und vom Programm her ist 
es sichergestellt, dass keine Bereiche überschrieben werden.

Trotzdem habe ich es auf Deinen Tipp hin mal ausprobiert und die Zeile 
von
1
finishedVector(to_integer(unsigned(channel & '1'))) <= '1'; -- 5 Bit breiter Vektor
auf
1
finishedVector(to_integer(unsigned(channel(2 downto 0))) <= '1'; -- 3 Bit breiter Vektor
angepasst. Damit kann es kein Überschreiben von Bereichen geben.
-> Die Ergebnisse in den Synplify-LOGs sowie der Ressourcenbedarf im 
Mapper sind identisch.
-> Es funktioniert auf dem Target leider nicht...

von Bitwurschtler (Gast)


Lesenswert?

Check mal die eingebundenden Bibliotheken, bspw testbench

Unsigned wird in mehrenen Bibliotheken definiert, da kann es mal zu 
Problemen kommen.

Und wahrscheinlich steckt der Fehler in dem nicht zitierten VHDL-Code 
....

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


Lesenswert?

Michi schrieb:
> Ich verstehe nicht, was an der Zuweisung nicht passt bzw. warum die
> Synthese alle Bits des Vektors "finishedVector" fix auf 0 setzt.
Manchmal hat der Synthesizer Probleme mit relativ einfachen Sachen. Ich 
hatte das mal für genau solche Multiplexer untersucht. Mal sehen, ob ich 
es nochmal finde...

> Folgender Programcode funktioniert wie gewünscht (OK): ...
Hast du mal Zwischenschritte gemacht?
Z.B. ein Signal, auf dem der Index berechnet und dann im MUX verwendet 
wird?
Oder die Concatenation ausserhalb der Indexberechnung?

Also sowas:
1
SIGNAL index          : integer; -- und dann auch mal mit -- range 0 to 10;
2
SIGNAL channel        : std_logic_vector( 3 downto 0);
3
SIGNAL finishedVector : std_logic_vector(10 downto 0);
4
:
5
:
6
index <= to_integer(unsigned(channel & '1'));
7
8
PROCESS (clk)
9
   IF (rising_edge(clk)) THEN
10
      ...
11
      IF (x = '1') THEN
12
         finishedVector(index) <= '1';
Oder sowas:
1
SIGNAL channel        : std_logic_vector( 3 downto 0);
2
SIGNAL finishedVector : std_logic_vector(10 downto 0);
3
:
4
:
5
6
PROCESS (clk)
7
VARIABLE index : std_logic_vector(4 downto 0);
8
BEGIN
9
   IF (rising_edge(clk)) THEN
10
      index := channel & '1';
11
      ...
12
      IF (x = '1') THEN
13
         finishedVector(to_integer(unsigned(index))) <= '1';

Bitwurschtler schrieb:
> Und wahrscheinlich steckt der Fehler in dem nicht zitierten VHDL-Code
> ....
Den Verdacht habe ich allerdings auch ein wenig...  :-/
Welche Warnungen kommen sonst noch bei der Synthese?

: Bearbeitet durch Moderator
von berndl (Gast)


Lesenswert?

Vor einigen Jahren hatte ich auch mal Probleme in Quartus mit den 
berechneten Indizes. Loesung damals, wie auch oben von Lothar 
vorgeschlagen:
Ausnahmsweise mal eine Variable (integer) verwenden. Das muss dann 
eigentlich jedes Tool schlucken...

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.