ZPU im Simulator laufen lassen, Problem mit prog2mem

OP #7788303
Lesenswert?

Hallo zusammen,

ich habe die ZPU auf mein Board portiert. Als Basis habe ich das hier genommen: Beitrag "ZPU: Opensource Softcore CPU Projekt für Xilinx Spartan-3 FPGA Board"

Das ganze baut auch richtig. Jetzt habe ich zwei Möglichkeiten, entweder ich teste direkt alles am Board, oder ich verwende vorher den Simulator. Ich habe mich für den Simulator entschieden.

In der Anleitung wird das hex-file, das laufen soll, mittels prog2mem dem bitfile hinzugefügt und dann wird das über den Programmer rübergeschoben.

Da liegt genau das Problem: Gibt es die Möglichkeit das hex-file beim synthetisieren gleich mit einzubinden? Ansonsten ist der Speicher für den Simulator leer und da passiert nichts. Wie mache ich das am besten?

Viele Grüße, Jens

#7788375
Lesenswert?

Man kann den Speicher mit einem Init-File vorbelegen, aber das könnte auch von der Entwicklungsumgebung abhängen.
https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vhdl/vhdl_file_dir_ram_init.htm
https://github.com/nullobject/de10-nano-z80/blob/master/src/single_port_rom.vhd

Man kann es auch mit fixen Werten vorbelegen:
https://github.com/costarc/Z80SoC/blob/master/RCC_Branch/ROM/rom.vhd
( Wie der Router dann entscheidet, interne Speicherblöcke zu verwenden und das ganze nicht als Logikgrab zu implementieren, weiß ich nicht)

OP #7789073
Lesenswert?

Hallo Martin,

vielen Dank! Das bringt mich mit Sicherheit weiter. Aber ich muss da wohl in Python einsteigen, das mache ich bisher noch nicht.

ich gehe mal davon aus, dass es keine "Bordmittel" der IDE gibt, mit der ich das sonst machen kann. Ich habe sowas gefunden wie "elf2hex". Das scheint aber auch über Python zu laufen.

Echt blöd! Wie machen das denn die anderen mit der ZPU? Wie stellt ihr sicher, dass euer Design läuft, wenn das mit dem Simulator nicht direkt läuft? In der fertigen HW Fehler zu suchen ist doch mit Sicherheit komplizierter!

Gibt es noch andere Ideen?

Grüße, Jens

#7789268
Lesenswert?

Jens W. schrieb:

Wie machen das denn die anderen mit der ZPU?

Genau so, wie Du Dir das gedacht hast. Die main.bin wird in ein passendes RAM- oder ROM-VHDL konvertiert:

1
zpu-elf-objcopy  --strip-debug --discard-locals  -O binary main.elf main.bin
2

3
cat                         > dualport_ram.vhd    dualport_ram.vhd_header
4
support/zpuromgen main.bin >> dualport_ram.vhd
5
cat                        >> dualport_ram.vhd    dualport_ram.vhd_footer

Es geht sicher auch eleganter, aber es geht.

Außerdem habe ich noch eine Möglichkeit geschaffen, das der Programmcode weiß, ob er auf der Hardware oder im Simulator läuft. Damit können dann langwierige Initialisierungen übergangen werden und man kann speziellen Testcode direkt anspringen.

Angehängte Dateien:
#7789355
Lesenswert?

Jens W. schrieb:

vielen Dank! Das bringt mich mit Sicherheit weiter. Aber ich muss da wohl in Python einsteigen, das mache ich bisher noch nicht.

ich gehe mal davon aus, dass es keine "Bordmittel" der IDE gibt, mit der ich das sonst machen kann. Ich habe sowas gefunden wie "elf2hex". Das scheint aber auch über Python zu laufen.

Die "Bordmittel" deiner FPGA-IDE (ich nehme an, ISE) sind, wenn vorhanden, immer sehr herstellerspezifisch und kaum portabel. Die meisten SoC-Baukasten liefern irgendwas mit elf to hex/hdl mit, der rom-generator der classic ZPU wurde ja oben schon reingeklemmt. Der ist allerdings sehr limitiert, aber fuer den Anfang ausreichend. Du musst ja typischerweise bei der standard-ZPU-Architektur nur ein 32bit breites RAM mit Werten fuellen. In die Scripttiefen einsteigen musst du erst, wenn gewisse Code-Segmente gezielt in andere Memories plaziert werden sollen.

Echt blöd! Wie machen das denn die anderen mit der ZPU? Wie stellt ihr sicher, dass euer Design läuft, wenn das mit dem Simulator nicht direkt läuft? In der fertigen HW Fehler zu suchen ist doch mit Sicherheit komplizierter!

Das Dogma der robusten HDL-Entwicklung gebietet eigentlich, dass erst mal alles im Trockendock verifiziert wird, bevor ueberhaupt Hardware angeschafft wird. Also: Ja, bei komplexen Systemen mit I/O sollte man alles mal erst virtualisieren, abgesehen von Safety-Aspekten bei Software (wo die MISRA-Compiler nicht hinterherkommen) spart man einfach massiv Zeit bei der Fehlersuche. Schon um einfache Treiber zu testen lohnt sich so ein Setup mit einem virtuellen UART, wo du asynchron mit deinem bare-metal-OS in der Simulation quatschen kannst.

OP #7789738
Lesenswert?

Hallo zusammen,

vielen Dank! Damit kann ich erstmal weitermachen! Nach so etwas hatte ich gesucht! Das werde ich mir mal so zusammenbauen, dass ich damit umgehen kann.

Ob ich bei der ZPU bleibe stellt sich dann später raus.

Vielen Dank an alle nochmal!

Grüße, Jens

#7789748
Lesenswert?

Dabei zeigt sich wieder einmal der Vorteil einer technologieunabhängigen Modellierung. Wenn man den Speicher als Array modelliert, kann man die Daten zu Beginn der Simulation mit den entsprechenden Funktionen (z.B. readmemh() in SytemVerilog) in den Speicher laden, was keine Simulationszeit kostet und rasend schnell geht. Sogar mehrmals, ohne den Simulator neu starten zu müssen. Und wenn man sich an die Designguides des FPGA-Herstellers hält, wird daraus auch ein Blockram synthetisiert, ohne dass man mit irgendwelchen generierten IP-Cores rumhampeln muss. Auf diese Weise simulieren wir gerade ein 64bit-Dualcore-RISC-V SoC, das sich ohne Änderungen für Xilinx-FPGA synthetisieren lässt.

#7790602
Lesenswert?

Technologieunabhaengig sind die RAM-Implementierungen aus obigen Projekten allemal, aber gerade bei der Initialisierung gibt's bei VHDL mit dem Einlesen von externen Hex-Files diverse Irritationen die man in Verilog nicht hat. Stichworte: VHDL08 versus 93 und das bei nur 8 Synthese-Targets: No such fun. In der laufenden Simulation RAMs neu einlesen ist auch eher simulatorabhaengig, da ist mir unter VHDL keine portable Loesung bekannt, ausser per VHDPIDIRECT oder VPI-Hacks, sofern es der Simulator kann.

Leider hat die openSource-Bewegung was die ZPU-Architektur angeht nicht richtig Fahrt aufgenommen, so ist der GCC-Port etwas alt und optimiert ziemlich schlecht. Weitergehende LLVM-Ansaetze sind leider nicht publiziert. Wenn eher Speed als Sicherheitsaspekte gelten, bietet sich allenfalls eher RISC-V oder neo430 an, letzterer hat als 16 bit CPU auch ganz ordentlich kompakten Maschinencode, die ZPU ist dabei natuerlich der Gewinner und laesst sich zudem sehr elegant mit Custom-Instruktionen aufbohren.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren