Forum: FPGA, VHDL & Co. Lattice Ice5LP Warnung beim Synthetisieren: Pruning unused register


von Fritz W. (fritz6392)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich arbeite mit einem iCE5LP von Lattice. Zum Synthetisieren nutze ich 
Synplify Pro. Meinen Code habe ich angehängt. Dieser soll eine 
verlangsamte Clock (Port: CP) und einen einmaligen Start-Puls (Port: 
START) ausgeben. Der START-Puls soll dann ausgegeben werden, wenn an 
START_in eine positive Flanke auftrat. Das CP-Signal soll die ganze Zeit 
laufen.

Aus meiner Sicht für das Problem irrelevant, aber der Vollständigkeit 
halber noch diese Infos:
Den Port clk_en brauche ich, um den externen Oszillator zu enablen. 
Dieser gibt dann ein Clock-Signal an clk. Später soll die clock noch 
ausgeschaltet werden können, aber für den Anfang habe ich clk_en erstmal 
konstant auf HIGH gesetzt.

Meine Frage: Beim Synthetisieren bekomme ich folgende Warnung:
@W: CL169 :"  --Dateipfad-- \main.vhd":48:1:48:2|Pruning unused register 
START_reg. Make sure that there are no unused intermediate registers.
Was bedeutet diese Warnung?

Eine kleinere Frage noch nebenbei zu den Zeilen 55 und 56:
Brauche ich diese wirklich? Ich habe das jetzt zur Sicherheit gemacht, 
damit START_reg von Anfang an definiert ist. Oder hält der FPGA den Port 
automatisch auf Low, solange er undefiniert ist?

Wäre super, wenn mir da jemand weiterhelfen könnte.

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


Angehängte Dateien:

Lesenswert?

Fritz W. schrieb:
> Oder hält der FPGA den Port automatisch auf Low, solange er undefiniert
> ist?
Was steht denn im Datenblatt?
Wenn du ein Signal deklarierst und keinen Defaultwert angibst, dann 
wird das üblicherweise mit '0' initialisiert. Allerdings darf der 
Synthesizer auch gern von einem beliebigen Wert ausgehen und auch mal 
etwas mehr wegoptimieren. An dieser Stelle kann es dann passieren, dass 
sich die Simulation und die Realität unterschiedlich verhalten.

> Was bedeutet diese Warnung?
Kurz und bündig: du verwendest keine Defaultwerte.

Die längere Version:
Xilinx XST sagt zu deinem Code
1
WARNING:Xst:647 - Input <reset> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
2
WARNING:Xst:647 - Input <START_in> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
Hoppla, START_in nicht verwendet? Der hat das alles wegoptimiert?
Klar, kann er. Denn du hast keinen Defaultwert und keinen Resetwert für 
deine Signale angegeben. Deshalb darf er davon ausgehen, dass 
startreceived  dauerhaft auf '1' ist. Und dann wird START_in nicht 
gebraucht, und dann ergeben sich noch weitere lustige Effekte...

Nach dieser Änderung hier:
1
signal CP_reg: std_logic := '0';
2
signal CP_cnt: integer range 0 to 1000 := 0;
3
signal START_reg: std_logic := '0';
4
signal startreceived: std_logic := '0';
5
signal startsend: std_logic := '0';
Kommt dann ein
1
ERROR:Xst:827 - line 46: Signal START_reg cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

Also drehen wir die Reihenfolge dieser Beschreibung mal so um, dass auch 
der Synthesizer die Struktur erkennt und nicht ein nachrangiger Reset 
beschrieben wird:
1
  if startreceived = '0' then
2
    START_reg <= '0';
3
  elsif rising_edge(CP_reg) then
4
    :
5
          START_reg <= '1';
6
    :
7
  end if;

Dann verbleiben nur noch 2 Warnungen:
1
WARNING:Xst:1426 - The value init of the FF/Latch startreceived hinder the constant cleaning in the block top.
2
   You should achieve better results by setting this init to 1.
3
WARNING:Xst:1426 - The value init of the FF/Latch startsend hinder the constant cleaning in the block top.
4
   You should achieve better results by setting this init to 1.
Die besagen, dass man mit einem "besseren Defautlwert" so einiges 
wegoptimieren könnte. Aber da kommen wir ja her... ;-)



BTW1:
Schreib nicht überall ein elsif hin:
1
    if startsend = '0' then
2
      START_reg <= '1';
3
      startsend <= '1';
4
    elsif startsend = '1' then   -- unnötig und gefährlich!!!
5
      START_reg <= '0';
6
    end if;
Denn auf diese Art bleiben 7 der Zustände eines std_logic 
unberücksichtigt!
Schreibe einfach ein else und fertig.

BTW2:
Dein Design hat viel zu viele Takte. Ein Drittel sollte reichen...
Wenn du einen Takt hast, dann steht nur der im gesamten Design hinter 
einem rising_edge. Die restlichen Signale werden auf diesen Takt 
synchronisiert und dann taktsynchron mit diesem einen Takt verarbeitet.

BTW3:
So werden in einem FPGA keine Takte erzeugt:
1
      CP_reg <= not CP_reg;
Nicht umsonst hast du da auch Taktmanager mitgekauft. Oder besser noch: 
arbeite mit 1 Takt und Clock-Enables.

BTW4:
Dein Zähler zählt 1001 Schritte. Der allseits beliebte off-by-one 
Fehler...

BTW5:
> Aus meiner Sicht für das Problem irrelevant, aber der Vollständigkeit
> halber noch diese Infos:
> Den Port clk_en brauche ich, um den externen Oszillator zu enablen.
> Dieser gibt dann ein Clock-Signal an clk. Später soll die clock noch
> ausgeschaltet werden können
Du drehst dir damit selber den "Pulsschlag" ab. Warum das?

BTW6:
Wo ich das "main.vhd" so sehe: du programmierst dein FPGA so, wie du 
einen µC programmieren würdest. Das geht schief.
Nicht umsonst heißt es VH-D-L. Du solltest zuerst mal eine Vorstellung 
oder ein Bild  von deiner gewünschten Hardware haben. Und diese Hardware 
dann mit VHDL beschreiben.

: Bearbeitet durch Moderator
von Fritz W. (fritz6392)


Lesenswert?

Danke erstmal! Das hat mich vorrangebracht.

Synplify Pro unterstützt, wie es aussieht, keine Initialwerte. Ich bekam 
folgende Warnung:
@W: FX1039 :" --dateipfad-- main.vhd":35:1:35:2|User-specified initial 
value defined for instance CP_cnt[9:0] is being ignored.
analog kam diese Warnung natürlich für die anderen Signale.
Ich werde mal Lattice LSE probieren. Das braucht aber Zeit, weil glaube, 
dass ich die Constraint-Files dafür umschreiben muss.

Nur für mein Verständnis:

Lothar M. schrieb:
> Schreib nicht überall ein elsif hin:
>     if startsend = '0' then
>       START_reg <= '1';
>       startsend <= '1';
>     elsif startsend = '1' then   -- unnötig und gefährlich!!!
>       START_reg <= '0';
>     end if;
> Denn auf diese Art bleiben 7 der Zustände eines std_logic
> unberücksichtigt!
> Schreibe einfach ein else und fertig.

Mit dem elsif wollte ich sicherstellen, dass die Zeile darunter NUR dann 
ausgeführt wird, wenn startsend auch wirklich 1 ist. Alle anderen 
Zustände wollte ich bewusst ausschließen. Sonst könnte die Zeile 
darunter ja auch ausgeführt werden, wenn startsend einen der anderen 
Zustände hat, oder?
Außerdem gibt später im FPGA doch nur die Zustände 1 und 0, die übrigen 
Zustände sind doch nur für die Simulation, oder?

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


Lesenswert?

Fritz W. schrieb:
> Außerdem gibt später im FPGA doch nur die Zustände 1 und 0, die übrigen
> Zustände sind doch nur für die Simulation, oder?
Richtig, und aus diesem Grund kannst du das bedenkenlos zugunsten der 
Leserlichkeit weglassen.

> Alle anderen Zustände wollte ich bewusst ausschließen.
Weil es sie nicht gibt musst du sie auch nicht beachten.
Sieh dir einfach mal anderen VHDL-Code an. Und besonders das Handbuch 
zum Synthesizer. Dort steht drin, was er versteht und in Hardware 
umsetzen kann, und auch, wie es dafür beschrieben sein muss.

> Sonst könnte die Zeile darunter ja auch ausgeführt werden
Schon wieder der Programmierer, dessen "Code ausgeführt" wird. Da wird 
nichts "ausgeführt", sondern deine Beschreibung wird in Hardware 
umgesetzt. In dieser Hardware ist jede "Codezeile" immer vorhanden und 
die zugehörigen logischen Verknüfpungen werden jederzeit parallel 
"ausgeführt", und die resultierenden Signale stämdig aus den aktuellen 
Signalen neu "berechnet". Stell dir einfach ein UND-Gatter vor: das 
"durchläuft" die UND-Funktion nicht nur bei jeder Signaländerung, 
sondern es erzeugt das Ergebnis auch dann, wenn sich die Signale nicht 
ändern. Aber bleib einfach dran, dann wird das schon noch...  ;-)

> wenn startsend einen der anderen Zustände hat, oder?
Und was müsste dein Code machen, wenn so ein "anderer Zustand" 
auftaucht? Die Augen zu und ignorieren?

von Fritz W. (fritz6392)


Angehängte Dateien:

Lesenswert?

Ich habe den Code jetzt mal angepasst.

Lothar M. schrieb:
> So werden in einem FPGA keine Takte erzeugt:      CP_reg <= not CP_reg;

zur Erzeugung des CP-Signals habe ich diese Zeile wieder benutzt. Wenn 
ich dich richtig verstanden habe ist so etwas nur für interne 
Clock-Signale ungünstig.

Jetzt funktioniert mein START-Signal aber garnicht mehr. Es wird immer 
nur 0 ausgegeben. Woran kann das liegen? Ich kann mir das überhaupt 
nicht erklären. Das CP-Signal funktioniert einwandfrei. Auch der 
FPGA-Pin ist in Ordnung, ich habe das START-Signal mal an einem anderen 
Pin ausgeben lassen, da war es aber das Selbe.

Synthetisieren mit Lattice LSE funktioniert. Ich bekomme aber die 
Warnungen:

Warning: The terminal connectivity clk_en_pad:OUTPUTENABLE is removed 
because the PIN_TYPE is configured as 011001
Warning: The terminal connectivity START_pad:OUTPUTENABLE is removed 
because the PIN_TYPE is configured as 011001
Warning: The terminal connectivity CP_pad:OUTPUTENABLE is removed 
because the PIN_TYPE is configured as 011001
Warning: The terminal connectivity clk_pad:OUTPUTENABLE is removed 
because the PIN_TYPE is configured as 000001

WARNING - synthesis: There are no design constraints in the file 
--Dateipfad-- /constraint/synthesis_settings.sdc
WARNING - synthesis: .. --Dateipfad-- main.vhd(46): Register 
startreceived_40 is stuck at One. VDB-5014
WARNING - synthesis: .. --Dateipfad-- main.vhd(64): Register 
startsend_44 is stuck at One. VDB-5014
WARNING - synthesis: ..--Dateipfad-- main.vhd(64): Register START_reg_43 
is stuck at Zero. VDB-5013

vielleicht hat das ja etwas damit zu tun. Woher kommen eigendlich die 
Nummern hinter den Signalen, z. B. startreceived_40? es gibt bei mir 
doch nur ein startreceived.

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


Angehängte Dateien:

Lesenswert?

Fritz W. schrieb:
> because the PIN_TYPE is configured as 011001
Was hast du denn im Constraint-File angegeben?

Ich habe dein Design nochmal etwas umgearbeitet und ein komplett 
synchrones Design daraus gemacht. Mir scheint auch ein Zurücksetzen des 
Vorteilers im "Wartezustand" sinnvoll...

> Woher kommen eigendlich die Nummern hinter den Signalen, z. B.
> startreceived_40?
Das ist eine interne Nummerierung für die verwendeten Flipflops.


BTW:
Empfiehlt das Handbuch zum Synthesizer diese Art von Clock-Enable:
1
  elsif rising_edge(clk) and clock_en = '1' then
2
    ...
Oder sollte da nicht die traditionelle Variante stehen:
1
  elsif rising_edge(clk) then
2
    if clock_en = '1' then
3
      ...

BTW2:
Hast du eine Testbench für dieses Design? Oder simulierst du das gar 
nicht?

: Bearbeitet durch Moderator
von Fritz W. (fritz6392)


Angehängte Dateien:

Lesenswert?

Meine beiden constraint-files habe ich mal angehängt. Ich glaube, dass 
011001 für die Einstellung "-io_std SB_LVCMOS -pullup no" bei einem 
Output steht, aber was soll mir diese Warnung sagen?

Eine Testbench habe ich nicht, ich teste direkt in der Hardware.

Ich habe mir auch mal mein Package View in iCECube angesehen. Das 
clk-Signal war anfangs noch grün, dann habe ich die pinning.pcf neu 
importiert, jetzt sind alle Inputs weiß (Screenshot liegt anbei). Die 
Outputs konnte ich auch per drag and drop zuweisen, das funktioniert mit 
den Inputs nicht.

Mein CP-Signal funktioniert auch nicht mehr.

Die fehlenden Input-Zuweisungen sind bestimmt die Erklärung. Aber was 
ist an den Einstellungen denn noch falsch?

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


Lesenswert?

Fritz W. schrieb:
> Ich glaube, dass 011001 für die Einstellung "-io_std SB_LVCMOS -pullup
> no" bei einem Output steht, aber was soll mir diese Warnung sagen?
Dass du den da nicht verwenden kannt. Denn der hat offenbar was mit 
differentieller LVDS-IO zu tun. Sowas hast du in deinem Design aber 
nicht...

Ich würde da was im Stil von LVCMOS33 erwarten und einsetzen.

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.