Vielleicht wenn sich die Zuweisung in reine Kombinatorik auflösen lässt,
hier eben ein Demux, bestehend aus Invertern und AND-Gattern.
Ist lang her und ich bin auf die Lösung gespannt.
mfg mf
Argh, es gibt wohl sehr viele Lösungen ...
Ich hatte irgendwie geglaubt (warum auch immer), dass man innerhalb von
getakteten Prozessen keine concurrent statements schreiben darf. Aber
siehe da, das scheint generell erlaubt.
Einzige Voraussetzung ist VHDL 2008 Unterstützung.
(Zumindest) ältere Quartus-Versionen z.B. können das (wegen eben
unvollständiger VHDL 2008 Implementierung) nicht.
Ansonsten ist es genau dasselbe wie
Markus F. schrieb:> Einzige Voraussetzung ist VHDL 2008 Unterstützung.> (Zumindest) ältere Quartus-Versionen z.B. können das (wegen eben> unvollständiger VHDL 2008 Implementierung) nicht.
Richtig. Das kam alles mit VHDL2008. Der Support dafür sieht aber i. d.
R. schlecht aus. Die Asic Synthesen können sowas zum Beispiel gar nicht.
Da kann man schon froh sein, wenn VHDL93 halbwegs funktioniert.
Schön zu sehen, dass so etwas immerhin von den FPGA Toolings (teilweise)
unterstützt wird.
Error: /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
8
Error: /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
9
Error: /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
10
*** Presto compilation terminated with 3 errors. ***
Ich korrigiere: das sollte schon immer gehen.
Dann hast Du's hier halt mit einer unvollständigen VHDL-Implementierung
zu tun...
[edit: das Ding scheint das Statement ja zu erkennen, hat "nur" keinen
Synthese-Support dahinter]
Gustl B. schrieb:> nter welchen Umständen sind concurrent Zuweisungen wie
Oh, auf die Idee wäre ich ja niiiiiiiiiiiiiiie gekommen, das überhaupt
auszuprobieren 🤯
Damals ging das noch nicht und ich hab das dann auch nie wieder
versucht.
Interessehalber nachgehakt:
1. Gilt das hier gesagte auch für verkettete with/select/when- bzw.
when/else-Konstrukte vs. case/is/when im Prozess?
2. Den else-Zweig beim if kann man als einzelne Zuweisung auch vor das
if-Statement setzen:
1
b <= '1';
2
...
3
if a = '1' then
4
b <= '0';
5
end if;
Gibt es das außerhalb der Prozesse auch, also z. B. when ohne else?
Kay-Uwe R. schrieb:> Gibt es das außerhalb der Prozesse auch, also z. B. when ohne else?
Ich habe es mir so gemerkt, dass in Prozessen "if" und außerhalb
Prozessen "when".
Damals ging es andersrum auch garnicht. Glaub ich werde es auch nie
wieder anders machen 🤔
Mampf F. schrieb:> Ich habe es mir so gemerkt, dass in Prozessen "if" und außerhalb> Prozessen "when".
Die Sache wird dann spannend, wenn sich die IFs und WHENs funktionell
überlappen und es echte exklusive IF-ELSE sind, bzw wie verschachtelt
sie sind. Als Beispiel könnte man auf die ersten 3 Bits eines Verktors
checken und parallel noch auf die ersten 2. Das ergibt einen parallelen
Konstrukt, der einen Vorrang braucht um eindeutig aufgelöst zu werden.
Dann gilt nämlich die Reihenfolge der Codierung und das noch im Bezug
auf das Auftreten von Signalen. Besonders in der Simulation macht sich
das dann bemerkbar. Wenn z.B. eine FSM läuft, die an zwei Stellen
zeitversetzt auf kombinatorische Signale prüft, dann würde eine Änderung
von Signalen zwischen den beiden Abfragen zu einem varianten Ergebnis
führen. Je nachdem, wie man die Process-Liste ausführt, bekommt man z.B.
3 mögliche Verhaltensfälle, von denen 2 nichts mit dem gemein haben, was
der synthetisierte Code macht.
Also, check’s mal: Wenn du in VHDL abgehen willst und so a <= b when c =
'1' else d; direkt im Prozess droppen willst, dann ist das klar machbar.
Aber das musst du außerhalb von den krassen if-Statements machen, die
auf den Clock abfahren, weißt du?
Hier mal ein Beispiel, wie das fresh aussehen könnte:
process(clock)
begin
if rising_edge(clock) then
-- Hier kommen die getakteten Moves
end if;
-- Und hier ballerst du die concurrent Zuweisung rein, easy.
a <= b when c = '1' else d;
end process;
Die Sache ist die: Concurrent Zuweisungen sind wie die Party, die
nebenan abgeht, während du in deinem Zimmer chillst. Die laufen parallel
und jucken sich nicht daran, was in deinem sequentiellen Flow abgeht.
Also kannst du die einfach nebenbei laufen lassen, solange sie nicht in
den if-Statement-Vibe reinkrachen, der auf den Clock reagiert. Voll
logisch, oder?
Gerda M. schrieb:> Aber das musst du außerhalb von den krassen if-Statements machen
Eben genau nicht. Ich dachte auch, dass das so wäre, aber es
funktioniert auch im getakteten Teil eines Prozesses.
Gerda M. schrieb:> process(clock)> begin> if rising_edge(clock) then> -- Hier kommen die getakteten Moves> end if;>> -- Und hier ballerst du die concurrent Zuweisung rein, easy.> a <= b when c = '1' else d;> end process;>> Die Sache ist die: Concurrent Zuweisungen sind wie die Party, die> nebenan abgeht,
Da sehe ich keinen Sinn drin. Das "a <= b when c = '1' else d;" gehört
raus aus dem process statement, wenn nicht irgendwelche Abhängigkeiten
nötig sind. Soweit sie sinnvoll sind, um die Simulation zu optimieren,
gehört das in einen eigenen Prozess, wo die SENS-Liste von (nur) diesen
Signalen abhängig ist.
Hier steckt auch wieder ein wenig die Strategie mancher Entwickler drin,
dass man alle getakteten Signale in einen process stopfen
kann/sollte/darf. Davon halte ich sehr wenig!
Ich tendiere lieber zu einer Einzelbeschreibung der relevanten
Ausgangssignale mitsamt dem Managment dessen, was dafür nötig ist. Das
vereinfacht die Verschachtelungen bei IF-THENs und auch eventuell WHENs.
Das Ziel sollte Übersichtlichkeit sein und nicht das Ausreizen von
Codierungs-Optionen. Weil immer viel historisches mitgeschleppt wird,
herrscht bei VHDL eine große Redundanz und ein Wildwuchs bei der
Möglichkeit, exakt Dasselbe zu beschreiben, dass es angezeigt ist, das
zu simplifizieren und zu vereinheitlichen.
> VHDL Rätsel
Wenn bei solchen Beschreibungen "gerätselt" werden muss und man die
Simulation braucht, um einen Konstrukt zweifelsfrei und vollständig zu
verstehen, ist er fehl am Platze.
VHDL ist eine Bauanleitung für eine virtuelle Elektronik und solche
Anleitungen sollten klar formuliert sein, damit sie gut und effektiv
überprüfbar sind. Das ist bei wachsender Schaltungskomplexität zunehmend
wichtiger und in vielen Branchen, in denen Code gereviewd werden muss
und Standards zu erfüllen hat, einfach unerlässlich. Es hat niemand
etwas davon, wenn ein Entwickler perfektionierte und selten genutzte
Konstrukte benutzt, die ihm Zeit ersparen, sehr elegant sind, von
anderen aber nur durch Analyse verstanden werden. Am Ende muss man X
Kommentare und Doku nachrüsten, was jeden Vorteil einer möglichen
Zeiteinsparung pulverisiert.
Auch in Sachen Code-Pflege ist es viel einfacher und durchsichtiger,
wenn beim Vergleich zweier eingecheckter Versionen nicht an
allenmöglichen Stellen aufgeblusterte und immer komplizierter werdende
FSMs und Prozesse auftauchen, sondern das einmal Gemachte in Ruhe bleibt
und neue Funktionen wirklich einfach nur zu einigen neuen Prozessen und
Zeilen führen, die im Compare-Fenster direkt aufpoppen. Die
Compare-Funktion profitiert massiv davon, wenn Code entsprechend
blockorientiert erstellt wurde. Auch lassen sich solche nachgerüsteten
Code-Fragmente viel einfacher per COPY und PASTE in andere Projekte
verfrachten und alter Code manuell nachpflegen. Das Automerge bei
gleichzeitiger Codebearbeitung von zwei Leuten funktioniert dann auch
unfallfreier.
J. S. schrieb:> Das "a <= b when c = '1' else d;" gehört> raus aus dem process statement, wenn nicht irgendwelche Abhängigkeiten> nötig sind.
Darum geht es nicht. Es ging mir nur um die Tatsache, dass solche
concurrent Zuweisungen möglich sind - und zwar nicht nur in einem
Prozess, sondern auch in dem getakteten Teil vom Prozess. Das war mir
neu, scheint aber standardkonform zu sein. Man kann jetzt also statt