 Okay, vielleicht ein bisschen ungewinnig heute mal die Slides. Das ist ein Textfall. Für mich der Grund, warum ich es so gemacht habe, weil ich ja sozusagen immer wieder Programmschnipsel habe und wenn ich diesen irgendwie rein kopieren muss, in irgendwelche Folien oder so, was war mit so blöd. Okay, dafür gibt es ja noch dieses Kontroll, ich weiß nicht, ob das jemand noch kennt. Das ist so seitenweise im Moor oder irgendwas anzeigen lassen. Okay, also heute Thema, Verlog Design Pattern. Ich bin Schipp-Designer, seit jetzt irgendwie so zwei Dekaden und habe da eine ganze Menge sozusagen selber lernen müssen, weil ich an der Stelle kein guten Lehrer hatte. Und eigentlich möchte ich jetzt sozusagen aber an der Stelle weitergeben, was sich so an die Zeit, über die Zeit so an Tricks angesammelt hat. Oder an Prinzipien. Okay, fangen wir mal mit den einfachen Sachen an. Kombinatorische Leitungen. Also sozusagen, dass was irgendwie ein, wie soll man sagen, nicht registriert wird, dass er kein Speicher verheiften hat. Kann man ein Verlog ja irgendwie so schreiben, wenn man sagt, hier von wegen Wire und dann irgendwie einfach aufzählen. Das geht. Wenn die Signale gleich bleiben, also alle gleiche Eigenschaften haben, kann man aufzählen. Das ist immer ein bisschen unschön. Macht vielleicht den Code ein bisschen schwerer lesbar. Was noch so eine Geschichte ist, wenn man hinguckt, es gibt ja diesen Prozess, um kombinatorisch zu beschreiben. Also always add, immer wenn oben eine Bedingung erfüllt ist, so was passieren. Also hier in dem Fall A oder B sich ändert. Denn soll der Simulator da reinspringen und sozusagen das ausrechnen. Aber was ist jetzt an der Konstruktion falsch? Was ist das? Also du hast recht, die Sensiviteliste ist der Haken, der da drin ist. Aber es ist so, dass er der Simulator nicht drauf reagiert. Der Simulator, der sozusagen falsche Ergebnisse anzeigt. Und es ist ein These-Tool, inzwischen so schlau ist, dass es einfach drüberhin weggeht. Ja. Also das würde sozusagen für Synthese funktionieren, für Simulation nicht. Also man hätte sozusagen eine Differenz zwischen Simulation und Synthese. Komm ja aus der VHDL-Welt und bin hier neugierigererweise nur, um mal quasi so ein bisschen über den Zaun zu gucken. Du hast gerade gemeint, das Synthese-Tool wäre so schlau, dass es da einfach drüberhin wegzieht. Ist das nicht ungeschickt? Also wäre es nicht eigentlich schlauer, für das Synthese-Tool dann nicht drüberhin wegzusehen und zu sagen, hier guck mal, wenn du das so schreibst, kriegst du Verhalten, dass sich in deinem Simulator und auf deinem Chip unterscheidet? Nee, ich glaube, da sind die Toolhersteller so, dass sie sagen, die Dummheit der Menschheit ist unendlich und wir müssen sozusagen nachgeben. Du hast nur noch was? Ich meine da noch ein anderes, einen anderen Effekt zu sehen, und zwar, wenn sich jetzt A, B und C nicht zum gleichen Zeitpunkt verändern und das wird nie passieren, wahrscheinlich habe ich da lauter Glitches im Z drin, die mich nachher wahrscheinlich stören werden. Du hast immer Glitches im Z drin, das ist richtig. Es ist wirklich so, wenn hier irgendwo sich was ändert, der macht die Operation am Wieder. Also Glitches hat man drauf. Aber normalerweise nimmt man ja dann sozusagen für Abspeichern von Werten danach Register und da hat man das nicht mehr. Jetzt eine Konstruktion, gleiche, kombinatorisch, nur halt ein bisschen besser. Wir haben erstmal hier die ganzen Signale aufgetrennt, also nicht wohl wegen alle in einer Zeile reingeschrieben, ist mehr Tipparbeit, ist aber einfacher zu patchen. Also wenn irgendwo Diff hat, wenn irgendwo was nicht irgendwelche anderen Sachen macht, so ist es einfacher. Also so ein Diff ist ja meistens zahlenbasiert. Man sieht sozusagen, was sich da geändert hat. Wenn man das alles in einer Zeile hat und da fehlt plötzlich irgendwie eine Viabe zwischendurch, dann muss man irgendwie ein bisschen länger im Bildschirm starten, um sowas zu sehen. Okay, hier haben wir auch die Sensivitiliste wieder vollständig. Aber da würde ich auch sagen, das ist WRLock95. Als ich auch irgendwie im Workshop schon drüber gerede, gab mir mal zwei Standlots, dieses WRLock95, das ältere, und dann dieses 2001er, das das Leben ein bisschen leichter macht. Da heißt es so, bei WRLock95, wir müssen wirklich die Sensivitiliste komplett aufführen. Immer mit allen Sachen, sonst haben wir den Ärger. Und jetzt haben wir so eine Konstruktion drin, WRLock2001. Da ist es so, kann ich bei kommunaturischen Sachen einfach ein Sternchen hinschreiben. Das ist mir immer das Leben unendlich leichter, weil dann fängt nämlich der Simulator oder das Synthesitul an zu gucken, welche Sachen ändern sich da drinnen oder können sich da drinnen ändern, nach welchen muss ich überhaupt gucken. Da sucht er sich selber raus. Also wenn jemand 2001 einen Code schreiben will, kann er das so machen. Meine Empfehlung dabei ist, wenn man sozusagen Features nutzt für auch für 2001, gleich oben in die Hände rein, oben in die Zeile rein, das wäre doch 2001. Man sozusagen gleich sehen kann. Okay. Jetzt hatte ich natürlich ein Beispiel gehabt, das ein bisschen länger war umständlich, mit dem Always Beginn End und so. In dem Fall hätte man auch einfacher schreiben können. Die können nämlich jetzt hier einfach sozusagen eine Assign-Anweisung ausgeben. Also von wegen, wir brauchen jetzt nicht keine Sanzivilliste dafür schreiben. Wir schreiben einfach so von wegenweise diese zwei Additionen dem Z zu. Aus. Das gibt es auch in Folie L so ähnlich. Okay. Blocking, Non-Blocking, Assignments. Das ist eine Geschichte, wo ich euch sagen, setzt euch damit mal richtig auseinander. Wenn ihr irgendwie so WLock code schreiben wollt, gibt es hoffenweise Forum-Einträge dazu. Der Hintergrund ist der, wenn ich Prozesse habe, wo sozusagen immer alles Sachen gleichzeitig laufen. Also wie zum Beispiel hier bei Hardware-Beschreibung. Und ich jetzt irgendwie so eine Zuweisung habe, die nur mit zum Ist gleich ist oder mal gucken. Ob ich jetzt sozusagen Blocking habe oder nicht Blocking. Das war irgendwie auch eine Frage der Workshop. Aber da würde ich sagen, Hausaufgabe selber an gucken, selber lernen. Gibt es tatsächlich Blocking Assignments? Das sind ja nur Weihers. Da ist ja kein Register beteiligt. Theoretisch dürfte auch kein Timing, also kein Blocking beteiligt sein, oder? Theoretisch, ja. Also, es gibt keine Weihheiten geben. Also du kannst an der Stelle vieles falsch machen. Deswegen einfach sozusagen, die goldene Regel ist eigentlich, wenn ich Kombinatorik habe, benutze ich immer, es ist gleich, für Synthese. Wenn ich Register habe, immer das mit dem Zuweisungs davor. Allerdings, das ist wieder so eine Geschichte, das ist bei Synthese. Wenn ich Testbenches habe, dann sind auch die anderen Sachen freigestellt. Aber ich hatte das zeitliche Verhalten, von wegen nicht alles zum gleichen Punkt, oder Testbench kann ich sagen, mach mal das und dann ein paar Sekunden später oder ein paar 90 Sekunden später was anderes. Ein bisschen aufpassen. Das ist denn so eine Geschichte, die sozusagen auf einer Testbench laufen und sozusagen auch Sachen haben, kann die hintereinander ablaufen. Okay, aber hören wir ja eigentlich bei hier Register. Unterschied ist, ich habe jetzt hier für Zet gesagt, das ist ein Register. Also mit Speicherverhalten soll das sein. Und ich habe jetzt hier für den Prozess nicht mehr die einzelnen Variabeln drin, die sich ändern können, sondern ich habe hier eine Triggerbedingung, das sage ich, eine Post-Edge für eine Clock. Also wenn die Clock eine positive Tagflank, also ein steigender Tagflank hat, dann soll das passieren. Und der Unterschied ist jetzt gegenüber der Kombinatorik, da oben, die Kombinatorik hat das halt immer gemacht, auch wenn die Variabeln sich geändert haben. Und hier ist es so, hier wird diese Operation nur einmal ausgeführt, nämlich dann, wenn die Clock Flanke kommt. Und wieder wichtig, Register, da, die ist ein anderen Zuweis uns erbar hat, also das kann man, Toffelsküche. Okay. Jetzt haben wir hier, da sind wir, bei einem Resetwerk. Also wir brauchen immer einen Reset, da fehlt mir glaube ich eine Folie. Dann kommt später mal gucken. Also dieser Reset hier oben, sage ich auch im Kommentar, das ist auch wieder so eine Schicht, bei Reset, der kann oftmals negativ sein. Manchmal positiv, bei FPGAS ist das positiv, dass ich wirklich beim Reset immer reinschreibe, wie rum der aktiv ist. Vom Namen habe ich auch sozusagen Unterscheidung, da habe ich oben wie kein Ander, das ist positiv. Immer so kleine Sachen, um solche Sachen rauszuhalten. Beise wie, es gab auch schon mal zwei Teams, die haben zusammen Chip gemacht. Das eine Team hat es mit einem positiven Reset gearbeitet, das andere mit einem negativen Reset. Ihr könnt euch überlegen, wie gut das Chip funktioniert hat danach. Der Reset hat super funktioniert, genau. Okay, also hier Clock, die beiden Signal, die ich habe. Gestaltet sieht es eigentlich so aus, von wegen Always, immer wenn die Posage kommt für den positiven Reset, also die, oder die Posage für den Clock, dann gehe ich hier rein, gucke nach, wie jetzt der Reset liegt, mache die Zuweisung und wenn nicht, dann mache ich hier unten in dem Clock Teil, mache sozusagen Operationen. Aber, das ist eigentlich schöner Code, trotzdem sehr hässlich. Hässlich deshalb, weil dieser Wert den ich dem Reset, also mit dem Reset, der war, ich habe den Zuweisung. Der steht irgendwo in einer Zelle hard codiert drinnen, kann man schöner machen. Wenn wir jetzt nämlich da reingucken, da waren wir, ich habe nämlich jetzt hier vorher lokal Param gemacht. Also wie soll ich sagen, bei Berylab2001 wieder, es ist eine Geschichte, dass man lokale Parameter vergeben kann, also sowas wie Konstanten. Parameter ist eine Konstruktion, kannte Berylab vorher schon in Berylab99, damals ich konnte die von außen sagen, wenn ich ein Modul aufgerufen habe oder instanzeheiert, wie jetzt gerade die Parameter gesetzt sind. Hat man ja in dem Workshop ein bisschen ein Turbo geredet. Local ist aber so, das Ding gilt wirklich nur innerhalb des Teils, also es ist wirklich schön eine Geschichte von Kapseln, wie man es früher auf mir bei der Uni noch gelernt hat. Und in dem Fall sage ich, mein Z, so als Default wird hier Null haben. Es hat den Vorteil später, wenn man sieht, diese Reset beschäftigt mich mehrmals, ich kann sie sozusagen nicht mehr übeln, ich kann es sozusagen nicht irgendwo, den Reset wird zweimal irgendwie unterschiedlich zuweisen. Ich habe nur noch diesen einen da. Und immer ich setze nicht so, wenn der Reset reinkommt, da ist die Zuweise, da steht nicht mehr hart kodiert, die Null drin, wieder oben, sondern da steht hier der Local Param drin. Und das ist einfach hier der Kommentar besser eigentlich, weil ich einen explizit Resetwert habe. Es ist auch eine Geschichte, zum Beispiel bei VRL. Wenn ich bei VRL Typen definiere, irgendwelche Exoten, ich habe immer gleich unter Typ Definitionen unten drunter eine Konstante, wo ich den Default dafür mache. Wir sparten jetzt nochmal bei VRL diese langen Konstruktionen, wenn es in der Nacht geschachtelt wird, wie dann der Reset zu legen ist. Okay, jetzt haben wir da so oft wie möglich Konstanten benutzen. Macht das Leben einfacher. Kann ich mal clean machen, oder? Na gut, okay. Jetzt kann man die Stiche, da müsst ihr ein bisschen im Hintergrund behalten für was ihr eigentlich die Synthese machen wollt. Wollt ihr den ESIC machen oder wollt ihr den FPGA machen? Und zwar der Grund ist der für ESICS. Stehen hier die Argumente da. Wenn ihr kein Reset benutzt, kann euch das den Job kosten, den Kopf oder was auch immer. Auf dem ESICS ist es so, nach nebenen Chip wirklich eingeschaltet wird. Die Regisse liegen zufällig. Ob die nach 1 gehen oder nach 0 ist das völlig stochastisch. Ihr habt keine Chance drüber. Damit ihr aber ein definiertes Verhalten habt mit dem Augenblick, wo es losgeht braucht der definierte Anfangszuständer. Und dann habt ihr solche Zustände die ihr nicht mehr vorausahnen könnt, was passiert. Also immer ein Reset dran. Das ist so die Regel dafür. Mag auch der Testengineer. Der will nämlich auch so vom Wegen von der Chip durch, zieht dann ein Reset. Danach weiß so und so liegen die Register. Und wenn die so liegen, dann kann er mit ein paar Tricks an den und den Stellen nachgucken, testen. Wie sozusagen die Kombinatorik verhält. Ist die da richtig oder ist sie kaputt? Der Testengineer wird durch den Kopf abreißen. Der Manager wird durch den Kopf abreißen. Und die Frauenrie wird durch den Kopf abreißen. Weil die sagt, so können wir nicht produzieren, wenn ihr den Reset vergisst. Du verwendest da oben einen Synchronenreset. Ich als wiederum FPGA-Entwickler, du wahrscheinlich als Chip-Designer, würde an der Stelle normalerweise eigentlich Synchronenresets verwenden. Einfach aus ressourcensparenden Gründen. Wie macht man das? Also ist das auf Chips anders? Nein, es ist so, dass diese Schreibweise Asynchronen, sozusagen die ältere, die historisch gewachsene ist. Und die Tooler-Steller sozusagen auch wieder gegenüber der Manpower gegeben haben und gesagt, okay, ihr könnt jetzt schreiben, was ihr lustig seid. Am Ende derjenige, der die Synthese macht, der kann über eine Option angeben, ob jetzt sozusagen Synchronenflipflops oder Asynchronen dafür verwendet werden sollen. Das heißt, um nochmal nachzufragen, das Konstrukt da oben, würde bei entsprechender Parametrisierung des Synthesituls tatsächlich einen Synchronenreset synthesieren? Ja, man kann natürlich das aus, aber das ist dann wieder Wörter-Synthese. Okay, also hier Reset nutzen, für ESIX. Und es sieht dann so aus, also wir haben hier ein Register für ein Set, weil wir wollen ja irgendwie was einsparenden, wir haben hier den Logeparam mit dem Default Wert, wir haben hier den Reset und wir haben hier Zuweisung. So, da ist ganz gut. Was haben wir mal jetzt? Reset, also wirklich für jedes Flippverpfiedeslatch, für jede Speicherzelle. Ramm sind ausgenommen. Das geht ein bisschen daneben. Für FPGAs kam man jetzt schon, was das sehr anders macht. Also da ist es so, FPGAs gab es irgendwann oder eine Anfangszeit, als FPGAs gemacht worden sind, hat auch jeder Design Engineer Resets geschrieben. Immer wieder für alles Mögliche. Bis dann irgendwann jemand bei Zylings mal auf die Idee kam, mehr geht das so offen, und wir sagten mit den ganzen Resets, die verbraten uns die ganzen globalen Ressourcen. Also das, was wir haben, um Klok zu ruten, irgendwelche anderen Signale, die überall hin distributiert werden müssen, also in jeder Ecke von dem Ship. Die natürlich entsprechend große Netzwerden, entsprechend große Treiber brauchen und entsprechend auch schlecht zu Konstruieren sind, also von wegen zeitlich einzuhalten sind in einer bestimmten Zeit. Und jetzt sagt der FPGA, der Designer, ich brauche ja eigentlich gar keinen Reset, weil wenn ich den FPGA konfiguriere, habe ich mit der Konfiguration jedem einzelnen Flipflop gesagt, was seinen Startwert ist. So was wie ein Resetwert halt. Und danach, wenn ich irgendwelchen Trubbel bekomme und sage, ich müsste jetzt eine Resetleitung ziehen, kann ich genauso gut an der Konfiguration ziehen und sagen, konfiguriere FPGA nochmal, dauert ein bisschen länger, oder der Effekt ist der gleiche. Und ich habe die ganze Resetleitung eingespart. Und da ist es nämlich jetzt so, Resets sind bei FPGAs zu vermeiden und hier wird plötzlich viel viel schneller. Und dann sieht nämlich der Prozess wieder ganz anders aus. Also wir haben dann irgendwie ein Register und wir haben nur noch beim Orbis das Post-Edge-Klock. Wir haben hier kein Reset mehr drin. Okay. Das passt da nicht rein. Jetzt haben wir auch das Problem, wir wollen ja eigentlich Kurschreiben, der auf ESIX und FPGAs zu benutzen ist. Da kommt eine Frage rein. Noch eine Frage und zwar wenn man diesen Reset nicht hat, wo kommt dann dann nicht der Startwert her? Ich denke, ist der da null? Du meinst jetzt hier in dem Fall? Ja. Also es gibt, so wie es jetzt da steht, würden die Tool-Hersteller wirklich null draus machen. Ich komme jetzt irgendwie noch auf eine Lösung, die sozusagen beides erlaubt und da steht es wirklich explizit drin. Okay. Und die Lösung eigentlich sozusagen um ein Code zu schreiben, der sowohl auf dem SPIA laufen könnte als auch ESIX, ist eigentlich ein bisschen umständlich. Man braucht sowas wie ein Conditional Compiling. Ein kleiner Zwischen. Und das kann dann halt so, hm? Ah, okay. Also dieses Define, da hier von wegen welchen Coding Style diese Define heißt bei mir Coding Style FPGA. Sprich, ich will beim FPGA keinen Reset-Renner haben. Das Ding kommt bei mir ins Make-File. Wenn ich den Aufruf mache und von wegen Synthese jetzt für ESIX, ist es nicht drinne. Da wird es da sozusagen das Reset, was überall im Code drinne steht. Wenn das Ding aber gesetzt ist im Make-File, würde ich die Sachen rauslassen. Und jetzt müssen wir ein bisschen das hier im Sacken lassen. Da ist das, was du eben mit der Einführung hattest. Da ist mein Reset-Wert drinne. Und da ist die Zuweisung. Also wir haben ja hier von wegen, wenn FPGA definiert ist, dann gebe ich dem Register den Default-Wert mit. Also den Init-Wert, wie es heißt. Der Init-Wert würde erstarten nach der Konfiguration. Und wenn nicht, dann bin ich sozusagen im ESIX-Zweig. Und dann ist es erstmal ohne in der Zuweisung. Weil ESIX, die können das nicht. Die Synthese-Tools sind da überall vorne. Das was jetzt kommt, sieht ein bisschen hässlich aus. Es ist aber eigentlich so eine Sache, wenn man es einmal geschrieben hat, man kommt mit ein paar Seten und gewöhnt sich dran. Also der Coding-Style von wegen für FPGA Wenn ich im ESIX drinne bin, dann habe ich beides drinne. Da ist nämlich auch der Reset drinne. Da habe ich den Reset-Sweig drinne. Wo ich wieder diese Default-Ware habe von da oben benutze, einmal. Das zweite mal hier habe ich das schon einmal benutzt. Und ich höre dann sozusagen auf. Und bin hier in der ganz normalen Bedingung operational, wie auch immer, was sonst laufen würde. So weit so klar. Meine Frage dazu ist, muss ich nicht einfach der Synthese überlassen, das rauszuwerfen. Also wenn ich im Prinzip immer mit Reset die Implementierung, also immer mit Reset schreibe, aber dann nachher das Reset-Signal immer fest auf 1 habe im FPGA-Teil, dann wird die Synthese das ja komplett rauswerfen, weil es nie Flanken drauf gibt. Und dann hätte ich quasi nur einen Codefahrt, der für beide funktioniert, ohne die Defines und IF-Defs. Also die Variante, die da steht, funktioniert wirklich in beiden Richtungen. Ich schreibe immer mit Reset und besetze den Reset dann mit einem Startwert, dass er sozusagen nicht gültig ist oder wie auch mal weg synthetisiert ist. Ist unschön. Würde vielleicht gehen. Aber jedenfalls die Variante da. Die kann ich nur sagen, die benutze ich irgendwie seit fast 10 Jahren und habe bisher nie wieder Probleme gehabt. Vorher habe ich auch eine ganze Weile damit umexperimentiert, wenn man es am besten macht. So dass der Code wirklich einfacher ist und die FPGA-Tools dann wenigsten Probleme damit kriegen. Also, kleinen Nachteil haben wir trotzdem, wir müssen beide Fälle, also mit und ohne Reset, sozusagen gucken in der Simulation, Verifikation, dass die funktionieren. Den Reset, wenn ich den Reset jetzt nicht verkabel im Code, würde sich doch nachher der Benutzer des Teams wundern, dass nichts passiert, wenn ich am Reset ziehe. Wie kriegt das den Engriff? Wenn, ich soll sagen, also das Tool selber stört sich da nicht dran. Gibt auch keine unbedingt Warnung draus. Also, da weiß ich nicht, muss ich passen. Würde sozusagen schöne Antworten voneinfallen könnte. Ja. Also, ich habe noch keine Warnung gesehen, weder bei ESSIG oder FPGA-Tools, die dazu was gebracht haben. Ich meine, mit Benutzer des Chips, der den tatsächlich in der Hand hat, nachher und irgendwo einlötet, wenn der am Reset zieht, um den Chips zu resetten, will ja nichts passieren, wenn ich... Ach so, beim richtigen Chip, also wenn du Sillizium in der Hand hast, dann hast du ja diese Variabel hier oben für FPGA-Coding-Stylen nicht gesetzt, die da. Und dann sind die diesiert, hm? Denn FPGA hat selten Reset draußen dran. Also, der Reset, wenn dann ist er an der Konfig angeschlossen, muss ich also sagen, auch der logaktive Konfig gezogen wird und dann wird wieder neu konfiguriert. Also, es wird nicht sozusagen im FPGA-Reset gezogen, sondern die ganze Konfiguration wird neu geladen. Also, mir sind wirklich noch keinen Fall untergelaufen. Also, das was ich schon gesehen habe, sind irgendwelche Sachen, dass Leute ein bisschen clever waren, die Sachen, wir hatten PLL drin und wir wollen sicherstellen, dass die PLL läuft, wir haben sozusagen einfach geguckt am Anfang, wenn die PLL eingeschwungen ist, das Log-Signal kommt von der PLL und wir sagten, jetzt geben wir den internen Reset frei, das war drin. Man macht sich beim FPGA wirklich mit Reset das Timing kaputt. Es geht auch mit oder es geht auch ohne. Manchmal braucht man ja eh irgendein Schaltkreis, der das Reset signal noch regelt, weil ansonsten macht man sich immer das Timing kaputt, das stimmt ja schon. Weil, wenn man jetzt verschiedene Clock Demins hat, muss man es ja auch irgendwie synchronisieren. Also Clock Demins ist so ein einzelner Ding, was besonders. Also, ich denke mal, du guckst offen einfach. Also, grob gesagt, sagen wir so, erster Nährung haben wir so, zweiter Nährung haben wir bestimmt irgendwo noch eine Sonderlocke extrawurst, begründet, sagt, warum es nicht so geht. Okay. Jetzt haben wir jetzt schon eine ganze Menge gut gesehen. Ich muss mal auf einen anderen Punkt einspielen. Ich habe ja hier bei dem Z Default mal so irgendwie ein Anderscore vorne drinnen gehabt. Man sollte beim Code schreiben so etwas wie Neeming-Rules einhalten. Manchmal ist es ganz praktisch genau die gleichen Namen zu verwenden, wie es ein Aspekt drinnen stehen, wie es ein Algorithmus drinnen stehen, wie es sozusagen eine Referenz hat. Es ist auch sinnvoll, Signale so zu benennen nach High-Aktiv-Low-Aktiv. Also, reset hat man schon. Aber in meiner Wahl bist du immer High-Aktiv. Wenn man einen loaktiven Signal hat, dann gibt es dieses Ander-N meistens hinten dran gehängt. Jetzt gibt es Leute, die sagen, ich will aber auch wissen, wenn ich ein Port habe, ob das Signal jetzt rein oder raus geht, was ein Port. Also, der Wichborn-Standard hat das z.B. so drinnen. Es ist eine gute Sache, sehr zu empfehlen und sozusagen an den Port-Signalen das dranstehen hat. Ob rein oder raus. Bei der Instanz-Irogue sieht man das dann sofort, ohne erst wieder in den Händen reingucken zu müssen. Allerdings, wenn man das Post hinten dran hängt, dann gibt es dieses Ander-O und das wird ein bisschen hässlich, weil man ein loaktives Signal hat oder man sagt, man hat ein Ennebel-Signal und dann kommt hinten wieder was dran. Es kollidiert ein bisschen. Ich bevorzuge eigentlich die Prifix-Nituation. Also, man wird sozusagen sagen, so das hat wie bei Input für ein I-Ander und in der Portnahme für ein Output ein O-Ander-Output. Vorne dran stürzt nicht hinten dran. Man kann immer das loaktiv Konventionen auch so ein bisschen. Also, I.O. hatte ich jetzt eben schon. I.O. für Bidi. Es gibt auch Signale, die rein und raus gehen können. Gleichzeitig. Also, auf dem Schipp eher, auf der Außengrenze, per Seite. Es gibt auch Signale, die außerhalb oder nach draußen hin heirkt Tristed sein können. Tristed ist, wie soll ich es erklären? Also, einmal kann man sich vorstellen, es treibt einen niedrigen Pigel oder einen hohen Pigel oder einen schlotenen Zustand, wenn sozusagen gar nichts getrieben wird und der Ausgang irgendwo hingeht. Also, hochohmig ist. Wenn man so eine bestimmte Eigenschaft auf dem Signal hat, sollte man das irgendwie auch mit einem Namen um die Kennzeichen reinsehen. Dann guckt man gleich wieder genauer hin. Das auch immer alles richtig macht. Eine Konvention hier auch noch, wenn man Weihersort, also einfach nur Drähte, benutze ich ein W vorne dran, intern, ist eigentlich nachvollziehbar. Es gibt doch Leute, die machen bei VHDL immer ein S vorne dran, für Signal. Nur da zieht man den Unterschied nicht so schön, ob das sozusagen ein Speicherverhalten drauf hat, also registrat ist oder nur ein ganz normales Weihhandel. Das ist in meinen Augen nach deinem VHDL. Bei Parameter, also diese sozusagen von draußen reinkommen können ins Modul, Konfigurierber sind, kann man auch ein Peter vorschreiben. Bei Loggepaarung, die konstant sind, sozusagen intern, kann man C davor schreiben. Gibt auch welche, die machen es also wie bei C, die fangen ja dann alles groß zu schreiben. Das Großschreiben lasse ich eher so bei den Defines. Okay. Noch ein wichtiger Punkt, bei den ganzen Sachen hier, Signalnamen, Verilog ist keessensitiv, im Gegensatz zu VHDL. Also wenn man da irgendwelche Bezeichnungen groß und klein schreibt, sind die unterschiedlich. Aber man sollte trotzdem aufpassen oder seine Tools kennen. Weil es gibt Tools, die einfach mal unter der Haube ohne ein Wörtchen darüber zu verlieren, alles nach groß oder nach klein konvertieren. Und dann passt es plötzlich nicht. Gibt es irgendwelche Konflikte mit irgendwelchen Signal, die plötzlich gleich geworden sind? Deswegen hässlich. Keessensitiv sollte man wissen und nicht benutzen. Okay, und jetzt kommen wir auf die Heavy-Stuff. Da können wir uns glaube ich noch ein wenig aufhören. Finestate Machines. Schon mal jemand davon ausgehört? Okay. Fangen wir nicht bei null an. Also Wikipedia. Erster Schritt. Lehrbücher gibt es ohne Ende. Guckt es euch an. Finestate Machines ist eigentlich so das Mittel der Wahl bei der Hardware-Entwicklung. Also es ist so wie von wegen, sieht jedes Problem aus wie nagell. Wir haben wirklich Finestate Machines. Damit können wir fast alles erschlagen. Sie sind sehr, sehr universell, sehr mächtig und erst mal angefangen hat, sich zu verstehen und damit cool zu schreiben, kann es passieren, dass jedes Modul irgendwie das Finestate-Machine enthält und diese ganzen anderen, diese ganze Krepi-Logik irgendwie man weglässt. Deswegen meine ganz heiße Empfehlung ist das Lernen. Es gibt zwei Finestate-Maschinen also zwei Prinzipien. Das eine nennt sich Mo und das andere Mili. Nach den beiden Leuten, die sich damit auseinander gesetzt haben. Ich bevorzuge Mo kommen wir vielleicht noch dazu. Okay. Best practice. Also wenn man sozusagen sowas schreiben kann, dass es danach auch lesbar ist. Also ich auch über die vielen Jahre immer wieder gesehen habe bei Finestate Machines, die sich richtig schön hässlich schreiben. Also da ist sozusagen die Möglichkeiten sind grenzenlos. Lesbaren Code zu schreiben ist schon eine Herausforderung. Man sollte sozusagen wissen wie man es macht. Aber beim Best Practice das einfachste wirklich straight forward unterschreiben, lesbaren Code geschalten ist so ne 3-Prozess-Geschichte. Also wir schreiben den ganzen Automaten in 3 Prozessen. Der erste Prozess ist kombinatorisch. Und da machen wir nichts anderes als den Next-State ausrechnen. Einfach mal nachgucken, was müsste jetzt anhand dem State, den wir im Augenblick haben also Q und State, was müsste sozusagen der nächste sein. Gucken wir auf die Eingänge und sagen, das ist unser Übergang. Der zweite Prozess, den wir haben, ist registrat. Das ist sozusagen das Speicherverhalten. Da merkt er sich in welchem State und übernimmt sozusagen das, was vom Next-State reinkommt als nächsten State-Zustand, wenn man so schön sagen kann. Und der dritte davon, okay, dritten kann man sagen 3 plus plus. Das können wirklich viele werden. Aber das ist so die Dependency. Also alles das, was davon abhängt. Wenn man jetzt nochmal in Mur zurückdenkt, Mur sagt, der Ausgang von dem Finestate-Machine hängt nur von dessen Zustand ab. Mini sagt, es kann vom Zustand abhängig sein und vom Eingang gleichzeitig. Das ist ein bisschen hässlich. Da macht man sich das Timing kaputt, wenn man nicht haben, Mur geht schneller. Kriegt man wesentlich schneller, sind diese also auf höhere Frequenzen gedacht. Ist auch einfacher zu lesen. Also Mur merkt es euch. Und 3 plus plus hat ich gesagt, wenn man sozusagen diesen Prozess einen einzelnen Ausgang beantwiegen, wenn man lustig ist, selber einzeln schreiben kann. Also nicht alle Ausgänge in ein Prozess reinschreiben. Man kann dafür beliebig viele machen. Aber die gucken alle nur nach dem Queue-Instate. Okay. Da nochmal dahin was, Mur performs besser. Sogar mit Wikipedia-Eintrack. Okay. Wie sieht jetzt sowas aus? Den Next-State. Also ganz am Anfang. Gibt es auch wieder so ein paar Sachen, fangen wir damit an. Die erste Variante ist hässlich. Geht mal hin und benutzt die Defines. Defines, wie bei C kann man Konstantin definieren. Aber, wenn sich das so Defines gelten, so lange, vom ersten Auftreten an, bis zu einem Augenblick wo der Code endet, also sozusagen den ganzen Daten, was es durch ist, oder bis die irgendwann an Defines sehen. Bei Synthese von irgendwelchen Ships sind wir nicht unbedingt auf die Reihenfolge angewiesen. In welcher jetzt irgendwelche Files gelesen werden müssen. Also wir sind die Tools Club genug. Also wir haben sozusagen ein stochastisches Element drin, in welcher Reihenfolge da was gelesen wird. Deswegen wissen wir nie, wo unsere Defines, die wir gemacht haben, in welchem Code die landen. Wenn wir einen Namenskonflikt haben, haben wir einen Pech. Oder wir kriegen irgendwelche anderen rein mit einem Namenskonflikt. Also kann man so machen, oder sollte man nicht so machen, vermeiden. Okay. Und was hier noch so in Geschichte ist, da sind die Stades einmal nur durchnummeriert. Von wegen State 0, State 1, State 2 ist nicht jetzt unbedingt lesbarer Code. Geht sicherlich besser. Also mein Hinweis dazu, bitte Defines in State Machines vermeiden. Wenn man das besser machen will, nutzt man die Local Params. Aber der Local Params in dieser Geschichte wäre ja noch 2001. Die 95 kannte das noch nicht. Und die habe ich auch so. Ich habe hier ein S vorne dran. Den weiß ich, das ist für mich ein State. Ich habe den State auch auf einen nünftigen Namen gegeben. Was da passiert. Sehe ich am Namen schon oder kriege vom Namen her schon eine Vorstellung, was ich damit machen möchte. Jetzt ist es so diese Durchnummerierung hier hinten. Die ist sozusagen, wie Lachs sagen will, völlig wurscht. Es muss nur eindeutig sein. Ich kann Buchstaben reinnehmen, ich kann Strings reinnehmen, ich kann Zahlen reinnehmen. Es ist völlig wurscht. Die Tools sind so weit in der Lage, dass sie sich derselbe auseinander klamüsen und die beste Lösung dafür finden. Man kann ihnen vielleicht noch ein bisschen auf die Sprünge helfen, muss man aber nicht. Das habe ich hier zum Beispiel OneHot benutzt. Die Frage? Was jetzt die beste Kodierung ist dazu, hätte ich dann aber auch schon noch mal eine Meinung als Designer. Also jetzt zum Beispiel OneHot oder welche Hamming Distance ich eben haben möchte zwischen meinen States oder ob ich irgendwelche Sachen haben möchte. Das muss ich dem Tool ja dann irgendwie mitteilen. Heißt das im Endeffekt, dass mir jetzt ein Veriloc synthesizer hier hinten die Kodierung dann nochmal neu machen würde? Veriloc oder andersum für FPGAs ist es definitiv so. FPGA Tools scheißen drauf, was du für eine Kodierung geben hast. Man sieht es irgendwann später in den ganzen Durchläufen, dass sie sagt, ich habe jetzt von da nach da transferiert. Also von wegen dieses OneHot war mir zu blöd, ich habe jetzt doch Beinerie draus gemacht. Das passiert immer wieder. Aber es ist wirklich so. Es ist völlig egal, man kann hier eigentlich auch Strings reinschreiben. Das ist zum Beispiel eine Sache, die ich auch öfters mal gesehen habe, wenn jemand W-Forms machen möchte, also W-Forms damit betrachten möchte und jetzt sozusagen so ein Automaten hat. Der sieht ja dann irgendwie bloß eine Kodierung da drinnen. Und das ist ein bisschen blöd, wenn man es nachvollziehen will in welchem Estate man sind. Man kann sozusagen irgendwie ein String reinmachen von wegen Eidl. Man kann ein String reinmachen ran. Und das sieht man dann auch in W-Form. Also OneHot hatten wir ja irgendwie schon warum OneHot. OneHot heißt, ich habe wenn ich irgendwie so mehrere States habe für jeden State immer alle bits in der Kodierung 0, nur eine einzige 1 drinnen. Dadurch, dass ich mich dann da verlassen kann, dass ich sozusagen nur eine 1 drinnen habe macht es mir ein Koding einfacher. Ich muss nicht mehr nach dem ganzen Bandel an States gucken. Also irgendwie so von wegen, sagen wir mal, 64 States. Ich müsste nie mehr über 64 solche Register gucken und das ausdiskutieren. Ah, jetzt habe ich den State. Und ich gucke nur noch nach diesem einen einzigen, der 1 ist. Damit habe ich diese ganze Kodierlogik weg und habe es mir viel, viel einfacher. Synthesitul hat sich das einfacher. Die Logik wird einfacher. Es geht aber auch andersherum. Also es geht auch nur zum Beispiel OneCold. Also dann kannst du sagen, alles einsetzen und dann irgendwie eine 0 setzt. Also, da kann man viele, viele Sachen Automaten schreiben. Okay. Also das ist jetzt hier so ein Beispiel, wenn man sozusagen die States, also die, sagen wir mal, diese Signale dazu beschreiben kann. Also, wie ich sage, geht ja immer vom Next State, also vom Nächsten und von dem Queue Rund. Queue Rund ist der aktuelle, den ich eigentlich haben will. Und eine Sache, wo ich euch hinweisen will, ist das da oben. Seht ihr das? Das ist ein Register dran. Ihr habt aber gesagt, Next State, da mit dem Wire, also W vorne dran ist eigentlich ein Wire, sprich eigentlich kombinatorisches Signal. Der Grund, warum ich jetzt aber hier ein Register hinschreiben muss, ist nämlich der da hinten. Ich will es in der Käsanweisung benutzen. Sehen wir nachher noch. Okay. Jetzt haben wir hier mal so eine Käsanweisung. Also ich habe jetzt zum Beispiel mal ein Signal, was wir mal in den Eingang darstellen die Bedingung, dass sozusagen der Automat von einem State zum anderen rumspringt. Ich habe da wieder das Astricks davor. Also ich nehme alle Sahlen. Ich spare mir den Ärgern mit der Sensivitelist und gucke beim Käse nur noch an Cure in State. Was ihr vielleicht auch sehen könnt, bei dem Orvis, es gibt kein Beginn und kein End. Das ist ein bisschen Faulheit, Träkhalt, sozusagen für mich zwei Zahlen eingespart, weil ich ja nur dieses Käse drin habe. Das Käse wirkt im Fall wie ein Beginnend, wie so eine Loop drumherum oder eine Klammer dafür. Okay. Also Cure in State gucke ich mehr an. Hatten wir da oben definiert, wieder in der Art und Weise mit dem Cooling Style. Und sage, wenn ich jetzt in IDLE bin und kriege das Enable Signal, dann ist der nächste State mal noch an State. Also soll irgendwas passieren. Wenn nicht, soll er in dem State bleiben. Jetzt noch einen kleinen Trick, den wir vielleicht noch gar nicht sehen. Wenn ich jetzt reinschreiben würde, Next State, würde wieder dieses SI dahinten stehen oder hinschreiben würde. Jetzt formal genau das Gleiche. Ändere ich aber später irgendwie mal meine State-Namen Stolperig da drüber. Oder es verschiebt sich irgendwas. Ich mache irgendwelche Änderungen dran und dann pinke ich mir selber ins Bein. Der Trick dazu ist, wenn ich sage, ich will ein Hole machen, also wirklich in dem State bleiben, ich weise einfach den Queue in State zu. Und damit kann ich diese Anweisung überall in meinen Käse verschieben, kann umsortieren und das Hole bleibt ein Hold. Und jetzt haben wir es hier so, also dieses Enable benutze ich als Start Condition. Da ist wieder auch der Trick drin, den wir im Workshop hatten von wegen, dass dieses Signal als Wahrheitswert interpretiert wird. Und beim One ist es so, habe ich hier einen Ausrufezeichen davor. Das ist ein Wahrheitswert, wieder invertieren. Da mache ich sozusagen ein Hold, ich gucke hier nach dem Hold, nach der Stop Condition. Also wenn sozusagen mein Enable aufhören würde, dann soll der nächste dann sein. Das Hold ist auch wieder hier mit Queue in State definiert. Da haben wir das dann von wegen alles fertig. So sieht im Regelfall ein Automat aus. Also er hat irgendeine Start-Bedingung, von wegen Nutzer drückt irgendwelche Taste, denn der Automat gibt die mal ein Geld, Bargeld, der kauft seine Fahrkarte, am Ende ist er fertig, geht nach dann, sagt Danke für den Fisch, fängt wieder von vorne an und wartet auf den nächsten Kunden. Genauso funktioniert unser Automat. Also wie gesagt, Automaten sind eine ganz mächtige Waffe. Und ich habe jetzt hier noch eine Sache drin, das ist diese Default. Das schreibe ich irgendwie schon routinemäßig hin. Wenn ich jetzt hier Steels habe, die vielleicht nicht völlig auskodiert sind, da oben 4 definiert. Passiert es mir, dass ich hier an der Stelle irgendwie so eine Situation komme, in dem Fall wüsste ich gar nicht, was ich da machen soll und nimmt ein Speicherverhalten an. Sprich erbaut mir ein Letch rein. Ich will aber gar kein Letch haben für Next State. Ich will, dass er wirklich rein Kombinatorsch macht. Also sag ich dem, wenn Default irgendwas passiert, dann soll er mir nach Eidl gehen. Und damit ist immer definiert, was der Defaultfall ist und was er machen soll, um so wirklich ausdekodieren zu können. Okay. Und da haben wir hier noch den Hinweis drauf. Für dieses Käster, um dem Next State in diesem Käst behandeln zu können, muss ich, wo haben wir es, da oben das Register schalten. Ansonsten kriegt er eine Warnung. Kriegt er sofort um die Ohren gehauen. Okay. Diese Next State, also noch mal auf den Automatenzug zu kommen, macht ja nichts anderes, als sozusagen auf den Q&S State zu gucken und auf Eingänger. Was wir beim Ausgang damit machen, ist erst mal völlig wurscht. Wir gucken nur auf Eingänger. Merkt es euch. Der Q&S State dazu, der wird sogar noch einfacher. Die Käseanweisung ist hier vielleicht noch übersichtlich. Die können wir auch noch ausufern. Das ist hier unten. Bleibt einfach. Eigentlich machen wir nichts anderes, als wieder sozusagen, ja, Cooling sei egal. Aber drüber gucken. Wir haben den Idol als Set. Und da ist die interessante Sache drinne. Das heißt also, mit jedem Takt machen wir nichts anderes, als den Next State, dem Q&S State zuweisen. Das ist unser ganzes Speicherverhalten. Sollte sagen, für diese eine Zeile Coolt haben wir den ganzen anderen drum herumgeschrieben. Okay. Jetzt noch eine kleine Herausforderung. Kann ja passieren. Das machen wir mit dem Fahrkartenautomaten vor. Der Nister steht davor, kauft seine Fahrkarte. Irgendwann drückt er die Abbruch-Taste. Das kann in beliebigen Augenblick passieren. Wie wollt ihr jetzt damit umgehen mit so einem Automaten? Vorschläge, Ideen? Also, okay, hässlich erstmal da unten. Ihr müsst diese Ausnahme hier mal erstmal reingucken. Bevor ich irgendwie gucke, wie mein Automat richtig funktioniert, dann müssen wir gucken, wie er falsch funktioniert. Von wegen einer drückt die Abbruch-Taste. Und wenn ich das hier oben irgendwo vergesse, dann kann es passieren, dass der Automat im Auto Zustand ist, der drückt seinen Abbruch. Aber ich habe es da gerade vergessen. Das ist hässlich. Und deswegen besser da unten. Einfach zu sagen, okay, dieses baue ich ein. Und zwar da. Diese Zeile habe ich dabei. Komm mal, komm mal, komm mal. Ja, haben wir. Also da unten. Von wegen ich habe jetzt hier das Interab-Signal zusätzlich, das ist die ganze Endung dazu. Meine Acception. Und dann mache ich nichts anderes als nach Error springen. Um sozusagen irgendwelche Sachen da abzufangen oder sowas. Also ich kann aus jedem beliebigen State habe ich sozusagen die Möglichkeit eine höhere, priorisierte Eingabe Bedingung zu haben. Also wie zum Beispiel Abbruch wie ein Interab oder irgendwie sowas. Möchte ich da als erstes abfrägen meine Ausnahmen. Und wenn aber alles gut gegangen ist, dann ist es eigentlich okay, dann ist es da ganz normal Wertearbeiten. Und damit habe ich es geschafft, aus jedem beliebigen State, egal wo der ist, meinen Abbruch reinzubaste. Und ihr habt schön einfach einen Code. Das war bei den Sachen, was der Automat eigentlich mal so ein bisschen, wenn du ihn konstruiert. An Ausgängen wollen wir aber eigentlich versteuern und irgendwas verändern wir auch immer. Und dafür brauchen wir die Dependencies. Also die Output-Verjablen wollen wir in Abhängigkeit vom State verändern. Ich habe jetzt hier mal was ganz einfaches geschrieben. Also ein Ausgang, er sagt nur, wenn der Automat läuft soll der Output auf 1 sein bei Default, also sprich wenn irgendwie es anders ist. Also Eidl hatten, wir, was hatten wir noch, dann hatten wir, man soll einfach auf 0 sein. By the way, die Konstruktion hatten wir im Workshop auch nicht. Da hatten wir mal nur mit Integer-Zahlen gearbeitet. Funktioniert hier auch das sagen mit D. Also ich sage die 1 ist sozusagen als Dezimal zu interpretieren. Das ist zwar völlig sinnlos in dem Fall, aber es geht. Also man kann es mit Hex machen, man kann es mit Benäher machen, man kann es mit Dezimal machen. Okay. So, dann habt ihr jetzt erstmal einen Eindruck davon, wie ein Automat geschrieben werden. 3 Prozesse. Den Next-Date, Keyroom-State, also Next-Date-Kombinatorisch, Keyroom-State-Registert und die Pendenzie. Die Pendenzie, wenn ihr hier reinguckt, der ist auch wieder eigentlich nur kombinatorisch. Ich brauche an der Stelle eigentlich kein Registert. Also es bringt mir nicht so ein ausgangsverhalten Registert davon ableiten. Gibt natürlich wieder Ausnahmen davon. Manchmal kann es sinnvoll sein. Dann sage ich, ich will jetzt irgendwie ein Tockelflipflop haben. Das ist in dem State auf 1 Tockeln und die anderen wieder zurück oder sowas. Dann kann es sinnvoll sein. Aber ansonsten, um irgendwelche solche Sachen zu machen, brauche ich es nicht. Okay. Jetzt wird es haarig. Da geht es weiter. Clock Domain Crossing. Das kann man so ein bisschen fischfeaturen, also von Veriloc. Jetzt kann man ja so eine Schaltungstechnik. Ich habe hier ein Stückchen Code, ein bisschen länger geworden und ich habe hier dazu Asciart. Asciart, und wir sagen mindestens seit 15 Jahren immer wieder. Einfach aus dem einfachen Grund, wenn jemand einen Quellcode guckt hat er meistens die Dekor nicht gelesen. Oder hat sie nicht daneben liegen oder wie auch immer. Oder ich müsste mir die auf ein Doppel machen. Also mache ich sozusagen schaltungstechnische Details die vielleicht ein bisschen haariger zu verstehen sind beim ersten Mal draufgucken, beim zweiten Mal. Nur wie erst mal länger drauf stehen muss. Die male ich ganz gerne in Asciart dazwischen. Und hier habe ich so ein Stückchen für das da oben. Also ihr könnt euch jetzt hier unten Asciart angucken und könnt mal gucken, ob ihr ein bisschen Code da oben mitschen kriegt. Gebe ich auch mal ein paar Minuten. Also die Leute aus dem Workshop haben es vielleicht einfacher. Die Zeile hier. Also hier oben, wieder wie wir es alles gehabt haben, wie wir es definiert. Diese Zeile hier mit den geschweiften Klammern. Da war was, die Concatenation. Stiftregister. Gibt es in der Virtual Box ein kleines Beispiel. Aber eigentlich, was ich mache ist diese Signal schiebe ich wieder sozusagen in diese Schriftregister rein. Also da kommt es. Diese Schriftregister ist sozusagen da geht es nur bis zu 1, nicht bis zu 0, obwohl es da oben bis zu 0 definiert worden ist. Also ein bisschen schmaler. Sozusagen diese 3 Register hier. Flipflops. Schneid jetzt sozusagen das Unterstab und hängt es davor. Und es ist genau diese Schieberregister verhalten. Warum baue ich das? Wenn ich Signale habe, die von draußen kommen. Vom Pet zum Beispiel. Ganz beliebt. Die aus einer anderen Clockdomänen kommen. Also wo ich sozusagen weiß, dass die zu meiner Clock nicht synchron sind. Die muss ich ein synchronisieren. Sonst komme ich wirklich in Teufels Küche. Weil ich nie garantieren kann zu welchem Zeitpunkt diese Signale sich ändern. Machen sie direkt kurz vor der Flanke, erwische ich es noch oder erwsche ich es nicht mehr. Die Flipflops haben immer so ein bisschen so ganz beliebt Setup and Hold Violations. Wir sind solche Geschichten von wegen bis wann darf sich vor der Flanke noch ein Signal ändern. Ab wann darf sich es wieder nach einer Flanke ändern. Um solchen Ärger zu vermeiden ein synchronisieren. Kriegt man eigentlich an der Uni immer wieder gesagt. Ich habe es jetzt hier so gemacht dass das sogar ein bisschen generisch ist. Weil der eine sagt, ich will aber mindestens zweimal ein synchronisieren. Andere sagt mindestens 3 Mal. Damit man das sozusagen ändern kann gibt es da oben diesen Parameter. Das ist kein Local Parameter, das ist Parameter. Das heißt also ich kann für jedes Modul immer von außen sagen, bitte schön in dieser Stufe 3 Mal. Wenn ich dann irgendwie eine Policy habe, wenn das meinen Chef sagt, ich will jetzt aber für den ganzen Schiff 3 Mal gebe ich ja noch was zur Stelle, propagiert durch, weil ich es entsprechend so gemacht habe und seit überall gleich ein synchronisieren. Der Grund, worum man es macht, da steht da unten auch, könnte ich auch mit auseinandersetzen. Das ist ein ganz zeigliches Thema. Metastabilität. Kloktoming Crosschen ist ganz wichtig. Also wirklich merkt es euch, wenn ihr irgendwie Signal habt, die aus einer Kloktoming kommen, in eine andere reingehen und wenn es ein Handshake-Signal ist ein synchronisieren. Zum Beispiel auch auf dem ESIC. Stellt euch mal vor, ihr macht einen Block, der wird ein bisschen größer und der Layouter sagt, ich will gerne diesen Block einzeln layouten, weil ihm das das Leben umwie einfacher macht. Danach hat er sozusagen so ein Stückchen layout, das packt er dann auf den Schiff daneben und hat vielleicht umwie mehrere von diesen Blöcken. Untereinander die Signale. Die laufen zwar vielleicht offiziell theoretisch mit der gleichen Klok, aber dadurch, dass die Distanzen so groß sind, müssen die Signale alle als Asynchron betrachtet werden. Das heißt also, wenn ich sozusagen so ein Signal habe, was von Block A nach Block B geht und einfach so eine lange Distanz überwinden muss, ist einfach die Policy ich muss es einzeln synchronisieren. Das heißt also, nächste Block rein und ich habe dann irgendwo wieder so eine Konstruktion drin einzeln synchronisieren. Also das taugt immer wieder auf, angucken, angucken, lernen. Jetzt können wir zu so einem Punkt und ich sage, ihr sollt alles einzeln synchronisieren, aber was passiert? Oder sagen wir so, diese Mechanismus hier funktioniert nur wenn ich Signale habe, die sich langsam als meine Klok ändern. Also richtig schön langsam. Typischer Fall, zum Beispiel hier ein Nutzer drückt ein Knopf, der Knopf prält, aber das Signal selber ist natürlich langsamer als meine Klok auf dem Ship. Dafür funktioniert es. Wenn ich jetzt aber sozusagen mit den Änderungen irgendwie in die Nähe komme, sagen wir so 3, 4 mal, irgendwie so was gerade mal, langsamer als meine Klok, dann wird es schon schwierig und ich will mir andere Sachen einfallen lassen. Oder ich habe Signale, die aus einer ähnlichen Klokfrequenz kommen, die dann plötzlich irgendwie rüber synchronisiert werden müssen. Dafür gibt es ein bisschen Tricks. Also hier, das einfache Ding 3 mal abtasten, funktioniert. Aber ihr müsst aufpassen, dass die Signale hier sich nicht zu schnell ändern. Okay. Jetzt haben wir gar kein Code mehr. Das haben wir nur noch ASCII-Art. Das ist ja ein bisschen zu lang. Aber das ist so eine Geschichte, die muss ich auch irgendwann wieder neuen Designern, oder Designern, die mir über den Weg laufen, erst mal beibringen, irgendwie vermisst die Uni da was. Wenn ihr Signale habt, die zum Beispiel so pulsförmig sind, hier, also diese eine W-Form hier, ist das Signal. Für einen Takt habt ihr eine Aktivität drauf. Das könnt ihr nicht mal so eben in der andere Klok rüber synchronisieren. Ihr müsst es erwischen. Aber ihr habt keine Garantie, dass es erwischt. Wenn es einfach nur abtaktet. Kann gut gehen, muss nicht. Jedes Mal muss nicht. Das bedeutet für euch auch, dass der Ship irgendwo im Ende in einem Zustand landet. Der vielleicht so nicht vorgesehen war. Irgendwie so was wie jetzt müssen wir mal so Set Pullen heißt. Also richtig machen. Aber wie kriegen wir das hin? Wie machen wir aus einem kleinen Signal an einer Klokdomäne? Was nur für einen Takt aktiv ist. Wie machen wir daraus wieder ein ordentliches Signal an einen anderen Klokdomänen? Und der Trick ist dabei, wir verschaffen uns mehr Zeit. Hier haben wir ja nur einen Takt ums zu erwischen. Wenn wir dieses Signal hier, aber dazu benutzen einen Flipflop zu tockeln, nämlich das da, steht ein T dran. Sprich dieses Flipflop jedes Mal, wenn ein Event reinkommt, kippt das einfach nur einen Ausgang. Dann haben wir nämlich sich die ganze Zeit zwischen zwei Events da für Zeit, das Ding einzusynchronisieren. Seht ihr es? Okay. Jetzt haben wir aber hier gesagt, wir haben ja einen Puls. Wir wollen auch gerne wieder einen Puls da hinten rauskriegen. Das haben wir jetzt zum Einzigen synchronisieren. Ich habe jetzt hier mal die Klok dazu gemalt. Damit den Doppelten, das sind meine aktive Flanken. Wir haben hier diese Schieberegiste sozusagen gesehen, dass sich hier dieses Signal geändert hat. Es ist reinschieben und nach drei Mal kommen wir in die Situation, dass dieses XO da hinten, das plötzlich erkennt, dass da eine Flanke war. Weil nämlich die beiden Zustände vor dem Flipflop, nach dem Flipflop unterschiedlich sind. Und solange wir die unterschiedlich sind, nämlich genau für einen Takt, liefert uns das dieses da hinten auf die Flanke. So einfach kann die Welt sein. Das ist jetzt ein Trick, wie gesagt, der kommt nicht an der Uni. Das ist Schaltungstechnik, Schaltungdesign, guckt es euch an. Ich habe gefragt, ob die letzte Kurve dann hier ein XO ist, was letztendlich... Die letzte Kurve ist das XO, ja. Okay, das war jetzt ein Signal. Ja, Frage noch. Was stellt denn der zweite Impuls auf der ersten Leitung da? Also ich war jetzt mal frech. Ich habe mir einfach gesagt hier, das ist mein Eingangssignal. Den da synchronisier ich ein. Und es kann aber passieren, dass hier hinten schon wieder ein nächstes Impuls kommt. Und der zweite Impuls sorgt aber dafür, dass sozusagen dieses Tockeflipflop da mit dieser Clockbounderie einfach wieder zurücktockelt. Es gibt sozusagen das zweite Mal. Das ist die Darstellung hier. Das sehe ich jetzt hier unten beim Einsynchronisieren nicht mehr. Das würde hier hinten irgendwo sein. Noch eine Frage. Das ist allerdings jetzt Trostzimpf. Sind die Ereignisse so kurz nacheinander, dass auch das Tockelsignal hinten bereits ein Pikart der kürzer ist, als drei Clockflanken von der Ziel-Clock. Noch mal. Wo ist jetzt dein Problem? Die beiden Eingangssignalen... Also das hier, noch mal. Dieses Signal, weh-Outside, ist das hier. Genau. Das hier, Clockbounderie, also das Tockelnde ist die zweite Zeile. So, das hier ist die Clock. Also der Takt, der hier da auf der Innenseite reinkommt. Und das Letzte ist jetzt sozusagen das, was jetzt hier hinten am X rauskommt. Sie haben vorhin gesagt, dass so ein... quasi, wenn man so ein so ein Signal Einsynchronisieren will, dass man mindestens drei Clockflanken konstant braucht. Ja. Also in dem Fall wäre es so, wenn man es wirklich genau durchrechnet, denn hier würde sozusagen na, hier würde der der Puls machen in dem Augenblick, wo dann der hier vielleicht schon irgendwie anfängt, den nächsten Flanken, oder nach der nächsten Flange zu sehen. Ja. Aber es funktioniert trotzdem, die Tockelregiste haben wir noch zweimal ab. Also es funktioniert schon. Es ist jetzt ein bisschen vielleicht zu kompensiert für die ganze. Aber solche Sachen, also wie oft oder wie dicht die Folgen sind, das muss man mit Konstantins machen. Das ist dann auch wieder eine ganz hässliche Sache, sowas zu schreiben. Eine Frage. Noch zusätzlich, da wird ja nicht geguckt, ob das Konstant ist zwischendrin. Also wenn jetzt der W-Outside-Clock noch ein Tag früher, oder Tockel zum Beispiel, dann habe ich ja das Ausgangssignal zur gleichen Zeit. Und das nächste came dann halt auch vor. Ich sehe es nicht, nochmal. Wo ist das Problem? Wenn das zweite... Das Signal, ja. Litsch wie auch immer auf dem W-Outside. Früher kommt. Da habe ich ja auch noch ein zweites Signal, das ich erwarte bei XOR. Also das hier zu früh? Genau. Denn es ist zu dich dran, dann habe ich ein Problem, ja. Genau. Da wird ja nicht geguckt, ob es nicht verändert wird zwischendrin. Also es wird nicht auf Konstant gecheckt, es wird einfach nur gewartet. Also es ist wirklich so, man muss versuchen beim Konstrains. Also sozusagen, mit einem Synthesitul an, welche Abstände es einhalten soll. Und da muss man wirklich sagen, dreimal. Aber das ist eine verdammt heftige Geschichte, so was zu formulieren. Weil man muss ja wirklich nach der Clock gucken, nach der Clock gucken. Also ich habe bisher bei den Konstrains viele Konstruktionen gesehen, da sind wir vielleicht irgendwie zum Detail drin. Aber viele Konstru... aber keine, wie ich sagen könnte, die funktioniert unter allen Bedingungen. Also das ist irgendwie immer haarecht. Das ist meistens wirklich so, dass der Ingenieur sich darauf verlässt, Daumenwege müsste passen. Das ist hässlich an der Stelle. Aber Clock-Domain-Crossing, das ist ein Thema, da könnt ihr irgendwie Dissertation darüber schreiben, noch ein Löcher. Und ihr werdet sozusagen praktisch viele Lösungen finden, die schlechter sind als diese. Guckst euch diese an, die ist gut, die ist praktisch. Noch Fragen oder so was? Gut, kommen wir langsam zum Ende, glaube ich. Dieses Clock-Domain-Crossing ist ja im Prinzip schon ein sehr häufiges Thema, weil ich ja im Prinzip immer Inputs an einem FPGA habe. Haben typische FPGA-Chips heutzutage einfach solche Stages fix und fertig mit eingebaut? Nein, nein. Also was FPGAs machen, die machen ja das da oben bei Pads. Also von wegen von einer Pads, also ich kriege über ein Beinchen was rein, dreimal einsynchronisieren, muss ich selber machen. Ja, das ist stabil. Aber intern auf dem FPGA, wenn ich damit verschiedenen Clock-Domains arbeite, macht das Tool solche Sachen nicht. Die muss ich selber einbauen. Das Tool versucht immer nur ein bisschen die Clocks so auszubalancieren, dass sie von der Wahrscheinlichkeit irgendwie gut geht. Das ist ja ein Entwicklungspraxis auf die Frage. Also es gibt keine speziellen Clock-Crossing-Units oder Slices oder sowas auf dem FPGA. Es gibt aber Modi, in denen man die typischen FPGA-Lutz betreiben kann, so FIFO-Modis oder auch delizierte Dual-Port-Fifos auf dem FPGA, die einem das Bauen von Clock-Crossings etwas erleichtern und eleganter machen. Also ich habe zwei Punkte dann auf der Agenda, nämlich diese Schaltung hier, die hat auch eine Reset-Spec. Also eine Geschichte, wo es schief geht. Wir hatten ja ganz oben mal drüber gesprochen, Reset beim ESIC. Beim ESIC wollen wir immer ein Reset haben. Wenn ihr jetzt sehr scharf hinkuckt, könnt ihr sagen, ok, ich habe es weggelassen, weil ich Frau bin, es ist kein Reset dran. In dem Fall habe ich wirklich absichtlich weggelassen, um sozusagen euch die Sache einfach zu machen. Weil, wir müssen uns ja vorstellen, wir haben einen Clock-Domain und wir hätten eine Reset auf diese anderen Clock-Domain. Und jetzt wird eine Seite von diesen beiden irgendwann mal ein Reset ziehen. Und wir haben sozusagen die A-Karte gezogen. Warum? Wir benutzen hier ein Tockeflipflop und hier unten steht es ein bisschen noch so drinnen. Also wenn dieses Tockeflipflop gerade auf 1 steht, auf High und der Reset auf Tritt beim Wingen auf der linken Seite würde das von 1 wieder auf 0 zurückgehen. Damit würde sozusagen hier eine Flanke generiert werden, die von dieser Seite wieder als gültig anerkannt wird. Anderer Fall, Tockeflipflop auf 1, wir ziehen hier ein Reset. Ja, passiert ja erstmal nichts. Der Reset sich zurück. So, irgendwann wird der aber wieder aktiv und stellt plötzlich fest, Mensch, da vorne kommt ja eine 1 rein. Mist, wir haben wieder ein Geisterimpulz generiert. Also beide Fälle, egal von welcher Seite wir ein Reset reinkriegen, wir generieren uns ein Geisterimpulz wenn der Tockeflipflop auf 1 steht. Deswegen diese Schaltung für FPGAs, sag ich kompromiss, das könnt ihr benutzen. Bei ESIX müsst ihr nochmal drüber nachdenken. Ob ihr vielleicht an der Stelle nicht irgendwie eine Seite mit einem Reset sparen könnt. Aber eigentlich die Regel ist wirklich so, zu jeder Glockdomäne gibt es ein eigenes Reset. Damit war wieder synchron sein können. Oder wir haben halt ein asynchrones Reset, dann ist es wurscht. Und was noch so kam jetzt hier mit dem FPG-Altepunkt, wir haben ja hier mit einem einzelnen Signal gespielt. Wir reden hier nicht über Busse, wir reden nicht über Größe, Bitbreiten oder wie auch immer. Dafür gibt es beim FPG-Altepunkt wirklich sowas wie Dual Ported Wamps. Also wirklich Speicherzellen, die zwei Ports haben von beiden Seiten und die so gebaut sind, dass sie auch über Glockdomänes hinweg gehen können. Also ich kann eine Seite mit einer Glock A treiben und andere Seite mit Glock B. Die sind wirklich so gemacht, dass die intern funktionieren. Und wenn du sowas habt auf dem FPG-Altepunkt Busse, dann wirklich die ganz heiße Empfehlung nehmt diese Dual Ported Wamps, machst du den Pfeil vor draus. Das ist das Einfachste. Aber wenn ihr irgendwie Handshake-Signale dazu habt, ist das das Mittel der Wahl. Da hinten irgendwie war jetzt noch was. Wobei, was ich mal hatte, dass halt diese FIFOS dann auch kaputt gehen können, wenn man halt irgendwie Glockclitches oder sowas hatte und also zum Beispiel bei Altera die benutzen halt ein Gray Counter und wenn man da halt ein Glockclitch hat, dann passiert es halt, dass der plötzlich rückwärts zählt und das kann man dann beim FPG-Alt damit verhindern, dass man halt einfach ein PLL da vorbaut oder so, dann funktioniert's wieder. Aber da muss man auch schon ein bisschen aufpassen. Ja, also Gray Counter ist eine Möglichkeit, wie man sozusagen eben zum Dual Ported Wamp machen muss, dass die Pointer von beiden Seiten, die sozusagen auf die Speicherzählen, Gray encondiert werden, also Bené hat man sozusagen immer wieder ein Bitt ändern. Da kann sich ein Bitt ändern, kann sich zwei ändern, kann sich billig wie ich ändern. Und beim Gray Counter ist es so, dass eigentlich definiert es zwischen einer, also plus eins oder sowas, also eine kleine Änderung, eine Adresse hoch oder runter, ändert sich immer nur ein Bitt. Das ist sozusagen einfach zu dediktieren, ob es sozusagen da oben, wenn Fehler passiert ist oder sowas. Oder wenn Fehler passiert ist, das entspringt der Counter halt weiter, das passiert erstmal nichts von der Logik. Das ist eine gute Lösung. Man hat, ist mir noch nicht unterengelaufen. Nee, ich meine jetzt bei der Logik, man muss halt irgendwie filtern. Also wenn man jetzt irgendwie eine Externe Glocke hat, dann gibt die direkt auf so ein Vifo drauf, das kann schief gehen. Also was ich euch an der Stelle empfehlen kann, manchmal sieht sie aus, ja, viele Glocke Domains, gerade in Mobilfunk ist so ein Kandidat dafür, wo man sozusagen irgendwie so mit 20, 30 oder sowas Glocke Domains zu tun hat auf einem Schip. Es wäre wirklich einfacher, oder er macht euch das Leben einfacher, wenn ihr irgendwo versucht, die Anzahl der Glocke Domains zu reduzieren. Und damit auch die Übergänge. Weil wenn ihr zu viele habt, ihr vergesst irgendwann irgendwo aus Versehen mal sowas. Weil ihr müsstet ja wirklich wissen zu jedem Signal, aus welcher Glocke Domain kommt und in welche Glocke Domain gehts. Also sowas zu überprüfen, gibt's zwei nette Tools dafür, die sehr, sehr viel Geld kosten, die man sozusagen so als kleiner Bastler nicht hat. Okay. Jetzt haben wir es kurz vor 6, 4 Stunden. Hätte ich noch Fragen, Antworten, ansonsten sind wir durch. Eine Anmerkung uns war, vorhin wurde halt ständig in Bayern benutzt, auch im Always Block. Bei ja was zugewiesen. Und das funktioniert halt nicht immer. Da muss man halt teilweise ein Register verwenden, also in Veriloc und halt ein Register muss halt nicht immer clogged sein. Das ist halt wieder so eine Person von Veriloc. Das ist das, also die Problematik hatte ich drin, aber die betrifft wirklich explizit das Case. Bei anderen Signalen funktioniert's. Manchmal kommt auf die Toolchain drauf an. Manche Toolchains mögen es nicht. Also zum Beispiel Altera Toolchain mag es nicht. Altera habe ich lange nicht mehr gehabt. Ja, also das sollte man aufpassen oder halt gleich also Veriloc und so weiter. Aber das Beispiel mit dem Case hat das gesehen. Das Typische, wo es wirklich immer wieder auftaucht. Aber ich habe es gerade mal explizit mit Altera gecheckt. Es verwenden da wirklich als Definition für eigentlich ein Wire. Aber vor allem hat nicht irgendwie clogged ist. Also dann wäre an der Stelle auch nochmal interessant, wenn du irgendwie rumspielen willst, wie Josef das Hand habt und auch vielleicht der Icarus. Also der Icarus Veriloc, der Simulator. Das sind so die beiden freien Tools. Und für mich ist so, wenn ich einen Referenz oder einen Referenz implementiere, gucke ich inzwischen nach dem Icarus. Da bin ich jetzt schon so lang auf der Mailingliste. Die haben wirklich für jedes einzelne Teil, haben die in Testkeys gemacht, die haben für jedes einzelne Teil durchdiskutiert, wie es im Standard drin steht, wie es richtig implementiert werden müsste und wie falsch es anderen machen. Also... Ich sage halt immer Veriloc und so weiter, das sind einfach furchtbar alt und so was nicht mehr machen. Also es gibt halt neuere Sachen, die sind dann halt konsistent und nicht so wie Veriloc, wo halt dann irgendwie ein Rack nicht irgendwie... Okay, aber das sind so kleine Floors, aber auf der anderen Seite sage ich dir, das zieht sich durch durch Veriloc. Also Veriloc ist wirklich an der Stelle die einzige Sprache, womit du mit freien Tools von vorne bis hinten durchkommst. Ja, das sage ich ja. Also aber dann benutzen man halt irgendwie andere Sprachen, um irgendwie nach Veriloc oder so was zu kopulieren. Denn wort man sich wieder in der Falle mehr ein. Ja. Okay. Und wie sonst noch Fragen, Anmerkungen? Nee, nichts mehr. Gut, dann vielen Dank euch fürs Zuhören, für die Geduld.