CPU-Testprogramm



  • Hallo,

    ich suche ein Test-Programm zum testen der elementaren Basis-Funktionen einer CPU.

    (so was ähnliches wie TestFloat http://www.jhauser.us/arithmetic/TestFloat.html für die FPU)

    Geprüft werden sollen:
    - simple Rechenbefehle mit korrektem setzen der Flags
    - bedingte Sprünge in Abhängigkeit der Flags
    - einfache/segmentierte Speicherzugriffe und zugehörige Adressberechnungen
    das Programm sollte in freiem Assembler-Source-Code vorliegen.

    Grüße und Danke schon mal für alle nützlichen Tipps
    Erik



  • sorry, aber wozu braucht man sowas? eine cpu sollte immer richtig rechnen.



  • Hallo rapso,

    > sorry, aber wozu braucht man sowas?

    um eine simulierte/echte CPU zu prüfen (zusätzlich möchte ich auch noch etwas dazu lernen)

    > eine cpu sollte immer richtig rechnen.

    in der Theorie, und wegen denn bekannten Unterschieden hin zur Praxis will ich das möglichst exakt prüfen.

    Ich habe schon den Source von Bochs durchgekramt aber leider nichts gefunden.

    Mir geht es speziell um die Flags, es ist kaum irgendwo vollständig beschrieben wie die unter allen möglichen Umständen gesetzt/gelöscht werden. Trotzdem gibt es bei allen CPU-Architekturen (die ich mir angesehen hab) die gleichen 4 Basis-Flags und darauf aufbauend 14 verschiedene Bedingungen. Ich habe gehofft das dafür irgendwo eine ausführliche Beschreibung und am Besten ein ausführliches Test-Case existiert. Als Entwickler möchte ich gerne (eventuell automatisiert) Testen können.

    Grüße
    Erik



  • Ein solches Testprogramm kenne ich auch nicht. Wird wie rapso schon andeutete sehr wahrscheinlich auch noch kaum jemand fuer sinnvoll erachtet haben. CPU-Hersteller testen ihre CPU sehr wahrscheinlich anders und Emulatorprogrammierer debuggen der Einfachheit halber wohl idR. auch nicht mit einem eigenstaendig (sinnvoll) lauffaehigen Testprogramm.

    Wie die Flags genau gesetzt werden kannst du bestimmt aus den Dokumentationen zu Intels alten Pentiums (AFAIR mehrere 1000 Seiten) heraussuchen, evtl. steht das auch in kuerzeren Dokumentationen zu einzelnen CPU. Ansonsten steht in Befehlsreferenzen idR. zumindest allgemein, welche Flags eine Intruktion beeinflusst. Da hilft dann in den meisten Faellen auch Namen der Flags und Operation anschauen sowie Hirn einschalten, in allen verbleibenden Faellen ausprobieren, um herauszufinden, wie die Flags genau gesetzt werden.

    Was es mit den 4 "Basis Flags" (C S/N Z O/V) auf sich hat, kann dir bestimmt auch das Wikipedia erklaeren, die funktionieren im Grunde bei allen ALUs gleich (zB. http://de.wikipedia.org/wiki/Statusregister).

    Dein Testprogramm wirst du dir ansonsten wohl oder uebel selbst schreiben muessen.



  • ich nutze immer programme mit graphikausgabe zum testen von emulatoren, z.b. ein mandelbort fraktal oder einen kugel raytracer, weil man dann sofort visuell sieht wenn etwas falsch laeuft.

    als unittesting benutze ich dann kompressionsalgorithmen und hashes, die sind recht komplex was logik angeht und der kleinste fehler propagiert sich weiter und wuerde vom referenzdatenset abweichen.

    wie "Nobuo T" sagte, teste ich das meiste auch live am OP-Tisch. ein unittesting waere nett, aber das waere nicht crossplattform (fuer welche cpu brauchst du das ueberhaupt?) und in assembler waere sowas viel aufwand und nur fuer eine sehr limitierte audienz.

    btw. mandelbrot, CRC32, usw. source findest du selbst bei wikipedia. 🙂



  • Danke für Eure Antworten,

    Das mit den von Euch vorgeschlagenen Demo-Programmen zum Testen sehe ich nicht ganz so optimistisch. Diese Programme "testen" wohl kaum alle Spezialfälle durch. Das ist einer der Vorteile von TestFloat, es wird auch der Umgang mit NaN's u.ä. getestet was in normalen Programmen möglichst vermieden wird.

    Bei den reinen Basis-Befehlen wird wohl kaum jemand die Flags nach einer Addition benutzen und trotzdem möchte ich gerne sicherstellen das auch die richtig funktionieren.

    Mit den von Euch vorgeschlagenen Methoden kann man sicher die Grundsätzliche Funktionsfähigkeit testen aber mit einem Unittest der möglichst 100% vom Testobjekt abprüft ist das nicht vergleichbar. Und gerade die Flags werden von den Compilern nicht ganz so ausgiebig genutzt. Ich kenne auch keine Hochsprache wo man mit den Flags direkt arbeiten kann.

    Die CPU-Hersteller haben bestimmt sowas im Haus aber das dürfte dort wohl unters Geschäftsgeheimnis fallen.

    Der von "Nobuo T" genante Wikipedia-Artikel enthält nur allgemeines Zeugs aber nichts mathematisches.
    Ich werde wohl auf jeden Fall mein Gehirn anschalten müssen 😃

    💡 Zum testen ist mir eingefallen das man das eventuell mit einer Script-Sprache (Phyton, PHP o.ä.) erledigen kann. Man bräuchte eine Reihe von abstrakten Test-Cases und für jede Ziel-Architektur eine Art Themplate das dann für jedes einzelne Test-Case in eine große Assembler-Datei geschrieben wird. Zusätzlich bräuchte man noch für jedes Zielbetriebssystem ein Basis-Gerüst (mit Linkerscript) in das der fertige Testcode eingebaut wird und anschließend könnte man die Binutils ein Binary erzeugen lassen. Ich muss diese Idee mal übers Wochenende sacken lassen, vielleicht mach ichs ja. Für x86, ARM und AVR tät ichs mir zutrauen (von der Scriptsprache mal abgesehen, davon hab ich keine Ahnung), für andere Architekturen müsste das jemand anderes machen.
    Das es für sowas nur wenig Verwendung gibt weis ich auch.

    Grüße
    Erik



  • erik_vikinger schrieb:

    Bei den reinen Basis-Befehlen wird wohl kaum jemand die Flags nach einer Addition benutzen und trotzdem möchte ich gerne sicherstellen das auch die richtig funktionieren.

    😕
    Keine ahnung, auf wen du dich da beziehst, aber dieser jemand muss ein schlechter Assembler Programmierer oder Compiler sein.

    erik_vikinger schrieb:

    Mit den von Euch vorgeschlagenen Methoden kann man sicher die Grundsätzliche Funktionsfähigkeit testen aber mit einem Unittest der möglichst 100% vom Testobjekt abprüft ist das nicht vergleichbar.

    Richtig. Das ist vielleicht oft wuenschenswert (siehe Errata aktueller CPU), ist aber leider oft aus verschiedensten Gruenden unpraktikabel.

    erik_vikinger schrieb:

    Und gerade die Flags werden von den Compilern nicht ganz so ausgiebig genutzt. Ich kenne auch keine Hochsprache wo man mit den Flags direkt arbeiten kann.

    Wieder 😕
    Hochsprachen abstrahieren idR. von der zugrunde liegenden CPU so weit, dass ein Zugriff auf Eigenheiten wie deren Status (=flags - wieso gehst du ueberhaupt ausgerechnet so auf die "flags" ab?) nicht explizit vorgesehen ist. Natuerlich wird im Maschinencode des compilierten Programms bei Bedingungen (if, Schleifen, usw.) aber auch ausgiebig mit den Flags gearbeitet. Wenn der Compiler vernuenftig optimiert auch nicht nur nach Vergleichsinstruktionen.

    erik_vikinger schrieb:

    Die CPU-Hersteller haben bestimmt sowas im Haus aber das dürfte dort wohl unters Geschäftsgeheimnis fallen.

    Zwar nicht ausgeschlossen, aber wie ich bereits schrieb, besteht eine Testbench fuer CPU idR. nicht aus einem auf dieser eigenstaendig (sinnvoll) lauffaehigen Programm. Das ist nicht mit diesem TestFloat zu vergleichen.

    erik_vikinger schrieb:

    Der von "Nobuo T" genante Wikipedia-Artikel enthält nur allgemeines Zeugs aber nichts mathematisches.

    Der Artikel beschreibt doch recht genau, wie die Flags gesetzt werden. Voraussetzung ist natuerlich, dass man eine ungefaehre Ahnung hat, wie eine ALU, bzw. das Rechnen mit binaeren 2komplement-Zahlen funktioniert. Was brauchst du da noch "mathematisches"?

    Ansonsten viel Erfolg mit deinem Projekt.



  • aber mit einem Unittest der möglichst 100% vom Testobjekt abprüft ist das nicht vergleichbar.

    Aus reiner Neugier, wie könnte man denn z.B. x86 cmp-Befehl mit 32-Bit Zahlen 100% überprüfen, ob die Flags richtig gesetzt werden? Man müsste ja alle möglichen Kombinationen von 32 Bit Zahlen durchgehen und miteinander vergleichen. Das wäre eine Schleife von 0 bis 4294967295 und in der Schleife müsste man noch eine weitere Schleife einbauen, die ebenfalls von 0 bis 4294967295 läuft und cmp Befehl aufruft... Oder? Wie lange würde so was wohl dauern...



  • Guten Morgen,

    aber mit einem Unittest der möglichst 100% vom Testobjekt abprüft ist das nicht vergleichbar.

    Aus reiner Neugier, wie könnte man denn z.B. x86 cmp-Befehl mit 32-Bit Zahlen 100% überprüfen, ob die Flags richtig gesetzt werden? Man müsste ja alle möglichen Kombinationen von 32 Bit Zahlen durchgehen und miteinander vergleichen. Das wäre eine Schleife von 0 bis 4294967295 und in der Schleife müsste man noch eine weitere Schleife einbauen, die ebenfalls von 0 bis 4294967295 läuft und cmp Befehl aufruft... Oder? Wie lange würde so was wohl dauern...

    Mit "möglichst 100% vom Testobjekt" war nicht gemeint das alle möglichen Kombinationen an Eingangswerten geprüft werden sollen sondern das möglichst alle "Datenpfade" geprüft werden sollen. Bei einem Addierer/Subtrahierer ist das im wesentlichen der "Carry-Chain" von einem Single-Bit-Addierer/Subtrahierer zum nächsten. Ein paar Kombinationen mit durchrotierender 1 oder 0 würden da IMHO völlig reichen um die korrekte Addition/Subtraktion zu prüfen, Fehler die dann noch übrig sind müssten schon sehr verworren sein. Auf die Flags bezogen sollten ebenfalls ein paar 100 Test-Cases reichen um alle Eventualitäten abzuprüfen, man muss eben ein paar Grenzwerte u.ä. raussuchen.

    Bei einer per Software simulierten CPU würde selbst das nicht viel nützen den in der Simulations-Software steht an der betreffenden Stelle in Source-Code einfach ein "+" oder ein "-" und das sowas richtig funktioniert setzen wir mal voraus. Für die Flags muss man da schon deutlich mehr Aufwand betreiben (weshalb ich auch gerade auf denen so rumreite) damit die immer richtig dazugerechnet werden, schließlich bekommt man die ja nicht von der Hochsprache geliefert (alternativ könnte man natürlich Inline-Assembler für die Host-CPU verwenden und direkt deren Flags abgreifen).

    Da ich die CPU nicht nur in Software sondern auch in einem FPGA implementiere ist mir ein Programm das möglichst schnell zu einem möglichst aussagekräftigem Ergebnis kommt sehr wichtig. Die von Euch gemachten Vorschläge mit "normalen" rechenintensiven Programmen benötigen sehr viel CPU-Zeit und auch eine laufende Umgebung (Betriebssystem und Peripherie). Selbst wenn ich den FPGA-Simulator 24 Stunden lang laufen lasse komm ich so vielleicht auf ein paar 100'000 CPU-Takte und das reicht nicht für ein Betriebssystem. (Das selbe Problem haben auch die CPU-Hersteller bevor das erste Silizium kommt und daher denke ich das die entsprechende kleine Testprogramme haben.) Das meinte ich mit dem plattformspezifischen Basis-Gerüst für das Testprogramm, je nach Ergebnis (OK / nicht OK) könnte man mit einem bestimmten GPIO wackeln oder auf eine bestimmte Portadresse schreiben wohingegen die Windows-Version eine Message-Box verwenden müsste. Außerdem könnte so ein Testprogramm auch ganz ohne OS (oder BIOS) auskommen. Auf einem System wo ein komplexes OS wie Linux oder Windows korrekt bis zur Shell oder GUI hochfährt gibt es sicher nur noch wenig was ein CPU-Testprogramm prüfen müsste (vom TestFloat mal abgesehen) aber wenn man nicht soweit kommt könnte ein kleines schlankes Testprogramm schon recht nützlich sein.

    Insgesamt gefällt mir die Idee recht gut, jetzt muss ich mal sehen ob und wie ich das am besten umsetzen kann. Kennt ihr ein gutes How-To für Template-Verarbeitung in einer vernünftigen Scriptsprache?

    Danke noch mal für Eure Antworten!

    Grüße
    Erik



  • Hallo,

    ich habe mir den Thread noch mal durchgelesen, verstehe ichs richtig, du möchtest x86 oder ARM oder AVR CPU in VHDL o.ä. nachbauen und sicherstellen, dass deine nachgebaute ALU die Flags richtig berechnet und in einem oder mehreren internen Registern abspeichert? Das wäre doch kein Problem, in der HDL deiner Wahl eine Testbench zu schreiben und alle Fälle im Simulator durchgehen... Verstehe nicht, was möchtest du da noch in einer Skriptsprache irgendwelche Assemblermodule generieren. Wenn du in deiner HDL Testbench sicher getestet hast, dass die betroffenen Signale in jedem Fall in einem Register landen und dieses Register sie auch weiterhin behält (also nicht gleich überschrieben oder zurückgesetzt wird), wäre ein weiteres Testprogramm in Assembler überflüssig. Eine weitere Testbench müsste testen, ob all die Befehle, die auf dieses spezielle Register lesend zugreifen, beim Lesen auch das bekommen, was im Register steht. Was immer du in einem Assembler-Programm testen möchtest, lässt sich doch im Simulator viel besser testen (auch wenn zig-Hunderte Takte simuliert werden müssen).



  • Hallo,

    @abc.w
    Nein.
    Ich entwickle eine andere CPU in einem FPGA (mit VHDL) und in einem Software-Emulator (mit C++) und möchte ein Test-Programm haben das ich als Binary in den VHDL-Simulator und in den Sofware-Emulator und auf das echte FPGA-Board laden kann um damit möglichst alle (zumindest die meisten) wichtigen Basis-Funktionen der CPU (in möglichst wenigen Takten wegen den Simulatoren) möglichst zuverlässig abprüfen kann. Da diese Basis-Funktionen bei allen mir bekannten CPUs weitestgehendst identisch sind könnte man das mit einem generischen Verfahren machen und hätte für verschiedene Plattformen ein kleines Testprogramm für die Basics. Als weiteren Vorteil sehe ich das ein generisches Programm auch auf meinem Entwicklungsrechner laufen könnte und ich somit die Test-Vektoren gegenprüfen kann, natürlich unter der Voraussetzung das die physische CPU in meinem PC korrekt arbeitet (wovon ich einfach mal ausgehe).

    Es gibt für viele verschiedene CPUs software-basierte Emulatoren und es gibt eine Reihe Soft-CPUs für FPGAs und daher bin ich der Meinung das von einem kleinem Basis-Testprogramm noch andere Projekte profitieren könnten.

    Auf den Flags bin ich deshalb so rumgeritten weil ich bei diesen ein höheres Fehlerpotential sehe als bei den eigentlichen Rechenoperationen. Auch in VHDL schreibe ich für eine Addition ein einfaches "+" hin und verlasse mich darauf das der FPGA-Compiler (Synthese-Tool) einen vernünftigen Addierer baut (für die verschiedenen FPGAs gibt es unterschiedliche Konzepte einen "vernünftigen", also schnellen und ressourcensparenden, Addierer zu bauen). Trotzdem sollen natürlich auch die Rechen-Ergebnisse aller Grundrechenarten bzw. Grundlogicfunktionen mit ein paar Testvektoren überprüft werden.

    Grüße
    Erik


Anmelden zum Antworten