Hi folks!
Ich nutze ja sehr gerne den Makefilegenerator vmk [1], um mir für die
Simulation von VHDL-FPGA-Projekten mit Modelsim ein passendes Makefile
mit allen Quellcodeabhängigkeiten zu erzeugen:
Nun habe ich ein Projekt in Verilog, welches ich weiterentwicklen will.
Dafür würde ich gern die Abhängigkeiten im Quelltext im Makefile
abgebildet haben, damit ich nicht vor jeder Simulation alle >200 Dateien
mit vlog wiederholt kompilieren muß, sondern nur, wenn sich was drand
geändert hat.
Es gibt zwar eine Variante für Icarus [2], von Larry Doolittle (den ich
vor ein paar Jahren kennen lernen durfte...), aber das funktioniert
offensichtlich nur für eine Handvoll von Quelldateien (es gibt kein %.v
Target).
Kurzum, kennt jemand ein passendes Tool?
Duke
[1] https://sourceforge.net/projects/vmk/
[2] https://www.mikrocontroller.net/articles/Verilog#Icarus_Verilog
Hallo Duke,
das vmk kannte ich bisher nicht, danke für den Hinweis.
Ich bin vor kurzem über das hier gestolpert, konnte es aber noch nicht
ausprobieren. Vielleicht ist es ja was für dich:
https://hdlmake.readthedocs.io/en/master/https://www.ohwr.org/projects/hdl-make
Auf den ersten Blick sah das so aus, als müsste man da mit Manifesten
manuell rumopern, aber irgendwie wird da auch mit "fetching modules from
repositories" und "automatically finding file dependencies" geworben.
Zumindest soll es VHDL und Verilog beherrschen.
Falls du es dir näher anschaust darfst du gern deine Erfahrungen hier
teilen ;-) .
Seit vielen Jahren schon beherrschen meines Wissens nach alle bekannten
kommerziellen HDL toolchains inkrementelle Übersetzung mit automatischer
Auflösung der Abhängigkeiten. Makefiles in HDL Projekten sind daher
völlig überflüssig und leider auch fehleranfällig.
Am Ende macht man dann aus Frust eh ein “make clean; make all” um sicher
zu gehen.
Marcus H. schrieb:> Seit vielen Jahren schon beherrschen meines Wissens nach alle bekannten> kommerziellen HDL toolchains inkrementelle Übersetzung mit automatischer> Auflösung der Abhängigkeiten. Makefiles in HDL Projekten sind daher> völlig überflüssig und leider auch fehleranfällig.
Seit vielen Jahren schon verwenden wir einen automatisierten Flow für
Simulation und Synthese. Dabei muss keiner mehr in einer GUI rumklicken,
sondern ein cronjob ruft einen build (und anderes) auf. Makefiles in
Projekten, welcher Art auch immer, führen dabei zu einer einfachen und
reproduzierbaren (Stichwort Versionierung) Lösung. Ganz abgesehen von
noch einigen anderen Vorteilen bei der Verwendung eines make-basierten
flows, wird derjenige, der makefiles verwendet, schon wissen warum. Eine
Diskussion darüber ist nicht Ziel dieses Threads!
Marcus H. schrieb:> Makefiles in HDL Projekten sind daher> völlig überflüssig und leider auch fehleranfällig.
Man kann problemlos alle HDL-Quelldateien im Makefile auflisten und
daraus das Projekt für die Toolchain erzeugen. Das hat den Vorteil, dass
sich keine ungewünschten Dateien in das Build schleichen und ist vor
allem gut reproduzier- und versionierbar.
Außerdem lässt sich damit ein einheitlicher, herstellerunabhängiger (und
halbwegs verständlicher) Arbeitsablauf aufbauen. Magie ist nämlich nicht
zuverlässig.
VHDL hotline schrieb im Beitrag #5540429:
> https://hdlmake.readthedocs.io/en/master/> https://www.ohwr.org/projects/hdl-make
Das sieht sehr vielversprechend aus. Zumal ich 75% der Tools auf der
Liste der unterstützden Programme mehr oder weniger stark nutze...
Beide Links zeigen offenbar auf das selbe Projekt.
Die Installation mit python auf cygwin ging problemlos.
> Auf den ersten Blick sah das so aus, als müsste man da mit Manifesten> manuell rumopern
Ja, das sieht so aus:
Um Dateien hinzuzufügen erzeugt man eine Manifest.py
1
files = [
2
"blinky.vhd",
3
"testbench/blinky_tb.vhd"
4
]
Falls man sein Projekt auf mehrere Verzeichnisse aufgeteilt hat, kann in
jedes Verzeichnis eine Manifest.py
Die Verlinkung erfolgt mit:
1
modules = {
2
"local" : [ "../sources"],
3
"local" : [ "../library"],
4
"local" : [ "../testbenches"],
5
}
In dem Verzeichnis, wo die Simulation gestartet werden soll, müssen die
folgenden Zeilen auftauchen:
1
action = "simulation"
2
sim_tool = "modelsim"
3
sim_top = "blinky_tb"
Mit "hdlmake" wird anschließend ein Makefile erzeugt.
Das Makefile sieht zwar ganz brauchbar aus, funktioniert aber erstmal
nicht mit cygwin, u.a. weil mein cygwin-Terminal keine Windowskommandos
nimmt (del, type nul).
Das läßt sich aber in hdlmake/util/shell.py|check_windows hacken bzw.
anpassen.
Danach funktioniert "make" wie man es erwartet. Super.
Allerdings hat hdlmake mit meinem großen Verilogprojekt noch ein Problem
beim Parsen. Schade.
Das Debugging von Pythonskripten mit Sets von 150 Elementen, wo eins
falsch ist, ist nicht meine Stärke...
Duke
VHDL hotline schrieb im Beitrag #5543922:
> Seit vielen Jahren schon verwenden wir einen automatisierten Flow für> Simulation und Synthese. Dabei muss keiner mehr in einer GUI rumklicken,> sondern ein cronjob ruft einen build (und anderes) auf. Makefiles in> Projekten, welcher Art auch immer, führen dabei zu einer einfachen und> reproduzierbaren (Stichwort Versionierung) Lösung.
Von einer GUI war bei mir auch nicht die Rede.
Die Hauptaufgabe eines Makefiles besteht darin Abhängigkeiten mehr oder
weniger menschenlesbar darzustellen. Make löst diese Abhängigkeiten dann
auf und führt entsprechende Regeln aus. Bekanntermaßen ist das Vorgehen
von Make einerseits recht fragil (z.B. Definition von “out-of-date”,
daher u.a. der tool-spezifische Generator, die Frage ob das Makefile
selbst super-dependency ist oder nicht, was passiert bei geänderten
Compile-Optionen, usw.), andererseits aber auch wiederum sehr unflexibel
darin, bestimmte Dinge zu definieren (z.B. unterschiedliche Pfade für
target/dependency, Stichwort VPATH).
Zur Versionierung reicht mir ein einfaches Shellscript, das meinetwegen
noch eine separate, ebenfalls versionierte Dateiliste einliest. Gerne
auch rekursiv, so dass jedes Untermodul seine eigene Liste definiert,
was in großen Projekten etwas mehr übersicht bringen kann.
Die Auflösung der Abhängigkeiten, also die Kernaufgabe von Make,
überlässt man dann der HDL Toolchain. Die kann das im Zweifel besser als
ein handgestrickter Makefile Generator, der das letzte Tool-Update noch
nicht mitbekommen hat.
> Ganz abgesehen von noch einigen anderen Vorteilen bei der Verwendung> eines make-basierten flows
Ich nehme an, das bezieht sich auf die missverstandene GUI-Vermutung.
Hier stimme ich selbstverständlich zu.
Vorteile eines Make-flows in HDL-Projekten gegenüber einem einfachen
Shellscript fallen mir aber ehrlich gesagt nicht ein.
> wird derjenige, der makefiles verwendet, schon wissen warum.
Du wärst überrascht...
S. R. schrieb:> Außerdem lässt sich damit ein einheitlicher, herstellerunabhängiger (und> halbwegs verständlicher) Arbeitsablauf aufbauen.
Offenbar nicht, sonst wäre kein Generator notwendig. Ein einfaches
Shellscript hingegen kann da schon einiges.
Duke Scarring schrieb:> Allerdings hat hdlmake mit meinem großen Verilogprojekt noch ein Problem> beim Parsen. Schade.
Genau das ist die Sorte von Problemen, die Makefile Generatoren
erfahrungsgemäß immer wieder mit sich bringen. Man findet sich am Ende
dabei wieder, den Generator, das Makefile oder beides zu debuggen.
Marcus H. schrieb:>> Außerdem lässt sich damit ein einheitlicher, herstellerunabhängiger (und>> halbwegs verständlicher) Arbeitsablauf aufbauen.>> Offenbar nicht, sonst wäre kein Generator notwendig. Ein einfaches> Shellscript hingegen kann da schon einiges.
Weiß nicht. Mir ist das Konzept eines Makefile-Generators eher
unsympathisch, weil das ein weiterer, relativ unnützer Komplexitätslayer
ist.
Mein Makefile synthetisiert, implementiert, baut den Bitstream und
programmiert das Ziel falls nötig, kann aber auch simulieren (und den
Simulator mit vordefinierter Konfiguration aufrufen, falls vorhanden).
Ich häng es der Vollständigkeit halber mal an.
Dafür läuft es nur unter Linux und nur mit ISE. Für Vivado habe ich ein
anderes Makefile, was passende Tcl-Scripte erzeugt und dann Vivado
machen lässt (allerdings weniger vollständig, da ich nie Bedarf hatte).
Am Ende fallen vermutlich sogar ähnliche Befehle raus, weil die
Toolchains alle gleich stinken und ferngesteuert werden müssen. Der
Vorteil ist nur, dass "make prog" bei aktuellem Bitstream direkt
losprogrammieren kann, ohne die Toolchain überhaupt starten zu müssen.
Die Notwendigkeit eines Generators erschliesst sich mir gerade noch
nicht, ausser, wenn komplexe Abhängigkeiten von Dateien voneinander
vorliegen, wo händische Auflistung aussen vor ist. Dann würde ich aber
nur die Dependencies per generierte *.d-Dateien auflösen.
Für's Konfigurieren und Bauen/Simulieren tut's bei mir (MaSoCist build
environment) wunderbar im Linux-Stil mit einem Makefile pro
subdirectory, z.B.:
Da hier eine Menge Dateien nach Konfiguration neu generiert werden
müssen, geht es ohne Make-Architektur schon längst nicht mehr. Das
funktioniert definitiv zuverlässiger als mit einigen Vendor-Tools, von
älteren ISE ist bekannt, dass ab und an fehlerhafte Builds bei rumkommen
und man das ganze Build-Verzeichnis löschen muss.
Ansonsten folge ich auch Methode "svenska" mit dem Erzeugen von TCL,
damit alles zentral der 'Make'-Kontrolle unterliegt und auch so
regress-getestet werden kann.
Marcus H. schrieb:> Vorteile eines Make-flows in HDL-Projekten gegenüber einem einfachen> Shellscript fallen mir aber ehrlich gesagt nicht ein.
Der Gag an Make ist, dass nur gebaut wird, was gebaut werden muss. Wenn
du eine Vielzahl von Black-Box-Dateien hast, die u.U. neucompiliert
werden müssen, merkst du das durchaus gegenüber einem linear
durchnudelnden Prozess, insbesondere, wenn in der letzten Source-Datei
in der Liste ein Fehler sitzt..
Im Falle des Regresstests fällt ein Makefile viel kompakter aus als ein
script, zudem hat man die parallele Ausführung (Multicore -jX option)
gratis.
Martin S. schrieb:> Die Notwendigkeit eines Generators erschliesst sich mir gerade noch> nicht, ausser, wenn komplexe Abhängigkeiten von Dateien voneinander> vorliegen, wo händische Auflistung aussen vor ist. Dann würde ich aber> nur die Dependencies per generierte *.d-Dateien auflösen.
Das sind ja wiederum Makefiles, die, wie Du sagst, generiert werden
müssen. Das macht dann ein Makefile Generator :)
Das -- vielmehr ein -- Problem bei Make ist die klare Ausrichtung auf
Systeme, bei denen am Ende eines Übersetzungsschritts genau eine
(Objekt)Datei rausfällt. Das funktioniert bei HDLs eben meist nicht. Man
denke nur mal an VHDL Configurations, Package Bodies, Components
(Verilog ist da zum Glück etwas unkomplizierter). Diese Abhängigkeiten
zu erstellen und irgendwelchen erstellten bzw. modifizierten Dateien
zuzuordnen ist mühselig, fragil und fehlerträchtig.
Überlasse ich diese Aufgabe sinnvollerweise dem Tool Frontend, bleibt
vom Makefile im Grunde nur noch ein Compile Script übrig, das gegenüber
einem reinen Shellscript den Nachteil hat, dass ich mir ums Quoting,
Zeilenenden und Leading Tabs Gedanken machen muss.
Wenn ich mir S. R.s Makefile ansehe (vielen Dank!), dann erkenne ich,
dass die Simulation (vgl. auch die Ursprungsnachricht) genau so
gestartet wird. Es werden einfach alle Quelldateien über die .prj Datei
auf das Frontend geschmissen. Das ist absolut richtig! Nur benötige ich
dafür kein Make und schon gar keinen Generator. Beim nächsten Aufruf
spare ich mir lediglich das Überschreiben der .prj Datei falls sich
keine Quelldatei geändert hat.
Duke Scarring schrieb:> Das Debugging von Pythonskripten mit Sets von 150 Elementen, wo eins> falsch ist, ist nicht meine Stärke...
Ich hab's doch noch hinbekommen. An zwei Stellen (in new_dep_solver.py
und sim_makefile_support.py) mußte ich None oder NoneTypes abfangen,
danach ging es. Ein Diff ist angehangen, ein Anmeldung an der
Maillingliste schlug fehl.
Marcus H. schrieb:> Vorteile eines Make-flows in HDL-Projekten gegenüber einem einfachen> Shellscript fallen mir aber ehrlich gesagt nicht ein.
Mit einem Makefile kann ich verschiedene Aufgaben out-of-the-box in eine
Datei packen. Das läßt sich natürlich auch mit einem oder mehreren
Shellskripten abdecken, ich fand es so übersichtlicher.
S. R. schrieb:> Mir ist das Konzept eines Makefile-Generators eher> unsympathisch, weil das ein weiterer, relativ unnützer Komplexitätslayer> ist.
Ja und nein. Für die Synthese braucht man das nicht (v.a. weil die Tools
keine echten Anhängigkeiten beherrschen).
Für die Simulation von größeren Projekten, wo eine Änderung an einer
Bibliothek einen Rattenschwanz an Recompiles nach sich ziehen muß, aber
eine Änderung am top-Level nur für die Testbench relevant ist, finde ich
so ein Makefile prima. Es verkürzt mir den Entwicklungszyklus (edit ->
recompile -> simulate).
GHDL kann solche Makefiles erstellen. Modelsim auch, aber erst nachdem
das Projekt einmal sauber (manuell) durchcompiliert wurde. Na danke
auch, vor allem wenn man mehr als fünf Quelldateien hat.
vmk lief da bisher unkompliziert und wollte nur eine Liste a'la
"library path/source.vhd". Und weil die Dateilliste dann schon da war,
hab ich die auch im Synthesemakefile verwendet.
S. R. schrieb:> Am Ende fallen vermutlich sogar ähnliche Befehle raus, weil die> Toolchains alle gleich stinken und ferngesteuert werden müssen.
Ja, ein großer Spaß: Die Lattice-Diamond Tools heißen genauso wie die
Xilinx-ISE Tools (par, map, bitgen, edif2ngd, ngdbuild, ...) :-/
Naja, haben eben eine gemeinsame Geschichte.
Egal ob ich LaTeX-Doku, C-Programm, C++-Programm, Simulation, Synthese
oder sonstwas mache: ein 'make' startet den Buildprozess oder gibt mir
eine Liste der möglichen Optionen aus.
Egal welcher Compiler, welcher Softcore, welches FPGA...
Mal hat man mehr von den aufgelösten Abhängigkeiten, mal weniger.
Marcus H. schrieb:> Diese Abhängigkeiten> zu erstellen und irgendwelchen erstellten bzw. modifizierten Dateien> zuzuordnen ist mühselig, fragil und fehlerträchtig.
Meine Erfahrung mit vmk sind da anders.
> Überlasse ich diese Aufgabe sinnvollerweise dem Tool Frontend,
Und hier eben auch (s.o.)
Duke
Marcus H. schrieb:> Das -- vielmehr ein -- Problem bei Make ist die klare Ausrichtung auf> Systeme, bei denen am Ende eines Übersetzungsschritts genau eine> (Objekt)Datei rausfällt.
An und für sich sollte ein Übersetzungsschritt genau das tun, was er im
Namen trägt: Von einem Format in ein anderes übersetzen.
Genau dafür ist Make (und im Übrigen auch UNIX als Ganzes) gedacht: Ein
Algorithmus besteht aus einer Aneinanderreihung von (einfachen) Filtern,
die gemeinsam ein Problem lösen. Insofern sehe ich das nicht als
Problem.
Marcus H. schrieb:> Das funktioniert bei HDLs eben meist nicht.
Genau das betrachte ich als Problem. Es ist durch die Grundstruktur der
HDLs nicht möglich, sie sinnvoll einzeln zu betrachten. Ich möchte die
Designer jetzt nicht unbedingt als Idioten bezeichnen, aber... ein wenig
mehr Weitsicht hätte ich mir da schon gewünscht.
> Man denke nur mal an VHDL Configurations, Package Bodies, Components> (Verilog ist da zum Glück etwas unkomplizierter).
Im Grund sind das doch Probleme, die es überall gibt. In C/C++ trennt
man Interface und Implementation durch die Trennung von Header und Code,
in anderen Sprachen gibt es funktionierende Modulsysteme und so weiter.
Unterschiedliche Auswahlsysteme existieren auch, und seien sie so
primitiv wie #ifdef GNUC.
Es ist äußerst unschön, um es sehr milde auszudrücken, dass HDLs (oder
zumindest VHDL) aus einer großen Soße bestehen, in die man alles
reinkippt, gut umrührt und hofft, dass der Compiler das irgendwie
zusammenpuzzelt. Ich laste das den HDLs an, keine guten Lösungen
bereitzustellen.
Was im Übrigen auch dazu führt, dass sich die Hersteller für parallele
Verarbeitung extra bezahlen lassen können. Zumindest mein ISE nutzt nur
einen Kern und bei Vivado war die parallele Verarbeitung ebenfalls
äußerst beschränkt (beides WebPack).
Marcus H. schrieb:> Es werden einfach alle Quelldateien über die .prj Datei> auf das Frontend geschmissen. Das ist absolut richtig!
Wie gesagt, es geht ja auch nicht anders. Das ist - aus meiner Sicht -
ein Versagen der HDL-Designer und Tool-Entwickler. Wobei insbesondere
letztere damit kein Problem haben, schließlich ist es Kundenbindung.
Duke Scarring schrieb:>> Am Ende fallen vermutlich sogar ähnliche Befehle raus, weil die>> Toolchains alle gleich stinken und ferngesteuert werden müssen.> Ja, ein großer Spaß: Die Lattice-Diamond Tools heißen genauso wie die> Xilinx-ISE Tools (par, map, bitgen, edif2ngd, ngdbuild, ...) :-/
Mit Lattice habe ich noch nicht gearbeitet, aber wenn der Flow ähnlich
dem von ISE ist, lässt sich das Makefile leichter anpassen. ;-)
Duke Scarring schrieb:> Egal ob ich LaTeX-Doku, C-Programm, C++-Programm, Simulation, Synthese> oder sonstwas mache: ein 'make' startet den Buildprozess oder gibt mir> eine Liste der möglichen Optionen aus.
Ist bei mir genauso. Wobei LaTeX sich wieder einigermaßen gebrauchbar in
Makefiles abbilden lässt, zumindest wenn man Bibtex u.ä. mit einbezieht.
Für Java (und Android, zumindest ältere Versionen) habe ich auch mal
Makefiles gemacht, aber da ist ja das gesamte Buildsystem ein großer,
sich ständig verändernder Clusterfuck. Seufz. "Ein Buildsystem, welches
zwingend Internet braucht." Wer denkt sich nur so einen Scheiß aus.
S. R. schrieb:> Ich laste das den HDLs an, keine guten Lösungen bereitzustellen.
Was aber nichts an der Tatsache ändert, dass Make eben nicht für die
partielle Übersetzung von HDLs (insbesondere VHDL) geeignet ist. Um
diese Frage ging es ja ursprünglich (“damit ich nicht vor jeder
Simulation [...] wiederholt kompilieren muß, sondern nur, wenn sich was
dran geändert hat”).
Die Compiler bauen intern sowieso die nötigen Datenstrukturen auf und
können diese dann entsprechend nutzen. Make basiert im Grunde auf einem
Implementierungsdetail früher Compiler/Sprachen (man hatte ja nicht
soviel Speicher). HDL Compiler erzeugen natürlich auch Artefakte, deren
Strukturen sind aber herstellerspezifisch und können sich daher
jederzeit ändern.
Ich kenne das nagende Gefühl, etwas unnötig übersetzt zu haben. Vor
langer Zeit hab ich selbst so einen Generator geschrieben, der VHDL und
Verilog Abhängigkeiten für Modelsim, VCS und Debussy anhand derer
spezifischen Artefakte korrekt auflösen konnte. Die entsprechenden
Makefiles wurden mit m4 aus einem gemeinsamen Metafile erzeugt. Das
Ergebnis war höchst befriedigend, der Entwicklungsaufwand und der
tatsächliche Nutzen eher nicht.
Die Übersetzungszeit (für die Simulation) ist für mich selbst in großen
Projekten kein echtes Problem mehr.
Marcus H. schrieb:> Make basiert im Grunde auf einem Implementierungsdetail früher> Compiler/Sprachen (man hatte ja nicht soviel Speicher).
Eher auf einem Grundgedanken von UNIX, nämlich Pipes und Filtern.
Vermutlich leitet sich der Compiler vom gleichen Gedanken ab, statt den
nur als Implementierungsdetail zufällig produziert zu haben...
Marcus H. schrieb:> HDL Compiler erzeugen natürlich auch Artefakte, deren Strukturen> sind aber herstellerspezifisch und können sich daher> jederzeit ändern.
Object-Files sind ebenfalls herstellerspezifisch (bzw.
compilerspezifisch). Schau dir mal die REL-Dateien von SDCC an. ;-)
Mir geht es bei Make nicht darum, unnötige Übersetzungen zu vermeiden,
sondern um Bequemlichkeit und Konsistenz über verschiedene Umgebungen.
Hier ein Shellscript, da ein Makefile, dort eine CMakeLists.txt, das
nervt einfach.