Hallo,
wenn man ein Signal in mehreren Processen zuweist, dann geht das nicht
in Vivado, obwohl das in Hardware möglich wäre. Gibt es Synthese
Werkzeuge die das verstehen und richtig machen?
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
entityspielwieseisPort(
5
clk:instd_logic;
6
a:instd_logic;
7
b:outstd_logic);
8
endspielwiese;
9
10
architectureBehavioralofspielwieseis
11
12
begin
13
14
processbegin
15
waituntilrising_edge(clk);
16
ifa='1'then
17
b<='1';
18
endif;
19
endprocess;
20
21
processbegin
22
waituntilrising_edge(clk);
23
ifa='0'then
24
b<='0';
25
endif;
26
endprocess;
27
28
endBehavioral;
Und hier die Testbench:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
entityspielwiese_benchis
5
endspielwiese_bench;
6
7
architectureBehavioralofspielwiese_benchis
8
9
componentspielwieseisPort(
10
clk:instd_logic;
11
a:instd_logic;
12
b:outstd_logic);
13
endcomponent;
14
15
signalclk:std_logic:='0';
16
signala:std_logic:='0';
17
signalb:std_logic:='0';
18
19
begin
20
21
uut:spielwieseportmap(
22
clk=>clk,
23
a=>a,
24
b=>b);
25
26
clk<=notclkafter20ns;
27
28
processbegin
29
waituntilrising_edge(clk);
30
a<=nota;
31
endprocess;
32
33
endBehavioral;
Also das ist ganz klar getrennt in in keinen Takt gibt es einen
Konflikt.
Du hast glaube ich nicht verstanden um was es geht. Ich hatte zweimal a
verwendet weil dadurch sichergestellt ist dass in jedem Takt nur eine
Zuweisung ausgeführt wird. Also dass immer nur ein Ausgang mit einem
Eingang verbunden ist und nie zwei Ausgänge untereinander.
Dass Deine Beschreibung nicht synthetisiert ist klar aber meine könnte
man als Hardware aufbauen.
Gustl B. schrieb:> Du hast glaube ich nicht verstanden um was es geht. Ich hatte> zweimal a verwendet weil dadurch sichergestellt ist dass in jedem Takt> nur eine Zuweisung ausgeführt wird. Also dass immer nur ein Ausgang mit> einem Eingang verbunden ist und nie zwei Ausgänge untereinander.> Dass Deine Beschreibung nicht synthetisiert ist klar aber meine könnte> man als Hardware aufbauen.
Bei deiner Beschreibung wird auch das Signal für den nächsten Takt
gespeichert. Damit wird immer 0 und 1 getrieben und du erzählst immer
ein x.
Im asic kann sowas durch die synthese laufen, aber das ist so 90er :)
interne tristate Busse sind sehr fehleranfällig und schwer zu testen
Welches Signal wird bei mir wo gespeichert? Also ja da ist ein Speicher
aber der Eingang davon wird immer nur mit einem Ausgang verbunden. Wo
werden denn zwei Ausgänge verbunden?
Gustl B. schrieb:> Du hast glaube ich nicht verstanden um was es geht.
Doch hab ich. Deswegen sprach ich von deinem Spezialfall. Warum sollte
ein Synthesewerkzeug sowas unterstützen?
Na weil das dann ein Ding mehr ist, das das Werkzeug kann?
Also ich habe verstanden, dass da Vivado zwei Speicher reinbauen will
und beide Ausgänge davon dann auf b gehen. Aber weil ich das so
beschrieben habe, dass in jedem Takt nur eine Zuweisung gemacht wird,
könnte man auch nur einen Speicher verwenden und wahlweise 1 oder 0
einspeichern.
Wenn ich alles in einen Process schreibe funktioniert es, also wieso
macht das einen Unterschied und gibt es Synthesewerkzeuge die das auch
erkennen wenn es auf zwei Processe verteilt ist?
Gustl B. schrieb:> Wenn ich alles in einen Process schreibe funktioniert es
Ja, klar.
Das ist ja der Normalfall: einem Signal wird nur in 1 Prozess ein Wert
zugewiesen.
> also wieso macht das einen Unterschied
Weil du bei getrennten Prozessen getrennte Flipflops mit jeweils eigenem
Takt beschreibst. Das ist die Vorgehensweise des Synthesizers: er sieht
ein rising_edge() mit Zuweisung an B und erzeugt daraus ein Flipflop.
Und dann sieht er nochmal ein rising_edge() mit Zuweisung an B und
möchte daraus auch ein Flipflop erzeugen. Da gibts aber schon eines. Und
davor hängt schon Logik...
> und gibt es Synthesewerkzeuge die das auch erkennen wenn es auf> zwei Processe verteilt ist?
Ich wüsste nicht.
> wenn man ein Signal in mehreren Processen zuweist, dann geht das nicht> in Vivado
Siehe Screenshot: es geht nicht mal im ISE-Simulator (ich habe dafür das
A ein wenig "symmetriert"). Hast du das simuliert bekommen? Womit?
Gustl B. schrieb:> gibt es Synthesewerkzeuge die das auch> erkennen
Ich denke nicht, dass es Werkzeuge gibt, die diese implizite Angabe
verstehen. Deine 2 Version sind nämlich nicht gleich, auch wenn die
Simulation es evtl. sagt. Ich habe mal vervollständigt:
1
processbegin
2
waituntilrising_edge(clk);
3
ifa='1'then
4
b<='1';
5
else
6
b<=b;
7
endif;
8
endprocess;
9
10
processbegin
11
waituntilrising_edge(clk);
12
ifc='0'then
13
b<='0';
14
else
15
b<=b;
16
endif;
17
endprocess;
Durch den fehlende Zweig wird implizit verlangt, dass sich das Signal b
nicht ändern soll. Dies führt in HW zu einem clock enable oder einer
feedback-Logik (wie ich es oben beschrieben habe).
Wie soll die Synthese jetzt dieses Kollision auflösen?
Daher würde ich nicht sagen, dass die Synthesewerkzeuge es falsch machen
(oder besser machen könnten), sondern es vollkommen richtig ist.
PS: je nach Simulator führt die erste Beschreibung auch zu Fehlern (oder
zumindest zu Warnungen): "multiple drivers".
grüße
Bitte 100 x an die Tafel schreiben:
"VHDL ist keine Programmiersprache".
Wenn man ein Signal aus 2 verschiedenen Prozessen zuweist, dann ergeben
sich in VHDL 2 Treiber für das Signal.
Dies ist zulässig und wird für die Simulation eines Busses benötigt und
verwendet.
Das Ergebnis ergibt sich mit der resolve Funktion( google nach resolved
signals)
In deinem Beispiel treibt Prozess 1 das Signal mit 1, der andere mit 0.
Dies entspricht einem Bus Signal, das von einem Chip mit 0 und vom
2.Chip mit 1 getrieben wird -> Konflikt.
Schlimmer noch, jeder Chip nimmt in deinem Beispiel das Signal nicht
zurück.
Dein Wunsch kann nich implementiert werden, weil VHDL anders
funktioniert als Du Dir vorstellst.
Deshalb: 100 x an die Tafel....
@ Gustl Buheitel (-gb-)
>wenn man ein Signal in mehreren Processen zuweist, dann geht das nicht>in Vivado,
Und auch nicht in anderen Synthesewerkzeugen, wahrscheinlich nicht mal
im reinen Simulator.
>obwohl das in Hardware möglich wäre.
Ach ja? Na dann zeichne mal einen äquivalenten Schaltplan.
>Gibt es Synthese Werkzeuge die das verstehen und richtig machen?
Gibt es VHDL-Designer, die das mit den gegebenen Werkzeugen und Methoden
richtig machen können?
Wenn ein Signal aus mehreren Prozessen zugewiesen wird, ist das im
Allgemeinen unbeabsichtigt und ein Fehler, auch wenn es bei Deiner
Beschreibung vielleicht rein logisch gesehen funktionieren würde. Auf
jeden Fall ist das schlechter Stil, der Code ist kaum verständlich und
schlecht wartbar. Es schüttelt mich bei dem Gedanken, erstmal alle
Qullen eines Signal im Code suchen zu müssen, bevor ich sein Verhalten
verstehen kann.
Deswegen machen meisten Tools "kurzen Prozess" und hauen Dir Dein
Konstrukt gleich um die Ohren, anstatt eine tief gehende Analyse
durchzuführen, ob es vielleicht dich geht. Wie in jeder Sprache gilt
auch bei VHDL: Nicht alles, was geht, ist auch gut.
Vancouver schrieb:> Wie in jeder Sprache gilt> auch bei VHDL: Nicht alles, was geht, ist auch gut.
Und dass nicht alles was simuliert wurde auch synthesefähig ist :)
Gruss
@ daniel__m: Ich hatte den else-Zweig extra weggelassen weil dann das
Signal nur zugewiesen wird wenn die if-Bedingung zutrifft.
@ Lothar Miller: Vielen Dank, bei mir sah die Simulation so aus wie bei
Dir.
@ Klaus Falser und Falk Brunner: Das was Ihr schreibt stimmt wenn man
aus der Beschreibung zwei Speicherelemente gebaut werden. Ich möchte
aber, dass die Synthese das erkennt und nur ein Speicherelement einbaut.
Ich weiß auch dass VHDL keine Programmiersprache ist und warum das was
ich beschrieben hatte nicht funktioniert, das ist mir alles klar. Aber
ich bin der Meinung, dass ein Synthesewerkzeug sehen könnte, dass b zu
einem Zeitpunkt immer nur in einem Process zugewiesen wird. Und dann
eben auch nur ein Speicherelement einbauen. Dass das nicht gemacht wird
ist mir klar, die Frage war aber ob es Werkzeuge gibt die das erkennen.
Natürlich ist das keine saubere Beschreibung, die Frage hier war einfach
nur aus Interesse.
Gustl B. schrieb:> Aber ich bin der Meinung, dass ein Synthesewerkzeug sehen könnte, dass b> zu einem Zeitpunkt immer nur in einem Process zugewiesen wird.
Hier ist es so, dass das Signal eben immer mit definiertem Pegel
speichernd(!) aus 2 Prozessen getrieben wird.
Wenn du es als Tristate und ohne Zugriffskonflikte beschreibst, dann
simuliert es wie gewünscht und es kommt sogar Hardware raus:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
entityspielwieseisPort(
5
clk:instd_logic;
6
a:instd_logic;
7
b:outstd_logic);
8
endspielwiese;
9
10
architectureBehavioralofspielwieseis
11
12
begin
13
14
processbegin
15
waituntilrising_edge(clk);
16
ifa='1'then
17
b<='1';
18
else
19
b<='Z';
20
endif;
21
endprocess;
22
23
processbegin
24
waituntilrising_edge(clk);
25
ifa='0'then
26
b<='0';
27
else
28
b<='Z';
29
endif;
30
endprocess;
31
32
endBehavioral;
Allerdings sieht das Ganze recht grobschlächtig aus...
@Gustl Buheitel (-gb-)
>@ Klaus Falser und Falk Brunner: Das was Ihr schreibt stimmt wenn man>aus der Beschreibung zwei Speicherelemente gebaut werden. Ich möchte>aber, dass die Synthese das erkennt und nur ein Speicherelement einbaut.
Und die Synthese möchte, daß DU dich an bestehende Regeln hälst und
gleich alles in einen Prozess schreibst. Der Rest der Welt kommt damit
problemlos klar.
>ist mir klar, die Frage war aber ob es Werkzeuge gibt die das erkennen.
Wozu? Damit DU dein persönliches Weltbild von VHDL ausleben kannst?
>Natürlich ist das keine saubere Beschreibung, die Frage hier war einfach>nur aus Interesse.
Und wieder ist ein Sack Reis in China umgefallen . . .
Also ich will das nicht machen weil ich es selber für schlecht lesbar
halte, aber theoretisch wäre sowas ja möglich dass ein Synthesewerkzeug
das erkennen könnte. Und genau das war eben die Frage.
Ich weiß auch wie man das so beschreibt dass es synthetisiert, ist ja
ein einfaches Beispiel. Wer mit der Frage unzufrieden ist braucht nicht
zu antworten, ist jetzt aber auch beantwortet.
Vielen Dank an Alle!
Gustl B. schrieb:> Also ich will das nicht machen weil ich es selber für schlecht lesbar> halte, aber theoretisch wäre sowas ja möglich dass ein Synthesewerkzeug> das erkennen könnte. Und genau das war eben die Frage.
Du kanns dir ja das ganze als eine Art Präprozessor wünschen, da
brauchst kein neues synthesewerkzeug. Also ein Tool das den VHDL-code
mit multi-process-write liest und daraus VHDL-code mit
single-process-write code erzeugt. Hardwaretechnisch muss man dazu nur
einen Multiplexor vor das speicherelement setzen.
Gustl B. schrieb:> wenn man ein Signal in mehreren Processen zuweist, dann geht das nicht> in Vivado, obwohl das in Hardware möglich wäre.
Sowas geht zurecht nicht. Es gibt keinen Grund, Signale aus mehreren
Ecken heraus steuern zu wollen, weil dann, wenn man ein Signal als
physisch interpretiert, es eben in der Hardware NICHT geht. Es geht nur
über Verundung oder Verorderung und das kann man programmieren.
Gustl B. schrieb:> @ daniel__m: Ich hatte den else-Zweig extra weggelassen weil dann das> Signal nur zugewiesen wird wenn die if-Bedingung zutrifft.
Nein, Daniel ist da völlig richtig, es wird auch genauso zugewiesen als
wenn ein else-Zweig darin wäre. Ich denke hier liegt der massive
Denkfehler.
Das Signal wird weiterhin getrieben, wenn der Prozess bei Taktflanke
durchlaufen wird ohne in den if-Zweig zu springen. Egal ob else oder
kein else geschrieben. Das wäre das selbe.
Klakx schrieb:> Nein, Daniel ist da völlig richtig, es wird auch genauso zugewiesen als> wenn ein else-Zweig darin wäre. Ich denke hier liegt der massive> Denkfehler.
Natürlich wird es so zugewiesen als stünde da ein else-Zweig. Aber nur
weil da zwei Speicherelemente verwendet werden, für jeden Process eines.
Was ich meinte setzt vorher an und zwar dass das Werkzeug erkennt, dass
es immer nur in einem Process zugewiesen wird zu einem Zeitpunkt und
dann auch nur ein Speicherelement einbaut. Also dass es den zweiten
Process als else Pfad von selbst erkennt.
Gustl B. schrieb:> dass das Werkzeug erkennt, dass> es immer nur in einem Process zugewiesen wird zu einem Zeitpunkt und> dann auch nur ein Speicherelement einbaut.
Dazu müsste man die Regeln von VHDL (und vermutlich jeder anderen HDL)
ändern, da es eine Behandlung eines Sonderfalls darstellt. Das würde
m.M.n. alles eher komplizierter und undurchsichtiger machen. Es nimmt
die Möglichkeit, eventuelle (bzw. eher wahrscheinliche)
Beschreibungsfehler zu erkennen und anzumerken.
Falls es zu diesem Featurerequest käme, würde ich es nicht befürworten,
da es genügend Alternativen der Beschreibung gibt.
grüße
Weltbester FPGA-Pongo schrieb im Beitrag #4812940:
> wenn man ein Signal als> physisch interpretiert, es eben in der Hardware NICHT geht.
Nicht nur dann. Auch wenn ein Signal als das interpretiert wird, als was
es interpretiert werden sollte, nämlich als eine logische Zuweisung
einer Information von einer Quelle zu einer Senke, entsteht immer ein
möglicher Widerspruch.
Ich habe zu dem Thema schon mehrfach Stellung genommen und bleibe fest
bei meiner Vorgehensweise, nämlich Signale vom Ausgang her zu denken und
alle Fälle explizit aufzuziehen, in denen eine Wirkung auf diesen
Ausgang entstehen soll. Dies kommt dann in einen einzigen Prozess. Das
ist übersichtlich und vor allem gut prüfbar.
Sparen kann man sich das nur bei der Simulation, weil in dieser die
Gleichzeitigkeit der Gültigkeit von Signalen und Variablen aufgelöst
wird, weil die Simulationsreihenfolge ins Spiel kommt. Die kann man
natürlich nutzen, um Signale einfacher zu manipulieren. Ob man es aber
auch tun sollte oder doch lieber Zwischensignale mit eindeutigem Vorrang
und Wirkungen benutzen sollte, wodurch explizit ablesbar wird, was
passiert, sei dahingestellt.
Falk B. schrieb:> Und die Synthese möchte, daß DU dich an bestehende Regeln hälst und> gleich alles in einen Prozess schreibst. Der Rest der Welt kommt damit> problemlos klar.
:-)