Zuweisung eines einzelnen slv-Elements funktioniert inklusive den cast-Anweisungen nicht

Gast #4543618
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 :-)
Gast #4543680
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...
Moderator (Firma: Titel) Persönliche Seite #4543713
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?

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