Forum: FPGA, VHDL & Co. ZPU im Simulator laufen lassen, Problem mit prog2mem


von Jens W. (jensw)


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

von Christoph M. (mchris)


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)

: Bearbeitet durch User
von Jens W. (jensw)


Lesenswert?

Hallo Christoph,

vielen Dank schonmal.
Wenn ich das mit einem Init-File machen möchte, dann muss das File aber 
auch das richtige Format haben.
Das HexFile, dass aus dem GCC rausfällt, kann ich vermutlich nicht 1:1 
verwenden oder?

Grüße, Jens

von Christoph M. (mchris)


Lesenswert?

https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/reference/glossary/def_mif.htm

Da steht:
"A Memory Initialization File serves as an input file for memory 
initialization in the Compiler and Simulator. You can also use a 
Hexadecimal (Intel-Format) File (.hex) to provide memory initialization 
data."

von Martin S. (strubi)


Lesenswert?

Guck mal hier, da gibt es einen "make virtual-zealot" setup, der baut 
aus einem .elf die passenden initialwerte fuer die BRAMs (DRAM16_init, 
o.ae.), siehe hdl/ram, in utils/ sind die Pythonscripte fuer die 
Konversion:

https://github.com/hackfin/MaSoCist

Der laufend unterhaltene Default ist hier allerdings eine pipelined 
Variante der ZPU mit Debug-Interface.

von Jens W. (jensw)


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

von Rick D. (rickdangerus)


Angehängte Dateien:

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.

von Martin S. (strubi)


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.

von Jens W. (jensw)


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

von Vancouver (vancouver)


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.

von Martin S. (strubi)


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.

von Christoph M. (mchris)


Lesenswert?

>die ZPU ist dabei natuerlich der
>Gewinner und laesst sich zudem sehr elegant mit Custom-Instruktionen
>aufbohren.
Was meinst du damit?

: Bearbeitet durch User
von Martin S. (strubi)


Lesenswert?

Dass man fuer spezifische Zwecke neue Opcodes/Befehle implementieren 
kann, ohne dass es die Kernarchitektur beeintraechtigt, im Gegensatz zu 
klassischen Registerarchitekturen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.