Hallo,
habe hier eine Aufgabe aus einer Altklausur und bin mir nicht sicher, ob
ich das Programm so richtig verstanden habe.
Frage 1: Ab der mit Frage 1 gekennzeichneten Programmzeile wird ein dann
folgender Anweisungsteil mittels einer PROCESS (clk) und END PROCESS;
Anweisung umklammert. Welchen Einfluss hat diese Klammerung bzgl. der
Abarbeitung der umschlossenen Anweisungen?
Meine Antwort auf Frage 1: Der PROCESS ist Taktabhängig. Die Anweisungen
innerhalb des PROCESS werden nur bei einem bestimmten Pegel
abgearbeitet.
Frage 2: Welche Funktionalität wird mit der Anweisung in der mit Frage 2
gekennzeichneten Programmzeile beschrieben?
Meine Antwort auf Frage 2: Es wird nur auf eine positive Taktflanke
reagiert.
Allgemein zum Programm:
clk stellt den Pegel dar -> entweder 0 oder 1, also low oder high
d ist ein integer von 0 bis 255
up_down legt Zählrichtung fest -> 0 für negativ, 1 für positiv
qa ist ein Integer und stellt den Ausgang dar
bei ld = 0 wird nicht gezählt
bei enable = 1 und ld = 1 wird gezählt
Das Programm wird beendet wenn cnt den Wert von qa erreicht.
Hab ich das alles so richtig verstanden?
Dirk schrieb:> Frage 2: Welche Funktionalität wird mit der Anweisung in der mit Frage 2> gekennzeichneten Programmzeile beschrieben?>> Meine Antwort auf Frage 2: Es wird nur auf eine positive Taktflanke> reagiert.
Kann man so sagen.
Dirk schrieb:> Meine Antwort auf Frage 1: Der PROCESS ist Taktabhängig. Die Anweisungen> innerhalb des PROCESS werden nur bei einem bestimmten Pegel> abgearbeitet.
Das ist nur teilweise richtig.
Ein Prozess ist eine Art Sammlung von Anweisungen. Die Sensitivity List,
also das was in Klammern steht, sagt dem Simulator, dass er den Prozess
nur ausführen soll, wenn sich clk ändert. Für die Synthese hat das aber
keine Bedeutung. Deshalb braucht man für die Synthese nochmal die
explizite Bedingung aus Frage 2.
Ein Prozess muss übrigens nicht getaktet sein, es gibt auch Prozesse
ohne Takt.
Bestimmte Konstrukte funktionieren nur innerhalb oder außerhalb von
Prozessen.
Das jetzt mal als Einstieg.
ein paar kleine Ergänzungen:
Dirk schrieb:> bei ld = 0 wird nicht gezählt
... sondern cnt wird auf einen von außen kommenden Wert geladen
Dirk schrieb:> Das Programm wird beendet wenn cnt den Wert von qa erreicht.
Nö. das qa <= cnt ist keine Abbruchbedingung, sondern eine Zuweisung:
der aktuelle Wert von cnt wird auf qa ausgegeben.
Der Prozess wird im Simulator immer wieder neu ausgeführt, wenn es zu
einer Änderung am Signal clk kommt - so lange, bis der Simulator die
Ausführung stoppt.
Achim S. schrieb:> Der Prozess wird im Simulator immer wieder neu ausgeführt, wenn es zu> einer Änderung am Signal clk kommt - so lange, bis der Simulator die> Ausführung stoppt.
Und das wird passieren wenn der Schritt 255 + 1 oder 0 - 1 erreicht
wird. Der Simulator hält sich nämlich streng an die VHDL-Spezifikation
und erfindet im Gegensatz zum Synthesizer keinen Wrap-Around wenn er
nicht explizit hingeschrieben wurde.
Dirk schrieb:> habe hier eine Aufgabe aus einer Altklausur
Das ist mal ein echt unschöner synchron-asynchron-Mischmasch. Entweder
beschreibe ich einen Prozess getaktet, dann passiert aber vor dem Takt
(ausser evtl. einem asynchronen Reset) nichts, oder ich beschreibe
einen kombinatorischen Prozess, dann kommt aber kein 'event darin vor.
Aber ich schreibe nicht vor oder nach den Takt noch eine kombinatorische
Zuweisung.
> bin mir nicht sicher, ob ich das Programm so richtig verstanden habe.
Weil du eine VH-Description-L verwendest, ist das wegen des "D" eine
"Beschreibung". Zum "Programmieren" würdest du ja mit einer
VH-Programming-L arbeiten müssen. Ich erwähne das nur, weil du dir
sicher eine blutige Nase holst, wenn du mit VHDL so "programmierst", wie
du mit C(++) oder Java oder sonst einer prozeduralen Programmiersprache
programmierst.
Dussel schrieb:> Ein Prozess muss übrigens nicht getaktet sein, es gibt auch Prozesse> ohne Takt.
Und dann heißt es: Aufpassen bei der Sensitivliste! Denn jedes Signal,
das eine Neuberechnung des Prozesses nötig macht, muss dort hinein.
> Ein Prozess muss übrigens nicht getaktet sein, es gibt auch Prozesse> ohne Takt.
Für den Synthesizer ist das eine einfache Rechnung: sobald ein 'event im
Prozess auftaucht, ist ein Takt im Spiel und es werden Flipflops
erzeugt. Das 'event kann z.B. auch im rising_edge() oder falling_edge()
"versteckt" sein.
> Bestimmte Konstrukte funktionieren nur innerhalb oder außerhalb von> Prozessen.
Dazu solltest du aber sagen, dass du mit "Konstrukten" keine Bauteile
wie Flipflops, Multiplexer oder Logik meinst, sondern bestimmte
Syntaxelemente. Eine case-Abfrage darf z.B. nur in einem Prozess
verwendet werden. Wenn ich die selbe Logik nebenläufig ohne Prozess
beschreiben will, dann muss ich mit with-select oder when-else arbeiten:
https://insights.sigasi.com/tech/signal-assignments-vhdl-withselect-whenelse-and-case/
Ich würde es eher so sagen: für bestimmte Konstrukte gibt es innerhalb
von Prozessen einen anderen Syntax, als wenn sie ausserhalb von
Prozessen nebenläufig beschreiben werden.
Lothar M. schrieb:> Dussel schrieb:>> Ein Prozess muss übrigens nicht getaktet sein, es gibt auch Prozesse>> ohne Takt.> Und dann heißt es: Aufpassen bei der Sensitivliste! Denn jedes Signal,> das eine Neuberechnung des Prozesses nötig macht, muss dort hinein.
Also praktisch all Signals. ;-)
Lothar M. schrieb:>> Bestimmte Konstrukte funktionieren nur innerhalb oder außerhalb von>> Prozessen.> Dazu solltest du aber sagen, dass du mit "Konstrukten" keine Bauteile> wie Flipflops, Multiplexer oder Logik meinst, sondern bestimmte> Syntaxelemente.
Richtig.
Lothar M. schrieb:> Ich würde es eher so sagen: für bestimmte Konstrukte gibt es innerhalb> von Prozessen einen anderen Syntax, als wenn sie ausserhalb von> Prozessen nebenläufig beschreiben werden.
Ich überlege gerade, gibt es Registrierung außerhalb von Prozessen? Also
ein Äquivalent zu if rising_edge()? Ich habe es noch nie gebraucht, aber
geht das?
Dussel schrieb:> Also praktisch all Signals. ;-)
Wenn man sich das Mitdenken sparen will, dann ja... ;-)
> Ich überlege gerade, gibt es Registrierung außerhalb von Prozessen? Also> ein Äquivalent zu if rising_edge()? Ich habe es noch nie gebraucht, aber> geht das?
Ich mache das gern z.B. bei Schieberegistern zum Eintakten asynchroner
Signale:
Lothar M. schrieb:>> Ich überlege gerade, gibt es Registrierung außerhalb von Prozessen? Also>> ein Äquivalent zu if rising_edge()? Ich habe es noch nie gebraucht, aber>> geht das?> Ich mache das gern z.B. bei Schieberegistern zum Eintakten asynchroner> Signale:
Interessant, danke. Ich war unsicher, ob rising_edge außerhalb von
Prozessen funktioniert. Mein Rechner mit dem VHDL-Zeug ist gerade aus
und belagert.
Dussel schrieb:> ob rising_edge außerhalb von Prozessen funktioniert.
"Funktionieren" tut das in VHDL schon immer. In der Simulation.
Ob sich das Ganze in Hardware umbiegen lässt, das sagt dir das Handbuch
zum Synthesizer. Aber seit gut 10 Jahren bin ich keinem begegnet, der
das nicht kann... ;-)
Lothar M. schrieb:> Weil du eine VH-Description-L verwendest, ist das wegen des "D" eine> "Beschreibung". Zum "Programmieren" würdest du ja mit einer> VH-Programming-L arbeiten müssen. Ich erwähne das nur, weil du dir> sicher eine blutige Nase holst, wenn du mit VHDL so "programmierst", wie> du mit C(++) oder Java oder sonst einer prozeduralen Programmiersprache> programmierst.
Das sehe ich nicht so eng mit den Begriffen. Ein FPGA ist deshalb doch
kein FDGA, oder? Der Name ist Programm, wie es so schön heißt -
letzteres etymologisch eine Bekanntmachung. Das Sequenzielle steckt
hingegen in den "S"-Zellen, im Gegensatz zur Kombinatorik (C-Zellen).
Seit wir von Schematic Entry auf Texteingabe (PAL/GAL seinerzeit)
umgestiegen sind, haben wir das immer Programmieren und nie Beschreiben
genannt.
Eine gute Übung ist das Umsetzen der Schaltung in eine bildliche
Darstellung mit Gattern, FFs etc., zumindest gedanklich. Kann man
übrigens mit aktuellen IDEs auch heute noch bewerkstelligen. Oder sich
mal eine automatische Umsetzung anseen (kleinere Schaltungen).
Duke Scarring schrieb:> dfIas schrieb:>> Ein FPGA ist deshalb doch kein FDGA, oder?> Das 'P' in FPGA kommt m.E, eher aus der Richtung 'programmable> resistor'...
Eher Programmierbare 'Gatter-schaltung'. Wobei eben nicht im
Halbleiter-'Ofen` programmiert, sondern easy auf der Platine hier
'Field'.
Das ist dann auch schon die grösste Gemeinsamkeit in der
'Programmierung' zwischen FPGA und ISP (in-system programmable)
mikrocontroller.
Man kann ja auch mit 74*** Gatter gräbern Ablaufsteuerungen
programmieren. Da die aus Gattern aufgebaute Version der Graphik-,DMA
und Peripheriecontroller für den späteren Commodore Amiga Homecomputer:
https://pbs.twimg.com/media/CpMsQd4UMAEtznY?format=jpg&name=large
Das P in FPGA kommt eher historisch davon, dass etwas (wie z.B. ein
EPROM) in einem "Programmiergerät" programmiert wurde. Und
dfIas schrieb:> Das sehe ich nicht so eng mit den Begriffen.
Ich im Grunde auch nicht, weil ich den Unterschied kenne. Aber die
Anfänger, die C-programmierenderweise aus der µC-Ecke oder mit C#/Java
vom PC kommen, sollten sich an diesen Begrifflichkeiten kurz mal stoßen.
> Eine gute Übung ist das Umsetzen der Schaltung in eine bildliche> Darstellung mit Gattern, FFs etc., zumindest gedanklich.
Ja klar. Und dann wird dieses (gedankliche) Bild mit Worten
beschrieben (**). Und dann sieht man sich das an, was der Synthesizer
draus gemacht hat (entweder als Schematic oder beim Ressourcenverbrauch
im Report) und denkt drüber nach, ob das zum Bild passt, dass man sich
selber gemacht hat.
(**) wenn ich vor einem schönen Bild oder in einer netten Landschaft
stehe und dir in einem Brief schreibe, was ich da sehe, was mache ich
dann?
"Programmiere" ich das, was ich sehe, in meinem Text oder "beschreibe"
ich es?
Der Mischmasch von synchronen und kombinatorischen Statements im selben
Process-Kontext ist einer großen Schwachpunkte bei VHDL. Seit einigen
Jahren arbeite ich (aus beruflichen Anforderungen) verstärkt mit
SystemVerilog, und da sind die Dinge eindeutiger geregelt.
Synchrone Prozesse werden mit always_ff gekennzeichnet, z.B.
1
always_ff @(posedge clk) begin
2
...
3
end
Alles zwischen begin und end wird hier nur bei der steigenden Flanke
von clk getriggert.
Kombinatorsche Prozesse heißen always_comb und haben implizit eine
Sensitivitätsliste, die alle Signale enthält, die in dem Kontext
verwendet werden.
Natürlich kann man auch in SV noch unbeabsichtigte Latches fabrizieren,
aber für gewollte Latches gibt es die always_latch Umgebung.
Man muss diese Konstrukte nicht zwingend benutzen, aber wenn man es tut,
dann fliegen einem solche Konstruktionen wie im Beispiel des TO gleich
beim compilieren um die Ohren und nicht erst später, wenn man sich in
der Simulation den Wolf sucht.
Dafür gibt es in SV andere Dinge, die einen in den Wahnsinn treiben,
z.B. die automatische Deklaration von Signalen.