Hallo an alle, ich arbeite an einem recht aufwändigen FPGA-Projekt. Dort ist ein SDR Empfänger und Sender implementiert, der über einen I2C Bus gesteuert wird. Aktuell läuft alles - aber ich möchte den I2C-Block neu gestalten. Es ist keine IP - es ist ein in Verilog handgeschriebener I2C-Slave. In diesem Modul muss ich alles mögliche ändern. Um nicht jedesmal den kompletten SDR neu zu bauen (das dauert doch schon recht lange) verwende ich zum Testen dieses Entwicklungsboard hier: https://de.aliexpress.com/item/33050240958.html . Darauf läuft mein Code auch so wie er soll. Schiebe ich dieses Modul jedoch in das aufwändige Zielprojekt, dann funktioniert auf einmal der DSP-Teil (FIR-Filter, Dezimierung) nicht mehr so wie er soll. Ich habe Stunden den Fehler in meinem Code gesucht bis ich festgestellt habe, dass schon zwei banale Zeilen im I2C-Modul den gleichen Effekt haben: ich lege ein Register im Modul an mit reg [7:0] dataready; dem ich dann in der Resetroutine einen Wert zuweise mit: dataready <= 0; Sowie die Zuweisung drin ist, geht der DSP Teil nicht mehr. Das Register dataready wird sonst nirgendwo mehr benutzt (was mir Quartus Prime lite auch brav meldet) - aber nicht warum der DSP Teil dann nicht mehr läuft. Da diese beiden Zeilen nichts Böses in sich tragen (und auf dem Entwicklungsboard mit vielen anderen weiteren Zeilen auch eine bewiesene Funktion haben) kann ich mir nur vorstellen dass der Fitter Dinge anders routet wenn ich diese Zeile einfüge. Ich denke also ich muss dem Fitter irgendwie sagen (mit dem Constraints_File??) dass er das bestehende Routing so lassen soll wie es ist. Nach meiner Vorstellung nach dem ersten Lauf einen "Schnappschuss" machen und den dann als Basis für weiteres nehmen. Nur wie geht das? Und ist meine Vermutung überhaupt richtig? Ich bin in Sachen FPGA Programmierung noch ein ziemlicher Anfänger und war schon froh dass ich den I2C-Slave von "only read mit festen 10 Bytes" auf "Register verwenden - variable Datenlänge - read/write" umstellen konnte. Den DSP Code verstehe ich aktuell nicht vollständig. Es ist GPLv3 lizensierter Code den ich auch noch verstehen und verändern möchte: aber deutlich später. Solange ich schon am I2C-Teil scheitere brauche ich damit gar nicht erst anzufangen... Wie kann ich das Problem angehen? Ich bin für jeden Tipp dankbar!
Wie passen dies > ich arbeite an einem recht aufwändigen FPGA-Projekt. und dies > Ich bin in Sachen FPGA-Programmierung noch ein ziemlicher Anfänger zusammen?
Die Antwort passt nicht wirklich auf meine Frage ;) Es gibt viele bereits lauffähige Projekte / Codeblöcke. Die habe ich übernommen - vorerst ohne sie komplett zu durchschauen. Aber selbst dort habe ich schon kleiner Fehlerchen gefunden und beseitigt - und die Funktion war dann besser / stabiler (je nach Codeänderung die zu Grunde liegt). Und dann sind da einfachere Teile - wie SAI, SPI, I2C. Die verstehe ich schon. Das ist ein Hobbyprojekt, und ich liebe "learning by doing". Mir ist durchaus bewusst dass die Lösung meines Problemes vermutlich für jemanden der schon lange mit FPGAs und Quartus arbeitet einfach ist. Für mich aber trotz intensiver Nutzung der Suche im Forum hier und im Netz nicht.
Andreas R. schrieb: > Dort ist ein SDR Empfänger und Sender implementiert, der über einen I2C > Bus gesteuert wird. Also gibt es schon einen funktionierenden I2C Slave der den SDR steuert? Wenn ja, wie meinst du das? Da sind I2C Register, die den SDR einstellen? Andreas R. schrieb: > aber ich möchte den I2C-Block neu gestalten. > verwende ich zum Testen dieses Entwicklungsboard.. > Darauf läuft mein Code auch so wie er soll. Schiebe ich dieses Modul > jedoch in das aufwändige Zielprojekt, dann funktioniert auf einmal der > DSP-Teil (FIR-Filter, Dezimierung) nicht mehr so wie er soll. Also hast du ein neues I2C Slave Modul dafür geschrieben und willst es jetzt wieder mit dem SDR verbinden und dies funktioniert nicht? Vielleicht solltest du mal etwas Code zur Verfügung stellen damit wir dir hier eventuell weiter helfen können.
* Mach ne simulation vom I2C * Zeichne ein Blockbild mit den internen Bussen/Registern von deinem design *schau ob dein Ansatz (änderung des designs auf Board A mit FPGA-Typ X), Übertragung des Designs 1:1 auf ein anderes Board B möglicherweise mit FPGA type Y überhaupt funktionieren kann. Das "verwende ich zum Testen dieses Entwicklungsboard hier: Darauf läuft mein Code auch so wie er soll. Schiebe ich dieses Modul jedoch in das aufwändige Zielprojekt, ..." und "Ich denke also ich muss dem Fitter irgendwie sagen (mit dem Constraints_File??) dass er das bestehende Routing so lassen soll wie es ist. Nach meiner Vorstellung nach dem ersten Lauf einen "Schnappschuss" machen und den dann als Basis für weiteres nehmen." kann man auch so interpretieren, das dein Designflow/'Programmierablauf' nicht funktionieren kann. Weil die 'Teile' nicht zusammenpassen und du nicht weisst welche Dateien/Settings überhaupt zwischen den Systemen auszutauschen sind. -- Sorry aber das klingt nach einem grundsätzlichen Problem aus völliger Unkenntniss der FPGA-Methologie und digitaler Schaltungstechnik, da ist eine Hilfe per internetforum so gut wie ausgeschlossen. Lass Dir von einer Fachkraft vor Ort eine Entwicklungs-/Testumgebung aufsetzen und erklären. PS: Dein Link zeigt einen 10CL016 und keinen 10CL025 (wie im Topic behauptet).
Hmmm. Ominös. Kann eigentlich nicht sein. Ein zusätzliches Register, das lediglich initialisiert und nie gelesen wird, wird mit (sehr) hoher Wahrscheinlichkeit sowieso wegoptimiert (sollte im "Registers removed during Synthesis"-Report im "Analysis & Synthesis"-Log eigentlich zu sehen sein) und kann deshalb kaum die Ursache für das beschriebene Verhalten sein. Sehr viel wahrscheinlicher ist, dass das Timing ohnehin schon am Limit ist, nur zufällig funktioniert hat und Du an der völlig falschen Stelle suchst. Was sagt der Timing Analyzer? Der Ansatz ein (anscheinend) einmal funktionierendes Design "einzufrieren", unverändert weiter zu benutzen um "an anderer Stelle weiterzubauen" scheint naheliegend, führt aber nicht zum Ziel. Zum einen kann das die Lite-Variante von Quartus nicht (das erfordert "Design Partition"-Funktionalität und die gibt's nur gegen Bezahlung), zum anderen würde das wahrscheinlich auch nicht helfen (man kann nun mal nichts ändern, ohne was zu ändern).
Markus F. schrieb: > Sehr viel wahrscheinlicher ist, dass das Timing ohnehin schon am Limit > ist, nur zufällig funktioniert hat und Du an der völlig falschen Stelle > suchst. Oder gar, dass da irgendwo der übliche asynchrone Eingang nicht eingetaktet wird. Andreas R. schrieb: > Darauf läuft mein Code auch so wie er soll. Wieviele "Takte" hat dein Code? > Sowie die Zuweisung drin ist, geht der DSP Teil nicht mehr. Aber dein neu implementierter I2C tut was er soll? > Sowie die Zuweisung drin ist, geht der DSP Teil nicht mehr. Undd was davon "geht nicht mehr"? Einfach alles? Oder nur der Teil, der mit dem I2C interagiert? Was steht in den Reports? Infos, die du nicht verstehst, sind dabei genauso wichtig wie Warnings, die dir nichts sagen...
Danke für eure Gedanken und eure Zeilen. Ich bin gerade dabei das GitHub für den Code aufzuarbeiten und werde es dann veröffentlichen. Vorab: Das "Ursprungsprojekt" lief auf einem 10CL006 - der war damit "so gut wie voll". Dann habe ich eine neue PCB mit veränderter Hardware erstellt und einen 10CL016 eingesetzt. Auch das lief problemlos. Weil ich vor hatte erheblich mehr Hardware anzubinden habe ich getestet, ob auch der 10CL025 läuft: er tat es. Die Pinbelegung habe ich von Anfang an auf den 025 ausgelegt. Die FPGAs sind im 256 UBGA Gehäuse. Die letzte PCB ist nun fertig (6-fach-Layer) und auch diese tut wie sie soll. Die neu hinzugekommene Hardware ist bereits teilweise ausgetestet und läuft ebenfalls. Die weitere Hardware wird Stück für Stück in den FPGA-Code eingebunden - so der Plan. Via I2C wird die Arbeitsfrequenz und die Samplerate des Ausgangs-Datenstromes (SAI) eingestellt. Ich habe diese auch mal "hardgecoded" im FPGA, so dass der I2C nichts mehr weiterreicht was zum Betrieb nötig ist. Auch das läuft. Das I2C-Handshaking geht natürlich noch. Wenn ich dann die oben gesagte Registerzuweisung in den Code einfüge, geht das I2C-Handshaking nach wie vor, der SAI-Strom hat auch noch die richtige Frequenz, aber der Datenstrom stimmt nicht mehr. Auf jeden Fall geht der Empfänger nicht mehr (reagiert nicht mehr auf Eingangssignale) und das auswertende SDR-Programm, das am SAI lauscht, erkennt Rauschen mit hoher Feldstärke. Es kommt etwas aus dem Tritt was definitiv nichts mit dem Codeteil der verändert wurde zu tun hat. Es sind mehrere Takte im Spiel (logischerweise). Meine Vermutung ist dass es in der Tat an gravierenden Fehlern in der Verknüpfung der Taktsignale liegt. Dazu mache ich auch eine Blockschaltung die ins GitHub wandert. Es wird nicht möglich sein die Ursache einzugrenzen ohne Kenntnis des gesamten Projektes. EDIT/Nachtrag: In sofern kann ich zustimmen dass die Sache "zufällig" läuft. Die Taktverhältnisse sind nicht so verknüpft dass eine robuste Schaltung herauskommt.
:
Bearbeitet durch User
Andreas R. schrieb: > Danke für eure Gedanken und eure Zeilen. Ich bin gerade dabei das GitHub > für den Code aufzuarbeiten und werde es dann veröffentlichen. > > . Dazu mache ich auch eine Blockschaltung die ins GitHub wandert. Es ist hilfreich, wenn sich neben den Code auch ein dazu passender Satz an Logfiles (Synthese, placer, router, drc, ...) finden lässt. Idealerweise mit script für den Designflow, an dem man erkennt, welche Optimierungen/compilerschalter aktiv sind. > In sofern kann ich zustimmen dass die Sache "zufällig" läuft. Die > Taktverhältnisse sind nicht so verknüpft dass eine robuste Schaltung > herauskommt. Stichwort dazu ist CDC - Clock Domain Crossing, da hat die Software mehr oder weniger passende Checks deren Ergebnisse sich auch im Log unter diesen Stichwort finden lassen. Wobei man das Problem aber schon früh mit der Spec löst, indem man sich fragt, ob es diesen Taktdomänübergang braucht und welches Mittel aus dem 'Werkzeugkasten' (FIFO, Handshake, Synchronizer, Gray-Codierung, level statt edge-detection, debounce, ..) hier sinnvoll ist. Ich hatte mal das Problem bei ein-clk-langen Steuersignale, die aus der schnellen in langsame Domain wechselten und mit 50% Wahrscheinlichkeiten liefen (weil Taktverhältniss 2:1 und Phasenlage je nach Zufall bei PowerOn) die lediglich auf 2 clk pulsewidth verlängert werden mussten, damit es lief. Dort 'ne kurze Einführung in das Thema mit Vivado: https://www.xilinx.com/video/hardware/cross-clock-domain-checking-cdc-analysis.html Das Prinzip ist bei Altera/intel gleich, auch dr Syntax der timing constraints sollte inzwischen gleich sein.
C-64 Freund schrieb: > Wie passen dies >> ich arbeite an einem recht aufwändigen FPGA-Projekt. > > und dies >> Ich bin in Sachen FPGA-Programmierung noch ein ziemlicher Anfänger > > zusammen? Kann Dir doch am AW vorbeigehn, oder?!
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.