Virtueller Hive

Erlebnisse und Schilderungen über die Arbeiten an eurem HIVE.
Benutzeravatar
Wuerfel_21
Beiträge: 57
Registriert: Di 21. Jan 2020, 19:20

Re: Virtueller Hive

Beitrag von Wuerfel_21 »

Wenn du am Projekt nicht mehr weiterabeitest, könntest du evtl. die Quellen posten?
thiloa
Beiträge: 37
Registriert: So 6. Okt 2019, 21:06

Re: Virtueller Hive

Beitrag von thiloa »

Wuerfel_21 hat geschrieben: Fr 16. Jun 2023, 23:33 Wenn du am Projekt nicht mehr weiterabeitest, könntest du evtl. die Quellen posten?
Willst du dir das wirklich antun? :D Das ist alles recht rudimentär, eher schlecht dokumentiert und ich habe dann irgendwann etwas enttäuscht aufgegeben.

Anbei ist gezippt der aktuelle Code des Simulators (propellersim) in C++/Qt5 geschrieben. Die Turbulence Demo startet, allerdings hat diese wohl ein paar Sekunden schwarzes Bild am Anfang, weshalb es über eine Minute bei der langsamen Taktfrequenz dauert, bis das erste echte Bild sichtbar wird.

Der P1 ist in 4 Implementierungen vorhanden von denen ich mal eine auskommentiert habe, da sie sich nicht mehr kompilieren ließ.
PropGenCpp (sehr langsam)
PropNewCpp
PropAsm (modifiziert zur Laufzeit den Code je nach Register, ist aber nicht viel schneller als PropNewCpp)
Verilator (derzeit auskommentiert, sehr langsam)

Zum Bauen ist neben Qt5 noch der nasm Assembler erforderlich.

In mainwindow.cpp im Konstruktor kann man den verwendeten Typ einstellen, derzeit PropNewCpp
Mit m_simGolden kann man auch auch zwei Implementierungen syncron laufen lassen und es wird verglichen, dass in jedem Takt alles gleich bleibt.

Vorab müssen in simulationmaster.cpp die Pfade der P1 Rom (hub_rom_lower.hex und hub_rom_upper.hex) ggf angepasst werden (Dateien sind im Zip). Außerdem muss dort noch das Image des EEPROMS eingestellt werden.

Neben dem P1 gibt es nur eine rudimentäre Implementierung des EEPROMs, PS/2 Keyboards und eines VGA Monitors. Alles wird in simulationmaster.cpp "verschaltet". Die Pins müssen je nach Image ggf angepasst werden.

Die GUI ist derzeit ein rudimentärer Debugger mit Einzelschritt / Disassembler / Hub/Cog Ram und Möglichkeiten den PASM Code zu annotieren. Wenn man das Programm mit F9 startet, dann läuft in der Standardausgabe ein Zähler auf 32768 hoch (Debugausgabe des EEPROMS), dann ist das Programm geladen. Dann ist derzeit ein Haltepunkt aktiv, man muss also nochmal F9 drücken, um das eigentliche Image zu starten. Mit F8 geht es zur nächsten PASM Instruktion im aktuell ausgewählten COG, mit F7 taktet man den CPU genau einmal (i.d.r keine komplette Anweisung).

Bis auf die Verilator Implementierung, lassen sich bei allen P1 Implementierungen Snapshots anfertigen, um bei einem Neustart des Programm an der vorherigen Stelle weiterzumachen. Dies schließt auch die komplette Peripherie Hardware mit ein. Diese Snapshots sind nur gültig, wenn sich nichts der Verschaltung der HW verändert hat.

Im Ordner propeller-clone ist eine Nachimplementierung in Verilog der einzelnen Module enthalten, welche näher am C/C++ Code sind. Alle wurden mit yosys formal gegen die Parallax RTL des P1 verifiziert, der Code sollte daher weitgehend passen. Die Yosys Files sind auch dabei, die Verifikation dauert aber insbesondere bei der Alu etwa 30 Minuten. Der P1 wurde daraus dann in eine einfachere Zwischensprache transferiert (propellersim/other-files/ilang.txt), woraus nach einigen Vereinfachungsschritten die zwei schnellsten P1 Implementierungen mit einem Tool generiert wurden (PropNewCpp, PropAsm)

Wenn du Fragen hast kannst du dich ja nochmal melden.
Dateianhänge
propellersim.tar.gz
(369.9 KiB) 73-mal heruntergeladen
Benutzeravatar
Wuerfel_21
Beiträge: 57
Registriert: Di 21. Jan 2020, 19:20

Re: Virtueller Hive

Beitrag von Wuerfel_21 »

thiloa hat geschrieben: Mo 19. Jun 2023, 23:43 Willst du dir das wirklich antun? Das ist alles recht rudimentär, eher schlecht dokumentiert und ich habe dann irgendwann etwas enttäuscht aufgegeben.
Besser mal gepostet als wenn die ganze Arbeit irgendwo in einem Festplattencrash verloren geht.


Aber wie es das Schicksal jedes zu komplizierten Build-Systems ist... Irgendwas Irgendwas Linkerkonfiguration. Das wird sich sicher lösen lassen.
Screenshot_20230620_220528.png
Außerdem scheint irgendwo eine verilated.h zu fehlen, aber das ist ja wohl eh nicht nötig. Kann außerdem nicht all die Skripte finden, die wohl zu den ".gen.cpp"s dazugehören.
Benutzeravatar
Wuerfel_21
Beiträge: 57
Registriert: Di 21. Jan 2020, 19:20

Re: Virtueller Hive

Beitrag von Wuerfel_21 »

Wuerfel_21 hat geschrieben: Di 20. Jun 2023, 21:17 Das wird sich sicher lösen lassen.
:DAUMENHOCH
Screenshot_20230621_001050.png
thiloa
Beiträge: 37
Registriert: So 6. Okt 2019, 21:06

Re: Virtueller Hive

Beitrag von thiloa »

Sehr gut, du hast es hinbekommen, das freut mich :-)
thiloa hat geschrieben: Mo 19. Jun 2023, 23:43 Außerdem scheint irgendwo eine verilated.h zu fehlen, aber das ist ja wohl eh nicht nötig.
Die verilated.h könnte erzeugt werden, wenn man den Verilator Build Prozess anstößt (propellersim/propeller-verilator/verilog/build.sh), den hatte ich nicht integriert. Bei mir ging das aber jetzt aber nicht mehr. Ist aber vmtl nur eine kleine Anpassung. Der Verilator P1 hatte ich nur mal ganz am Anfang und als Kontrolle ob alles richtig läuft. Er ist allerdings sehr langsam, und lässt auch keine Savestates zu, was mich fast noch mehr als die geringe Geschwindigkeit genervt hat.
thiloa hat geschrieben: Mo 19. Jun 2023, 23:43 Kann außerdem nicht all die Skripte finden, die wohl zu den ".gen.cpp"s dazugehören.
Du meinst den Code Generator dazu? Ich sehe gerade, die waren in separaten Unterordnern. Ich habe sie mal angefügt. Es scheint wohl zwei zu geben, propeller-clone-translator und propeller-jvm-backend, bin mir leider nicht mehr sicher was neuer war. Aber ich glaube das wurde auch als Kommentar in manche Header/Asm Dateien gespeichert. Die Generatoren sind in Kotlin geschrieben.

Zusätzlich ist noch ein Ordner propasmlivedebugger drinnen, das ist ein weiteres Qt Programm (siehe Screenshot), welches man neben dem eigentlichen Simulator laufen lassen kann und live Änderungen am generierten ASM Code anzeigt, sofern die ASM Implementierung gewählt wurde (funktioniert über shared memory). Wenn dann eines der COG Hardwareregister (Video/Counter) geändert wird, dann kann man dort sehen, wie neuer x86 Code generiert wird.
propsim2.png
In der Asm Implementierung ist auch eine Performance Messung verschiedener Cog/Hub teile realisiert, wenn man

#define MEASURE_PERFORMANCE
#define MEASURE_PERFORMANCE_FINE

einkommentiert (ist derzeit schon aktiv). Dann wird in der Ausgabe regelmäßig angegeben, welche Teile des P1 wie viel Zeit zur Ausführung benötigt haben. Diese Messung ist allerdings selbst sehr zeitintensiv.

Wenn du die auskommentierst, dann läuft der ASM P1 nochmal deutlich schneller (bei mir fast Faktor 2).

Wenn man die undefinierten Befehle im Cog mal außen vor lässt, dann müsste man noch ein wenig von dem Hub Memory Zugriff wegoptimieren können. Derzeit wird der ja quasi immer noch virtuell nachgebaut. Leider haben einige der undefinierten Befehle seltsame Eigenschaften, die von Hub Aktionen der Nachbarcogs beeinflusst werden.

Ansonsten hatte ich mir noch überlegt, ob man irgendwie COG Codesequenzen erkennen kann, welche keinen äußeren Einfluss haben. Sofern nicht der Einzelschrittmodus aktiv ist, könnte man diese durch entsprechende x86 Code Sequenzen ersetzen. Leider macht die hohe Anzahl an selbst modifiziertem Code bei typischer P1 Software das nicht gerade einfacher...

Man könnte auch überlegen, ob man die einzelnen Cogs in separate Thread auftrennt. Das ist allerdings nur möglich, wenn die Software das ignoriert, wobei hier der Zugriff auf den Hub Speicher auch fraglich ist. Sobald man aber mehrere Cogs hat, die genaues Timing untereinander besitzen müssen, klappt das schon wieder nicht. Mein Anspruch war ja eigentlich auch zyklenexakte Emulation.
Dateianhänge
propellersim-codegen.tar.gz
(119.98 KiB) 64-mal heruntergeladen
Benutzeravatar
Wuerfel_21
Beiträge: 57
Registriert: Di 21. Jan 2020, 19:20

Re: Virtueller Hive

Beitrag von Wuerfel_21 »

thiloa hat geschrieben: Mi 21. Jun 2023, 00:14 Wenn du die auskommentierst, dann läuft der ASM P1 nochmal deutlich schneller (bei mir fast Faktor 2).
Yupp, bei mir ~ 3.5 MHz in Turbulence.

Den Generator sollte ich mir morgen mal ansehen. Der output scheint nicht 100% optimal zu sein. Hier ein Stückchen aus einer der Dateien:

Code: Alles auswählen

cogClk7_4SUUUT:
    .sect0:
        ;let outp_cog_alu_r 0I0
        mov ecx, 0x0    <-- Sollte xor ecx,ecx sein
        ;preload p_reg
        mov eax, dword [rsi+cog_p_reg]
        ;let instr_dst p_reg
        mov edx, eax
        ;if (neq32 (and32 p_reg 0I1f0) 0I1f0)
        and eax, 0x1f0
        cmp eax, 0x1f0
        jz .sect2
    .sect1:
        ;let outp_cog_alu_r bus_q_reg
        mov ecx, dword [rdi+hub_bus_q_reg]    <-- Könnte CMOV sein, nicht sicher ob das hier hilft.
    .sect2:
        ;Call Macro macroCogState4ZF1
        ;Inputs: [rdx: instr_dst, r8: outp_cog_alu_r]
        ;Modified: [rdx, r8]
        mov r8d, ecx
        call macroCogState4ZF1  <--- Sollte tail-call sein
        ret                        
thiloa hat geschrieben: Mi 21. Jun 2023, 00:14 Wenn man die undefinierten Befehle im Cog mal außen vor lässt, dann müsste man noch ein wenig von dem Hub Memory Zugriff wegoptimieren können. Derzeit wird der ja quasi immer noch virtuell nachgebaut. Leider haben einige der undefinierten Befehle seltsame Eigenschaften, die von Hub Aktionen der Nachbarcogs beeinflusst werden.
Die undokumentierten Seltsamkeiten werden meines Wissens nach nicht absichtlich ausgenutzt und sind IIRC sowieso im Verilog-Modell nicht ganz akkurat, soweit ich weiß ist das Modell nicht die direkte Quelle für das tatsächliche Chiplayout, das wurde manuell aufgebaut. Im tatsächlichen Chip hängt die undokumentierte WRxxxx Z-flagge davon ab, in welchem physischen RAM-Block die Cogs arbeiten.

Bild
thiloa
Beiträge: 37
Registriert: So 6. Okt 2019, 21:06

Re: Virtueller Hive

Beitrag von thiloa »

Wuerfel_21 hat geschrieben: Mi 21. Jun 2023, 01:03 Die undokumentierten Seltsamkeiten werden meines Wissens nach nicht absichtlich ausgenutzt und sind IIRC sowieso im Verilog-Modell nicht ganz akkurat, soweit ich weiß ist das Modell nicht die direkte Quelle für das tatsächliche Chiplayout, das wurde manuell aufgebaut. Im tatsächlichen Chip hängt die undokumentierte WRxxxx Z-flagge davon ab, in welchem physischen RAM-Block die Cogs arbeiten.
Da der Code von Parallax so kryptisch in Verilog aussah und vor allem sehr "Gate Nah", dachte ich, das zumindest Teile der Hardware darauf aufbauen (abseits von dem analogen Kram). Es sind m.E. nicht nur die Flags. Bei den unbenutzen Befehlen konnte man meines Wissens nach ohne Warten vom Hub lesen. Natürlich nicht die eigens angefragten Daten, sondern dann ggf. welche vom Nachbarcog. Wenn du meinst, dass diese Befehle de facto nie in realer Software benutzt werden, kann man das natürlich für den eigenen Zweck optimal auslegen und bspw. ein NOP daraus machen. Ich hatte nur den 6510er im Hinterkopf wo die Leute alle möglichen undokumentierten Opcodes verwendet haben und relevante Simulatoren diese deshalb auch nachbauen ("müssen").
Wuerfel_21 hat geschrieben: Mi 21. Jun 2023, 01:03 Yupp, bei mir ~ 3.5 MHz in Turbulence.

Den Generator sollte ich mir morgen mal ansehen. Der output scheint nicht 100% optimal zu sein. Hier ein Stückchen aus einer der Dateien:
Das stimmt, mir war es damals vor allem die korrekte Ausführung wichtig und das ASM Backend ist halt komplett selbst geschrieben. Vorher hatte ich ja mit einer Lib vom GCC gearbeitet, dessen Code ist sicher besser, aber das hat jedes Mal über 100ms gestoppt, dieser "Schluckauf" beim Ändern eines Counter/Vid Registers war mir dann doch zu viel. Außerdem ist das Programm häufiger abgestürzt und ich konnte nie herausfinden, was die Ursache war.

Abseits davon ist in dem Code der Zwischensprache noch ein wenig Ineffizienz was manche COG Operationen angeht, insbesondere die Flags und manche Subtraktionsaktionen sind ein wenig kreativ eingebaut. Damit kann daraus leicht Code für C generiert werden, wo man ja keinen Zugriff auf die Flags hat. Bei x86 Asm müsste aber zumindest das Zero Flag in vielen Operationen implizit anfallen. Das Carry Flag unterscheidet sich an manchen Stellen hingegen glaube ich etwas zwischen x86 und PASM.

Auch die Funktionsaufrufe zwischen C++/Asm sind glaube ich noch etwas ineffizient (siehe asm-callstubs.gen.asm).

Der aktuelle Generator ist wohl übrigens propeller-jvm-backend.


Neben der P1 Implementierung wird auch etwas Zeit in der Simulation "drum herum" an der Pin Schnittstelle verschwendet. Auf die ursprünglich angedachten 80 MHz kommt man so aber vermutlich nicht, daher hatte ich das Projekt für mich als Hive Emulator schon gedanklich aufgegeben.

Ob abseits davon Interesse an so einem zyklengenauen Simulator in der doch recht überschaubaren Propellergemeinde besteht, weiß ich nicht. Ich meine etwas schneller und "genauer" als Gear ist es ja schon, der Code und das Userinterface sind halt so noch unbrauchbar für Dritte. Der P1 ist allerdings inzwischen auch ein wenig in die Jahre gekommen..
Benutzeravatar
Wuerfel_21
Beiträge: 57
Registriert: Di 21. Jan 2020, 19:20

Re: Virtueller Hive

Beitrag von Wuerfel_21 »

thiloa hat geschrieben: Mi 21. Jun 2023, 20:49 Da der Code von Parallax so kryptisch in Verilog aussah und vor allem sehr "Gate Nah", dachte ich, das zumindest Teile der Hardware darauf aufbauen (abseits von dem analogen Kram). Es sind m.E. nicht nur die Flags. Bei den unbenutzen Befehlen konnte man meines Wissens nach ohne Warten vom Hub lesen. Natürlich nicht die eigens angefragten Daten, sondern dann ggf. welche vom Nachbarcog. Wenn du meinst, dass diese Befehle de facto nie in realer Software benutzt werden, kann man das natürlich für den eigenen Zweck optimal auslegen und bspw. ein NOP daraus machen.
Wenn sie benutzt werden, dann entweder in Code der nie publiziert wurde oder unabsichtlich. Das mit der Flagge war nur das wo ich genaueres weiß...
thiloa hat geschrieben: Mi 21. Jun 2023, 20:49 Abseits davon ist in dem Code der Zwischensprache noch ein wenig Ineffizienz was manche COG Operationen angeht, insbesondere die Flags und manche Subtraktionsaktionen sind ein wenig kreativ eingebaut. Damit kann daraus leicht Code für C generiert werden, wo man ja keinen Zugriff auf die Flags hat. Bei x86 Asm müsste aber zumindest das Zero Flag in vielen Operationen implizit anfallen. Das Carry Flag unterscheidet sich an manchen Stellen hingegen glaube ich etwas zwischen x86 und PASM.
Joa. Wobei ich denke das große Gewinne vor allem in Code der fast immer läuft zu finden sind.
thiloa hat geschrieben: Mi 21. Jun 2023, 20:49 Auch die Funktionsaufrufe zwischen C++/Asm sind glaube ich noch etwas ineffizient (siehe asm-callstubs.gen.asm).
Ja, normalerweise muss man IIRC nur RBX, RBP und R12 aufwärts wegstacken.
thiloa hat geschrieben: Mi 21. Jun 2023, 20:49 Der aktuelle Generator ist wohl übrigens propeller-jvm-backend.
Jo, soweit war ich auch, aber hab es noch nicht gebaut bekommen. Noch nie was mit Kotlin am Hut gehabt.
thiloa hat geschrieben: Mi 21. Jun 2023, 20:49 Neben der P1 Implementierung wird auch etwas Zeit in der Simulation "drum herum" an der Pin Schnittstelle verschwendet. Auf die ursprünglich angedachten 80 MHz kommt man so aber vermutlich nicht, daher hatte ich das Projekt für mich als Hive Emulator schon gedanklich aufgegeben.

Ob abseits davon Interesse an so einem zyklengenauen Simulator in der doch recht überschaubaren Propellergemeinde besteht, weiß ich nicht. Ich meine etwas schneller und "genauer" als Gear ist es ja schon, der Code und das Userinterface sind halt so noch unbrauchbar für Dritte. Der P1 ist allerdings inzwischen auch ein wenig in die Jahre gekommen..
GEAR ist halt wirklich extrem langsam, aber dein Projekt ist an den grenzen von sinnvoller Interaktivität. Ich finde das ist nicht zu unterschätzen.
Antworten