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
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
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?
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?
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
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
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.