 Ich habe die große Freude und Ehre hier klippert und die Leute, die ihn kennen, vorzustellen. Seid gewarnt. Dieser Mann ist wie ein Hochgeschwindigkeitszug. Wenn wir den Startkopf drücken, dann wird er lospressend. Legt eure Sicherheitsgut an. Das ist mein Vortrag über formale Bestätigung von Mit-Joses-SMTBMC. Es ist eine abgekürzte Version, aber ich werde trotzdem schnell sprechen müssen. Wenn ihr euch für den kompletten Satz der Folien interessiert, dann geht bitte unten auf diesen Link. Von dort könnt ihr auch die ganzen Beispiel-Files runterladen. Mein Ziel ist es euch grobem Überblick zu geben, was man damit tun kann. Dann könnt ihr die Beispiel runterladen und damit das Ausprobieren. Ihr könnt die Beispiel-Files nehmen und an eure eigenen Bedürfnisse anpassen. Als erstes werde ich mal ein bisschen über Joses erzählen. Man kann ein bisschen mehr damit machen als formelle Verifikation durchführen. Man kann auch Synthetisierung durchführen. Letztes Jahr habe ich ein Talk dazu gegeben. Ich musste das Bitstream-Format dafür reverse-ingenieren. Hier muss man Xilinx verwenden. Es gibt noch ein paar Asic-Flows, die Joses unterstützt. Man kann seine persönlichen Synthesisierung-Flows derschein. Auf der Verifizierungsseite darüber reden wir heute. Aber es gibt auch noch ein paar andere Verifizierungs-Flows, die man in Joses durchführen kann. Joses hat einen eingebauten SAT-Löser. Man kann Joses als Frontend verwenden, mit dem man das Design in Formate anderer Tools übersetzt. Man kann also mit Joses andere Formate zur Verifikation an ABC übergeben. Ich werde erklären, wie ein begrenzter Check passieren kann. Ich nutze die S&T Bibliothek, damit kann das mit unterschiedlichen Solver kombiniert werden. Es gibt zwei Solver, die gut getestet sind. Es sollte eigentlich mit allen funktionieren, aber die zwei funktionieren am besten. Bevor wir in die Formale Verifikation einsteigen, erkläre ich hier mal, was daran besonders ist. Ich habe hier ein paar Ideen, wenn man diese Tools Studenten, Hobbyisten und Enthusiasten zur Verfügung stellt, was man machen kann. Man kann FPGAs synthetisieren und es gibt freie Tools, um das zu machen. Man kann die von Xilings oder von anderen Herstellern herstellen und in eine oder zwei Stunden, wenn man sie installiert hat, dann kann man damit auch selber was machen. Mit dieser FPGA-Synthese gibt es auch ein paar Open Source Optionen. Joses ist eine der Optionen. Es gibt auch noch andere Open Source Tools, WTR gibt es auch noch. Das gleiche gilt für HDL Simulation. Wenn man selber ein paar Erfahrungen damit sammeln will, diese Hardware Definition Language zu simulieren, dann kann man Xilings Excel nutzen. Es gibt auch freie Open Source Tools, um diese Simulation durchzuführen. Das kann man in ein paar Minuten installieren und dann kann man loslegen. Aber auf der Seite mit der formalen Bestätigung gibt es praktisch überhaupt nichts freies. Neben dem, was ich euch heute zeige, gibt es keine freien und Open Source Tools, die man dazu verwenden könnte. Die Leute in der Industrie beschweren sich, dass sie niemanden mit solchen Fähigkeiten einstellen können. Das sollte der Fokus sein. Ich kann jetzt nicht sagen, wie schnell meiner ist im Vergleich zu den kommerziellen. Ich habe keine Möglichkeit bis jetzt, dass mein Zeug zu vergleichen mit dem kommerziell verfügbaren Zeug. Ich habe ein bisschen Forschung an der Uni. Bei der formalen Bestätigung haben wir da nicht wirklich Zeugs da. Das spielt jetzt nicht so eine Rolle, ob meines schneller ist, als das kommerzielle oder genau die gleichen Features hat. Aber das Wichtige ist, es gibt jetzt all die Möglichkeiten, Erfahrung zusammen mit dieser Form von Technologie. Und hoffentlich kann ich das eines Tages meine Arbeit vergleichen mit den kommerziellen Tools. Dann werden wir wissen, ob meines besser ist oder die kommerziellen Tools oder ob die vergleichbar sind. Also, jetzt sprechen wir mal über Formale Verifizierung. Was heißt das genau? In fast allen Präsentationen über dieses Thema findet man eine Slide, die sieht etwa wie diese hier aus. Also, es hat ein paar Zustände, der Schaltkreis hat ein paar Zustände und dann gibt es Simulationspfade hier drauf. Also, ich weiß nicht, was das für eine Farbe ist, aber das ist so ein Simulationspfad, den man hier sieht. Ja, das hier. Das ist einer dieser Simulationspfade. Man sieht hier, hat es drei dieser Pfade und die decken einen Subset der erreichbaren Zustände ab. Und zum Beispiel, der Rote hier ist nicht abgedeckt und der verletzt eine Annahme. Also, und wenn wir den Schaltkreis testen, wollen wir wissen, dass dieser Rote Fall hier abgedeckt ist. Also, der sollte nicht erreichbar sein. Also, man könnte einfach mehr zufällige Simulationen stehen, um die Coverage zu verbessern. Aber wenn wir jetzt dieses Beispiel hier anschauen, dann sehen wir, es gibt nur genau einen möglichen Pfad, der zu diesem roten Zustand geht. Und einige sind da fast hingekommen, aber in letzter Minute sind sie anders abgebogen. Also, wenn jetzt man das Ganze multipliziert, also die Anzahl Möglichkeiten, die jeder Knoten hat, dann kann es sein, dass man hier zum Beispiel 1.000 Simulationspfade ausführt auf diesen kleinen Beispiel hier. Und trotzdem hätte man nun eine 50-prozentige Wahrscheinlichkeit, um zu diesem roten State zu kommen. Also, zufällige Simulation ist nicht wirklich eine gute Lösung, um sicherzustellen, ob ein ungültiger Zustand erreichbar ist oder nicht. Man braucht stattdessen formale Methoden. Also, und die schauen sich das ganze Zustandsdiagramm an als Ganzes. Also, gar jetzt nicht, um einzelne Pfade zu simulieren, sondern es gibt eine definitive Antwort, ob dieser rote Zustand erreichbar ist oder nicht in diesem Diagramm. Wenn man das Ganze halt simuliert, dann kann man ziemlich sicher sein oder sehr sicher sein, wenn man die Simulation mehr Stunden laufen lässt, aber komplett sicher kann man nur mit formaler Verifizierung sein. Also, ja, das sprechen wir jetzt, wenn wir über formale Verifizierung sprechen. Wieso, wieso werden wir das machen? Wieso wollen wir das? Praktisch immer, wenn formale Verifizierung verwendet wird, haben Sie den ersten Use Case hier. Die wollen beweisen, dass das korrekt ist, das Modell. Also, ja, das ist ein sehr guter Grund. Also, wenn man sicher ist, dass hier der einzige Weg, um das zu testen, um sicher zu sein. Also, um zu zeigen, ob das sein korrekt ist, ist es trotzdem noch ein ziemlich schwieriges Problem. Also, erst mal braucht man eine formale Spezifizierung des korrekten Verhaltens. Wenn man kein formales Verhaltensspezifiziert hat, wie soll denn das Tool wissen, was richtig ist und was nicht. Also, nur schon dieser eine Schritt, als die formale Spezifikation zu erstellen, ist unter Umständen schon ein Showstopper. Also, das kann alleine schon ein Projekt sein, das so groß ist, dass man es nicht machen will. In vielen Anwendungen geht das nicht. Also, ja, zum Teil geht es nicht in an gewissen Orten. Macht man das natürlich trotzdem, aber... Und sonst sagt man halt, wenn wir einen Bug finden, machen wir einfach einen neuen FPGA und lösen das Problem so. Aber es gibt natürlich große Anwendungsgebiete. Also, es gibt Backhunting und Formal Optimization. Normalerweise rede man über die zwei nicht so viel, weil das Problem ist, die Preise für die kommerziellen Tools dafür sind einfach viel zu hoch. Also, man kauft die nur, wenn man die wirklich wirklich kaufen muss. Und die einzigen Orte, wenn man das machen will, ist, wenn man den ersten Fall hat, wenn man beweisen muss, dass das Design korrekt ist. Also, viele Projekte werden davon profitieren von Verreffizierung, aber die machen es halt nicht, weil, ja, das ist bei denen gar nicht auf dem Radar. Also, was ist der Unterschied zwischen Backhunting und Beweisen, dass es korrekt ist? Für Backhunting macht man nur eine partielle Spezifikation. Also, es reicht, wenn man einen Teil des Schaltkreises spezifiziert und dann kann man prüfen, oh, wenigstens dieser Teil der Spezifikation eingehaltet wird. Und natürlich, die Teile, die nicht spezifiziert sind, kann man nicht prüfen, aber wenn diesem einen Teil der spezifiziert ist, ein Backhat in der Schaltung, dann ist es trotzdem nützlich. Das andere ist, wenn man nach Backs sucht, kann man viele verschiedene Checks machen mit verschiedenen sich überlappenden Teilspezifikationen. Und man braucht dann nur so ein sehr gutes Gefühl, dass die überlappenden Stücke etwa das Ganze abdecken. Aber wenn man beweisen will, dass etwas fehlerfrei ist, dann, und man würde dann gerne das aufteilen in Teilspezifikationen, dann braucht man separaten zweiten Beweis, dass man keine Teile ausgelassen hat mit den Partsteilspezifikationen. Also, es gibt Leute, die sagen, dass sie das erste machen, aber das machen sie nicht. Also, die lassen halt Dinge offen und dann ist es tatsächlich nur Backs finden. Oft finden sie sehr, sehr obskure, schwer zu finden in Backs. Also, solche Backs würde man normalerweise nie finden mit handgeschriebenen Testeinrichtungen. Also, weil niemand würde so etwas Komisches sich ausdecken, um eine Assertion zu verletzen. Also, man findet nicht nur Backs, man findet auch diese Backs, die sehr, sehr schwer zu finden sind in der Backsis. Also, zum Beispiel, wenn man ein Prozesse hat, der gut läuft und nach einem Jahr im Einsatz kommt jemand und sagt, da gibt es irgendwie ein Gimpplugin und wenn man dieses Binärdatei mit diesem Gimpplugin benötigt und das dann laufen lässt, dann stürzt irgendwie der Prozessor ab. Das sind dann so diese speziellen Backreports und da muss man herausfinden, wie kommt man von dieser Beschreibung zu diesem obskuren Back in deinem Instruktionscash, das jetzt genau in diesem Szenario ausgelöst wird. Aber wenn man den gleichen Back hier findet, dann gibt einem das Tool ein Beispiel. Also, das sagt einem dann, wenn man die Inputs des Schaltkreises so verwendet, dann geht es in diesen Zustand und dieser Zustand ist ein ungültiger Zustand. Also, man ist in viel besseren Ausgangslage, um rauszufinden, was da schiefläuft. Selbst wenn man den Back eigentlich in Hardware reproduzieren kann, ist man hier an einem komplett anderen Ausgangspunkt. Also, es ist angenehm, um so Backs zu handeln. Mit Optimierung, also man macht da im Wesentlichen das Gleiche, wie wenn man beweisen will, dass ein Design richtig ist, aber man nimmt einfach das unoptimierte Design als Spezifikation. Also, man hat ein Design, das funktioniert und dann sagt man, das ist, was wir haben wollen und wenn man etwas dann optimieren will, dann wird es in der Regel etwas kompliziert. Also, zum Beispiel, wenn man das Energiesparen da haben will, dann fügt man Clockgating hinzu und dann muss man halt sich entscheiden, welche Flipflop-Zustände können clockgated werden, in welchem Teil vom Zyklus und wenn es da ein Problem gibt, dann würde man es mit formaler Verifizierung zu finden, wenn man das Optimierte verifiziert mit Hilfe der Spezifikation des ursprünglichen Designs. Das ist eigentlich sehr, sehr ähnlich zu formaler Equivalent-Testung und bei der Optimierung ist es allerdings so, dass die Anzahl Entwicklungszyklen reduziert werden. Also, jetzt, ja, man hat dann ja die zwei Schaltkreise, die formal nicht Equivalent ist, das eine produzierte etwas, zum Beispiel ein Resultat, ein Zyklus früher, aber man kann immer noch einen formalen Beweis machen, indem man das berücksichtigt in der Methode der formalen Verifizierung. Ja, also, das hier werde ich jetzt nicht im Detail durchgehen. Das werde ich jetzt nur um euch zu zeigen, dass es sehr einfach ist, das zu installieren, also auf Ubuntu oder Debian oder anderen Distributionen. Also, es gibt wirklich keine Entschuldigung, das nicht auszuprobieren, wenn ihr bisher, ja, also, formale Verifizierung könnt ihr euch wirklich helfen und ihr müsst ja nicht nachmittag damit verbringen, Vortragcode aus den 70ern zu kompilieren. Also, ihr müsst einfach gewisse Pakete updaten, dann baut ihr Yosis und dann baut ihr einen SNMT-Solver und nach 20 Minuten oder je nachdem, wie schnell euer Computer ist, habt ihr dann alles installiert, damit ihr damit rumspielen könnt. Ja, also, der erste Link hier ist der gleiche Link, den ich euch schon gezeigt habe, das sind die Slides hier und ein paar Beispiel-Files. Einige Beispiel-Files, die interessant sind, sind in Examples slash SMTC, im Yosis Quellcode und wenn ihr mein Pico R2 kennt, das ist ein Risk 5 Implementation, da habt ihr einige formale Spezifikationen dazu, das könnt ihr auch anschauen, um noch weitere Beispiele zu haben und damit könnt ihr ja die formale Verifizierung ausprobieren. Also, springen wir mal da rein, ein bisschen Code. Also, das ist ein einfaches Hallo-Welt-Programm, wir haben einen Zähler, initialisieren den auf 0 und dann haben wir ein Blob mit einem Clock-Signal und wenn Reset High ist, dann wird der Zähler zurückgesetzt und wenn der Reset nicht High ist, dann wird der Counter Incremented, also erhöht. Und dann haben wir ein paar formale Aussagen hier am Ende. Also, wir nehmen an, dass der Counter nie 10 erreicht und dann assorten wir, dass der Counter nie 15 wird und wenn wir den Zähler immer um 1 erhöhen, können wir nie zu 15 kommen, wenn wir nie über 10 kommen können. Also, um das zu prüfen, führen wir diese drei Kommandos aus, die hier unten rechts sind. Das erste ist JOSES, also das ist für Synthese dieses Schaltkreises. Also, wir synthetisieren das nicht für ein FPG aus, sondern wir synthesieren ihn zu einem SMT2-Beschreibung dieses Schaltkreises. Dann benutzen wir SMTBMC, um zu prüfen, ob diese Assertions eingehalten werden. Da haben wir zwei Aufrufe. Das erste macht ein Bounded Model Check. Also, das heißt, wir prüfen, ob der Schaltkreis, ob diese ganzen Assertions eingehalten werden in den ersten Endzügeln, üblicherweise 20. Und das zweite probiert dann, von da aus einen Inuktionsschritt zu machen aus den ersten Endzügeln, sondern das, um zu zeigen, dass es in unendlich vielen Zügeln halt. Also, das, in der Regel, wollen wir das zeigen, dass es für immer hält. Aber natürlich in gewissen sehr komplizierten Beispielen kann es extrem lange gehen, also extrem kompliziert sein, zu prüfen. Also, ja, aber wenn man natürlich Bugs finden will, dann reicht mir vielleicht der Bounded Model Check für 100-Tag-Zügeln. Dann bin ich vielleicht schon zuversichtlich genug, dass das Teil läuft, wie es soll. Aufgrund meines Verständnisses des Designs weiß ich, dass in 100 Zügeln vielleicht eigentlich schon alle sinnvollen Zustände reicht werden sollten. Wenn man das jetzt laufen lässt, dann bekommt man diese Output hier. Der erste Teil ist der Output des Bounded Model Checks. Also, das sind diese Assertions, werden im Time Step 0 überprüft. Dann nach einem Übergang halten Sie im State 1 und so weiter bis State 19. Und das zweite ist der Induktionsschritt, der zählt rückwärts von 20. Und ist es sehr einfach, was zu prüfen bei Induktion. Dann versucht es, den Induktionsschritt effizienter zu machen und geht dann zurück und sagt dann, ja, okay, alles, irgendwann merkt es dann, okay, es konnte jetzt das feststellen, dass in der Induktionsschritt funktioniert, hier ging es bis 15 runter und dann sagt es, okay, es funktioniert. Also, wer hier kennt etwas Verilog? Okay, immerhin. Vielleicht etwa 30% oder so, das ist schon ziemlich gut. Okay, also für Formale Verifizierung braucht man gewisse zusätzliche Statements in der Verilogsprache. Man muss Assertions machen kann und man muss Assumptions machen kann, also Annahmen. Also, wir haben diese Statements schon gesehen in diesem Hello, Hello, World Beispiel. Also, wenn man Assert Ausdruck hat, dann heißt das, wir sagen, dieser Ausdruck muss immer wahr sein. Und wenn es ein Weg gibt, dass dieser Ausdruck false wird, dann ist das ein Pack und das Tool muss einem ein Weg zeigen, wie man da hinkommt. Dann Assume annehmen. Also, wenn wir sagen Assume, diese Aussage ist wahr, dann ist das nicht eine Eigenschaft des Designs, sondern das heißt, dass wir schränken den Beweis ein. Also, wir können zum Beispiel sagen, wir nehmen an, dieses Eingangssignal ist immer low. Oder zum Beispiel, diese beiden Inputsignal sind nie high gleichzeitig, weil das ist zum Beispiel etwas, das wir wissen, weil das Teil vom Protokoll ist und auf der anderen Seite ist ein anderes Endgerät, dass das Protokoll korrekt verwendet und in unserem Protokoll können die beiden Signale nie gleichzeitig ein sein. Dann Restrict macht nochmal in etwa das Gleiche. Das heißt, wir wollen gewisse Fahrdaymodelle gar nicht anschauen, wo eine bestimmte Bedingung false ist, sondern nur diese, wo diese Bedingung true ist. Aber die Umstände sind ein bisschen anders, wenn man Assume und dann Restrict verwendet. Also Assume, wenn man Assume verwendet, heißt das benötigen wir, wenn die Assertion abhängen davon, weil man eben aufgrund äußer Umstände was weiß. Weil wenn, ja, wenn zum Beispiel ich den Core geschrieben habe und der Annahme, dass dieses Protokoll eingehalten wird, dann ja, mit Restriction sagen wir aber stattdessen, wir machen den Beweis einfacher, wenn man das annehmen kann, aber es ist nicht eigentlich notwendig, das anzunehmen, damit die Assertions eingehalten werden. Also wenn eine Assumption nicht eingehalten wird, dann gibt es immer noch einen Fehler. Aber wenn Restriction verletzt wird, dann ist uns das egal, weil die Assertion nicht davon abhangen. Das ist einfach eine Zusatzinformation für die formale Verbeziehung, die den Beweis etwas einfacher macht. Es gibt sofortige und gleichlaufende Assertions. Sofortige können ja ein normales Statement verwendet werden und Assume wird in einem Modellkontext verwendet. Und Assume nimmt an, dass es immer überall genommen wird. Eine Mediat, das heißt also, das If-Statement, das wird nur zu dem Zeitpunkt verwendet. Das wird mit Vari-Lock-Properties verwendet, die joses unterstützt das nicht. Normalerweise würde man nur auf temporale anwenden. Wenn wir joses verwenden, dann werden wir normalerweise im Mediat verwenden. Formale Tests-Setze. Wir verwenden Eingangssignale für diese Schaltkreise. In der formalen Verifikation verwenden wir sowas auch, aber die gehen nicht durch einen Fahrt durch, sondern wir fügen äußere Einschränkungen hinzu. Zum Beispiel das Reset-Low-Sign im ersten Zyklus. Und ansonsten lassen wir viel freien Raum für die Simulation, alle Pferde zu erkunden. Hier ist das Beispiel von einer Test-Bench. Das ist eine Abwandlung von der vorherigen Design. Und hier nutzen wir eine formelle Test-Bench. Wir haben die Initialisierung für den Zähler entfernt. Und wenn Reset ist hoch, dann setzen wir den Counter auf 0. Und in der Test-Bench machen wir die Annahme, machen wir das Assume, dass das im ersten Zyklus high ist. Das heißt, wir machen ein Reset von außen. Und dann haben wir die gleiche Kombination von Annahmen, Assumptions und Assertions-Festlegungen wie bei dem anderen. Das heißt, im ersten Zustand im Initial-State ist uns das nicht so wichtig. Und nachdem der Reset fertig ist, dann werden die Annahmen angewandt. Ich habe gedacht, ich hätte dieses Land rausgenommen. Begrenzte und unbegrenzte Methoden, baundet und anbaundet. Eine begrenzte Methode geprüft in so und so vielen, in einer begrenzten Menge, in einer festgelegten Menge von Schritten, dass die Eigenschaft gewährleistet ist. Und in einem unbegrenzten Modellcheck, da wollen wir das beweisen, dass es für immer hält, für eine unbegrenzte Anzahl von Zyklen. BMC ist Bounded Model Check. Das ist ein Teil von diesem Namen, Joses SMT BMC. Und ist ein Teil von einem Namen. Im Temporal Induction ist etwas, das auf diesen Bounded Model Check aufbaut. Das heißt, das ist eine zeitliche Induktion und prüft das dann für immer. Hier ist der begrenzte Model Check, der Bounded Model Check. Wir haben also einen formalen Schaltkreis in unserem Tool beschrieben, auf der Oberen Seite, der Anfangszustand ist hier in Gelb und dann drei Zustände danach folgen. Und für jeden dieser Zustände prüfen wir, ob alle Annahmen auch tatsächlich halten. Das ist ein naiver Ansatz, um das zu machen. Das einzige, was der hier eingeschränkt hat, ist halt dieser Initialzustand und den Rest hat er nicht eingeschränkt. Das funktioniert, das ist auch korrekt. Das funktioniert auch, um ein Bounded Model Check für Endes gleich drei zu machen. In der Praxis ist der untere Teil des slides der richtige Weg. Wir haben einen symbolischen Anfangszustand gemacht. Und wir schauen, ob es irgend einen gibt, der meine Annahmen verletzt. Und wenn ich den gefunden habe, dann bin ich fertig. Das Tool möchte gerne einen Aufnahmezustand finden. Und wenn das für das Tool nicht funktioniert, dann geht das Tool her und baut einfach mal das Modell für zwei Zustände. Und wir können jetzt schon die Annahme machen, dass der erste ist sowieso schon richtig. Das heißt, wir brauchen den gar nicht prüfen, sondern wir brauchen nur noch die danach prüfen. Und so geht es dann weiter. Und wenn das erfolgreich durchgeprüft wurde, dann gehen wir zu drei Schritten. Und wenn das immer noch keinen Fehler gefunden hat, dann gehen wir weiter. Und das ist sehr viel effizienter in der Praxis als der naive Ansatz, in dem ich versuche, alles auf einmal zu prüfen. Insbesondere, wenn ich tiefe Bounded Model Checks mit so 100 Schritten machen möchte. Eine zeitliche Induktion, eine Temporal Induction nimmt das her und versucht, einen Beweis zu erstellen. Am Anfang sind wir dahergekommen. Es gibt einen Anfangszustand, gefolgt von drei Folgen zu schritten, die alle das nicht verletzen. Und jetzt wollen wir beweisen, wenn es drei Auffeinanderfolgende gibt, die nichts verletzen, dann wollen wir jetzt den Beweis erbringen, dass es darauf keinen Nachfolgeschritt gibt, der das verletzt. Und wenn wir das bewiesen haben, dann wissen wir auch, dass es für eine beliebige Zeit hält. Das heißt also, wenn wir die ersten drei bewiesen haben und daraus dann eine Ableitung beweisen können, dass es keine Verletzung im vierten Schritt gibt, dann werden wir diesen Ansatz immer wieder an und kommen so auf eine unbegrenzte Zeit. Wenn das funktioniert und das Design sieht gut aus, dann funktioniert das ausgezeichnet. Aber vielleicht finden wir ein Gegenbeispiel. Wenn das Gegenbeispiel kann sein, vielleicht habe ich ein Problem, es ist ein bisschen tiefer, oder es kann sein, es ist alles kein Problem, aber vielleicht brauche ich keine drei Schritte, sondern zehn oder hundert. Und das ist, was ich hier in diesem Beispiel sehe. Hier haben wir die Zustände, die einen Ausnahmezustand darstellen in Rot. Man muss auf die Richtung der Pfeile ansehen und es geben keine Pfeile von innen nach außen. Normalerweise haben wir kein explizites Bild für sowas. Und dann haben wir diese Zwischenzone hier, wo es Zustände gibt, die mit unseren Annahmen übereinstimmen, aber trotzdem nicht erreichbar sind. Das heißt, wenn wir jetzt hier drei Stück haben, dann haben wir drei Stück. Wir haben hier drei Stück, die haben die Assertion und dann haben wir einen, der kommt nicht darauf. So, und jetzt kann man als einfachstes die Induktionslänge verlängern von den vier, die wir bisher benutzt haben, auf fünf. Und wenn wir die geholt haben, dann kriegen wir kein Gegenbeispiel. Aber hier auf der rechten Seite gibt es eine Schleife und das heißt, da gibt es eine unbegrenzt lange Schleife von Problemen. Und an einem Schluss kann ich ausbrechen und diesen Ausnahmezustand finden. Das heißt, wenn ich einfach meinen Induktionstiefe tiefer mache, dann kann ich das Problem auf der rechten Seite nicht lösen. Das heißt, ich muss etwas finden, was ein dieser vier Zustände, die den Kreislauf begonnen haben und dann kann ich das mit Induktion beweisen. Und dann kann ich das auch mit Zyklen überprüfen lassen. Hier nämlich meine Designs. Ich stecke sie in Josis. Dann sieht man hier, wie die Zwischengefeils generiert werden. Und dann gebe ich es an einem späteren Schritt zu dem Solver und wenn ich einen Fail bekommen habe, dann bekomme ich einen Gegenbeispiel. Auf der rechten Seite komme ich gegen zwei Spiele raus. Wenn ich einfach etwas reproduzieren möchte, was ich vorher gefunden habe, hier ist ein normaler oder ein typischer Workflow. Ich fahre ein Bounded Modelchip für 10 Schritte, für 20 Schritte. Mal gucken, ob es irgendein Problem gibt. Wenn ich einen Fehler finde, dann habe ich entweder einen Fehler gefunden oder meine Assertions waren falsch oder komisch. Und meine Lösung und der nächste Schritt wäre dann, dass ich entweder den Bug in Ordnung bringe in meinem Design oder aber dass ich die Annahmen locker habe. Wenn das alles funktioniert hat, dann kann ich hier zu dem Schritt 2 gehen und kann den induktiven Beweis fahren. Wenn das schief läuft, dann kann ich das Gegenbeispiel anschauen und dann muss ich für mich entscheiden, ob das erreichbar ist oder nicht. Da muss ich selber eine Entscheidung treffen. Und wenn es erreichbar ist, dann muss ich mein Design ändern und in Ordnung bringen. Und kann wieder von vorn anfangen. Aber wenn das Ding nicht erreichbar ist, dann muss ich neue Bedingungen für den Solven zufügen, um mitzuteilen, dass das nicht erreichbar ist. Und wenn ich das gemacht habe, kann ich neu laufen lassen. Das heißt, das ist ein Dialog zwischen mir und dem Solve. Und so gehe ich weiter. Dann lasse ich den Solven noch einmal betrachten. Und wenn wieder Annahmen das rauskommt, mache ich es noch mal. Wenn das durchgegangen ist, dann weiß ich, dass alles gut ist. Aber dann kommen zwei Sachen raus. Entweder ich sage, ja, jetzt habe ich es bewiesen. Es hat Verifikation durchgefallen. Aber man könnte auch sagen, ich hätte gerne mehr Assertions in meinem Design. Und wenn ich diese neuen Assertions einfüge, dann kann ich es noch mal laufen lassen. Und dadurch weiß ich dann, dass also jedes Gegenbeispiel nicht erreichbar ist. Wenn ich einen Fehler mache und eine Assertion hinzufüge, dass irgendwas unerreichbar ist, dann kann der Solve auch zurückkommen und sagen, ja, du hast einen Fehler gemacht, das ist erreichbar. Jetzt würde man hier mit über nochmal drüber sich unterhalten, aber es lasst uns jetzt mehr sein. Jetzt kommen wir nochmal zum Ursprungsbeispiel zurück. Hier ist eine leichte Abwandlung. Jetzt haben wir einen ModeInput. Und das sagt uns die Richtung, ob wir nach oben oder nach unten zählen sollen. Wir machen die Annahme, dass wir bei fünf anfangen mit unserem Zähler. Und dann schauen wir uns hier eine Weile an und dann sehen wir, dass es auch wahr ist. Es gibt hier keinen Weg, um von fünf zu 200 zu gehen. Und mit einem Underflow funktioniert es auch nicht, weil wir das auch abgefangen haben. Und wenn wir das jetzt laufen lassen, dann macht der boundedModelCheck. Aber die zeitliche Induktion funktioniert nicht. Hier ist ein Gegenbeispiel und es fängt mit 194 an und geht immer immer weiter. Und es geht halt in der Nähe von 200 rum und dann am Schluss kann ich von 199 zu 200 erhöhen. Und der Grund, warum wir ein Gegenbeispiel finden, ist, weil wir dem Solven nicht erzählt haben, dass 194 nicht erreichbar ist. Und jetzt haben wir hier unten die rote Zeile hinzugefügt, haben das Design modifiziert. Und da haben wir gesagt, hier, der Zähler ist immer kleiner als 100, dann funktioniert der Solver und der Beweis funktioniert. In meinem ersten Beispiel war ich nur dabei, nach oben zu zählen und habe also gesagt, man kann den Schritt 10 nicht erreichen. Und ich kann Schritt 15 nie erreichen, weil ich fünf Schritte hatte in diesem temporalen Induktionsbeweis. Wenn wir jetzt korrekt den kompletten Lösungsraum beschreiben wollen, dann können wir das hier laufen lassen. So, jetzt habe ich hier noch ein paar andere Beispiele, die ich vorstellen möchte. Es gibt einen besonderen Kommentar, der Asapimux heißt, das ist ein paralleles Case Statement. Hier haben wir in Veriloc ein paralleles Case Statement. Und wir designen das so, dass die exklusiv sind und das Tool kann damit eine Optimierung designen. Wenn wir das hier sagen, dann können wir in ganz böse Probleme reinlaufen. Wir können das in einem FPGA für viele, viele Stunden prüfen und dann geht es zu einem anderen Hersteller und implementiert das dort. Und der macht dann parallel und der Originale-Test hat mir nicht geholfen. Also, es ist ein weiteres Beispiel hier. Also, da habe ich ein Speicherdesign und dann ein anderes Speicherdesign. Das ist ein weiteres Beispiel hier. Das ist ein weiteres Beispiel hier. Das ist ein weiteres Speicherdesign, das ein bisschen komisch aussieht. Aber man sieht das halt so aus, wenn man ein Südtese Tool dazu bringen will, dass es genau auf einer speziellen Hardware läuft. Also, wir wollen beweisen, dass diese beiden Speicherdesign equivalent sind. Da macht man diese formalen Testbench hier, die eine Instanz macht von beiden Speichern parallel. Und dann gibt es diesen Constraint-File hier oben rechts. Dann nehmen wir an, dass der Ursprung, der Stadtzustand bei beiden gleich ist. Und bei allen anderen Zuständen nehmen wir einfach ein Assert, dass die gleich sind und dass die gleichen Werte rauskommen, wenn die gleichen Inputs reinkommen, die gleichen Inputs generell, weil die sind mit den gleichen Signalen verbunden. Also, das hier ist ein Beispiel mit der Mirren Clock Domains. Also, es ist einfach, um euch zu zeigen, dass das auch geht. Da haben wir ein Zähler. Und die Implementation ist so, dass man einfach das tiefere Bit benutzt, als das Clock Input zu einem Toggle Flip Flop. Und wenn man jetzt ein Zähler baut, mit TTL, ICs, dann also wäre das möglich, das so zu machen. Also, üblicherweise machen wir das nicht so auf dem Chip, aber man hat hier jetzt ein, zwei, drei, vier Clock Domains. Also, das erste ist so der übliche Zähler und ja, und die anderen Blöcke hier sind halt die Bits für andere Zähler. Und das Assert hier ist das zwei Counter, immer den gleichen Wert haben. Und tatsächlich, das kann ich beweisen, mit diesem speziellen Kommando hier, Clock to FF Logic, dann kann man das mit dem machen. Das ist ähnlich hier. Anderes Design, das heißt, für ein Z-Reset Flip Flop, benutzt das nie in einem echten Design. Das ist ganz, ganz schlimm. Aber wenn ihr das benutzen müsst, dann ja, könnt ihr das so prüfen hier. Also, das ist eigentlich, was die Xilings-Tool mit Z-Reset Flip Flops machen, weil die haben das nicht in der Hardware, die synthetisieren das so. Und ja, also, wir können beweisen, dass das ein korrektes Modell ist. Ja, dann gibt es noch eigenes Zeug hier. So, und gibt es ein größeres Projekt, das probiert, Ende zu Ende formale Verifizierung zu machen von Risk 5 Prozessoren. Das heißt, Risk 5 Formal. Also, da bin ich gerade am Arbeiten. Und ja, benutze natürlich vier der Impfachstruktur hier, um diese Verifizierung ausführen zu können. Also, wir würden gerne, ja, halt etwas Größeres kompliziert das zu machen, um zu schauen, ob das funktioniert mit etwas Größerem. Ja, noch ein Beausblick. Ich würde gerne mehr System Very Log Assertion Eigenschaften hinzufügen. Also, es ist einfach, da findet man halt schon was, was man das hat. Und es wäre interessant, wenn man da halt einige Stücke davon verwenden können. Dann verbesserte Unterstützung für Very Log X Propagation. Also, in gewissen anderen Verification Flows kann man modelieren die X Propagation. Genauso wie die Very Log LRM, das spezifiziert. Und es wäre schön, wenn man diesen Flow das auch machen könnte. Das ist ein See-Backend für Joses. Also, ein Schaltkreislauf, ein Dialekt von C umwandeln und dann ein C Validierungstool, wie See-Prover und so weiter. Und am Ende noch hier gibt es dieses Projekt Symbiosis. Das ist ein Frontend um das Ganze hier. Also, Joses, Flows und so weiter. Also, ohne dass man etwas Neues lernen muss, wenn man zu einem anderen Flow wechselt. Kannst du mal? Also, was haben wir heute gelernt? Ja, wir haben gelernt, dass ich sehr, sehr schnell sprechen kann. Also, ja, was du normalerweise einen halben Tag baust, hast du in einer Stunde gemacht. Ich frage aus dem Web zuerst, bitte. Nicht? Okay. Schade, schade. Also, dieser Mann hier. Ich habe noch nicht verstanden, was der Unterschied zwischen Joses und einfach irgendeinem Very-Lock-Simulator ist. Also, der Simulator reagiert ja auch auf Asserts. Ja, aber man muss natürlich ein Testband schreiben, dass die Assertion Triggered und mit Formaler Variation muss man das nicht. Man kann einfach sagen, das ist das Set der gültigen Inputs. Moment, da gibt es einen besseren Weg, das zu zeigen. Also, wenn wir hier hingehen, als die Simulation heißt, man hat diese diversen Traces und das kann sein, dass man die Assertion verletzt oder nicht. Und ich habe hier aber ein Tool, das im Prinzip ein Schreck zurücktritt und das Gesamtbild anschauen. Das kann deinen Ansatz nicht. Also, weil die Zustandsabfolgen sind halt einfach. Es gibt viel zu viele Möglichkeiten. Ich frage mich, ob in deinem Untersuchung Probleme mit Genauigkeit hattest. Also, deine Annahmen erhalten, weil du künstlich den Zustands Space eingeschränkt hast. Also, ja, das kann sein. Wenn immer man Restrict or Assume benötigt, kann es sein, wenn man da einen Fehler macht, dass es dann die Webziehung funktioniert. Aber, ja, also, üblicherweise hat man im Workflow macht man das, dass man künstlich Bugs einfügt und dann prüft man, ob man tatsächlich noch die künstlich eingefügten Bugs finden kann, ob man mit Restrict or Assume keinen Fehler gemacht hat. Dann eine Frage von Internet. Was für Ausdrücke unterstützt Josef genau in diesen Expressions? Also, ich kann, man kann nur immediate Assustins verwenden. Also, ein beliebiger Verylock Ausbruch, aber nicht System Verylock Syntax Eigenschaften. Also, man kann keine letzte Frage Kannst du mir eine ungefähre Idee geben wie lange so eine formale Variation ungefähr braucht? Es kommt sehr auf die Art von Problem an auf den Solver, den man verwendet auf viele andere Parameter. Also, hier habe ich ein 3 verschiedene Benchmarks für eine Handvoll Solver. Also, da gibt es eine ziemliche Spanne. Also, das sieht man hier vielleicht nicht so gut. Aber oft hat man ein Beispiel, dass es sehr gut funktioniert mit einem Solver, aber dann sehr lange mit einem anderen Solver. Und wenn man ein anderes Problem hat, ist es genau umgekehrt. Also, ja, es ist sehr gut, dass man mit Josef SMBTC verschiedene Solver ausprobieren kann. Herzlichen Dank Clifford. Super, dass du da sein kannst. Danke, dass du dein Wissen teilst mit all diesen Leuten hier. Herzlichen Dank. Noch mal eine Runde Applaus, bitte.