Forum: FPGA, VHDL & Co. Warnung: "Variable must explicitly be declared as automatic or static"


von Mirko H. (mirkoh)


Lesenswert?

Liebe FPGA Entwickler Gemeinde,

im Rahmen eines Hobbyprojekts ("C64 Core für den MEGA65") habe ich vor 
einer Weile ein Altera/Quartus basiertes Projekt ("MiSTer C64 Core") auf 
Xilinx/Vivado 2019.2 portiert.

Das funktionierte gut - und funktioniert auch heute noch gut. Nur bin 
ich inzwischen auf Vivado 2022.2 umgestiegen und seit ich das gemacht 
habe, werfen SystemVerilog Code-Teile wie das Folgende die Fehlermeldung

"[Synth 8-10180] variable 'cur_track' must explicitly be declared as 
automatic or static"

Und das nicht nur für cur_track, sondern für jedes Register im always 
@(posedge clk) Block, das mit "0" initialisiert wird.

Ich bin VHDL Hobbyist und kann (System)Verilog grob lesen und verstehen, 
bin aber mit den detaillierten Unterschieden zwischen SystemVerilog und 
Verilog nicht sehr vertraut.

Googeln führte zu Verwirrung, weil mein Verständnis bisher war, dass die 
nachstehenden Register lokal im always Block gescoped sind - und wenn 
ich nun ein "static" davorschreiben würde wären wir dann nicht im 
Modulscope? (Wie gesagt: VHDL Hobbyist mit wenig Verilog Ahnung)
1
always @(posedge clk) begin
2
  reg  [6:0] cur_track = 0;
3
  reg  [6:0] track_new;
4
  reg        old_change, update = 0;
5
  reg        saving = 0, initing = 0;
6
  reg        old_save_track = 0;
7
  reg        old_ack;
8
9
        [... Code gelöscht ...]
10
end

Es ist nur eine Warnung und der Commodore 64 funktioniert einwandfrei, 
aber ich versuche immer die Anzahl der Warnungen zu minimieren - daher 
wäre ich für Euren Rat dankbar.

Hier ist das Codestück:

https://github.com/MJoergen/C64_MiSTerMEGA65/blob/6d0ff61a663bec1577bab7a575309dc5b911d925/rtl/iec_drive/c1541_track.sv#L60

Und hier ist ein anderes, welches auf den lokalen Scope vertraut und 
beispielsweise "cnt" mehrfach verwendet (Zeilen 47 und 73):

https://github.com/MJoergen/C64MEGA65/blob/master/M2M/vhdl/av_pipeline/audio_out.v#L73

Der Code ist nicht von mir, ich portiere ihn nur - und wie das bei 
solchen Retro-Computing Projekten so ist, fasse ich den Code nur mit 
Samthandschuhen an, damit ich Upstream Modifikationen weiterhin einfach 
einbauen kann (und um keine Inkompatibilitäten einzuführen).

Viele Grüße,
  Mirko

von vancouver (Gast)


Lesenswert?

Die Warning wird nicht durch den lokalen Scope verursacht, sondern durch 
die Initialisierung. Diese Art der Signalinitialisierung ist sehr 
fehleranfällig (in einem anderen Thread gab es dazu kürzlich eine 
hitzige Debatte) und wird in SystemVerilog eigentlich nur noch aus 
Kompatibilitätsgründen (zu Verilog) und in Simulationsumgebungen 
unterstützt. Daher die (etwas missverständliche) Warnung.
Einige Simulatoren (z.B. Verilator) deklarieren das als Fehler und 
brechen ab. Vivado hatte bisher eine eher entspannte Einstellung zum 
SystemVerilog-Standard, scheint aber aufzuholen.

Ich sehe hier drei Möglichkeiten:

1. Da es funktioniert, ignorierst du die Warning, aber das fällt dir 
irgendwann auf die Füße.

2. Der Sourcecode, den zu verlinkt hast, ist eigentlich kein 
Systemverilog sondern plain-Verilog (In SV verwendet man z.B. keine regs 
und wires mehr sondern logic, und always heißt jetzt always_ff). Du 
könntest das File von .sv in .v umbenennen, dann erkennt Vivado ein 
Verilog-File und mosert vielleicht nicht herum.

3. Wirf die Initialisierungen ganz raus und setze die Signale mit 
reset_s auf einen definierten Wert, wie es bei den meisten Signalen 
ohnehin gemacht wird.

Die beste Variante wäre, das ganze Modul in sauberen SV-Code 
umzuschreiben, aber das wird etwas mehr Arbeit.
Btw, Signale mit gleichem Namen in lokalen Scopes im selben Modul zu 
verwenden, ist nicht gerade die feine Art. Ich weiß gar nicht, wie man 
die im Simulator unterscheidet, wenn die always-Scopes keinen eigenen 
Namen haben.

von Mirko H. (mirkoh)


Lesenswert?

Danke Dir, vancouver.

Deine Antwort war extrem erhellend und hilfreich für mich.

Ich habe (2) probiert, aber Verilog akzeptiert keine Deklarationen in 
unbenannten Blöcken ("unnamed blocks"). Wenn ich dann einen Namen 
hinzufüge und neu synthetisiere, kommt die besagte Warnung trotzdem.

(3) möchte ich aktuell nicht machen, da - wie gesagt - der Code ein 
durch hunderte Hände gegangener und inzwischen extrem C64 kompatibler 
Retro-Computing Code ist; und ich möchte weiterhin die Chance haben von 
"Upstream" (z.B. vom MiSTer FPGA Projekt und vom MiST FPGA Projekt) 
Updates zu erhalten.

Daher werde ich für jetzt mit (1) leben müssen:

Man sieht diesen Codebases ihr Alter und die "vielen Köche, die den Brei 
verderben" durchaus an ;-)

Danke nochmals - dann weiß ich zumindest wo ich für ein zukünftiges 
Code-Cleanup Projekt ansetzen könnte (und da gäbe es noch tonnenweise 
mehr zu tun, nicht nur diese Sache ;-)).

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.