Hallo, ich arbeite mich gerade in VHDL ein und mache dazu auch
übungsaufgaben.
ich hoffe von euch kann mir einer hierbei klarheit verschaffen,
eigentlich dachte ich wäre alles klar - nun habe ich aber zwei
unterschiedliche meinungen bekommen und kann die ergebnisse derzeit
nicht durchsimulieren. eure meinung zur wertefolge für diesen abschnitt
würde mich sehr interessieren!
1
signaly3,ye:integer;
2
3
process(clk)
4
variabley:integer;
5
begin
6
if(clk'eventandclk='0'then
7
y1:=3*y2;
8
y2<=x+2;
9
y3<=y1+y2;
10
endif;
11
endprocess;
Das Signal wird extern entsprechend folgender tabelle mit einer
taktrückflanke übergeben. Die Tabelle im anhang soll ausgefüllt werden.
nun die Frage: Innerhalb von Prozessen wird doch SEQUENZIELL zugewiesen,
oder? Eine Lösung (die musterlösung, meiner ansicht nach falsch) sieht
so aus:
x 4 8 5 7 3
y1 U 18 30 21 27
y2 U 6 10 7 9
y3 U U 24 40 28
Meine Lösung wäre gewesen:
x 4 8 5 7 3
y1 U U 18 10 21
y2 U 6 10 7 9
y3 U U 24 40 28
Das alles dürfte für die Könner unter euch trivial sein - ich würde mich
total über Hilfe freuen!
Eine Variable im Process bekommt sein neuen Wert sofort zugewiesen.
Ein Signal dagegen bekommt seinen neuen Wert beim nächsten Process
Aufruf.
In deiner Tabelle:
Alex schrieb:> x 4 8 5 7 3> y1 U 18 30 21 27> y2 U 6 10 7 9> y3 U U 24 40 28
Beim ersten Durchlauf hat y1 den wert U weil y2 den Wert U immer noch
hat.Erst beim 2.Durchlauf wird y2 aktualisiert und nimmt dann den Wert
6.Aber da eine Variable sofort seinen Wert bekommt,ist y1 dann
3*y2=18.Initialisiere mal y2 mit einem beliebigen Wert,und du wirst
sehen dass,y1 diesen Wert beim ersten Durchlauf sofort annimmt.
Den Rest kannst du sicherlich daraus ableiten.
Im Hardware bedeutet sequentiell nicht gleich sequentiell wie bei
Hochsprachen wie C.
Diesen Beitrag wird bestimmt helfen
Beitrag "process jetzt sequentiell oder nicht?"
Gruß
Mus
Hallo,
danke!
verstehe ich das also richtig - die reihenfolge der "ausführung" (in
diesem fall zuweisung) in einem prozess ist nicht abhängig von der
reihenfolge in der es dort geschrieben steht? Also anders: Unabhängig
von der zeitverzögerten Zuweisung bei Signalen (die habe ich verstanden)
gelten signal und variablenzuweisungen in dem prozess dann "global"
insofern, dass hier eine variablenzuweisung die im code vor der
signalzuweisung y2 steht, von deren wert sie ja abhängig ist, dann "im
nachhinein" (was die reihenfolge des codes angeht) zugewiesen wird?
> Erst beim 2.Durchlauf wird y2 aktualisiert und nimmt dann den Wert> 6.Aber da eine Variable sofort seinen Wert bekommt,ist y1 dann> 3*y2=18.
Kann ja sein, dass ich in den letzten 17 Jahren, die ich mit VHDL
rummache, was grob verpennt habe, aber diese Aussage ist doch Unsinn.
Die Zuweisung auf y1 nimmt den Wert von y2, der beim Start des Prozesses
aktuell ist, y1 verändert sich nach dieser Zuweisung nicht mehr. Wäre ja
noch schöner, dass spätere Signalzuweisungen RÜCKWIRKEND sind... Der
einzige hier relevante Unterschied zwischen Variablen und Signalen ist
doch nur, dass man den Wert einer Variable im selben Prozessdurchlauf
noch nutzen und auch wieder ändern kann.
Und daher ist die Musterlösung falsch (soll's geben, dass die
Aufgabensteller auch nicht wissen, was sie tun).
Alex schrieb:> sorry korrektur im code:> if (clk'event and clk='0' then
Da fehlt auch noch was... ;-)
Alex schrieb:> eure meinung zur wertefolge für diesen abschnitt würde mich> sehr interessieren!
Hübsche kleine komplexe und gar nicht so triviale Aufgabe... ;-)
Tja, da ist es wieder, das Problem mit der Simulation und der realen
Hardware.
Fangen wir mal so an: Nach allgemeiner Lehrmeineung ist die Variable y1
ist nicht speichernd, sondern rein kombinatorisch. Deshalb kommen bei
der Synthese auch nur 2*32 Flipflops heraus:
1
entityversuchmachtkluchis
2
port(x:ininteger;
3
y_2:outinteger;
4
y_3:outinteger;
5
clk:instd_logic);
6
endversuchmachtkluch;
7
8
architectureBehavioralofversuchmachtkluchis
9
10
signaly2,y3:integer;
11
12
begin
13
process(clk)
14
variabley1:integer;
15
begin
16
if(clk'eventandclk='0')then
17
y1:=3*y2;
18
y2<=x+2;
19
y3<=y1+y2;
20
endif;
21
endprocess;
22
23
y_2<=y2;
24
y_3<=y3;
25
endBehavioral;
1
Macro Statistics
2
# Registers : 64
3
Flip-Flops : 64
Damit MUSS zwingend in der Hardware die Variable y1 gleich nachdem y2
nicht mehr undefiniert ist, einen neuen Wert bekommen. Kurz: sobald y2
nicht mehr undefiniert ist, ist auch y1 nicht mehr undefiniert.
Soweit die Hardware.
In der Simulation ist es allerdings so, dass y1 nur und genau bei der
fallenden Taktflanke interessant ist! Und was ist mit der Zeit zwischen
den beiden Takten? Was macht y1 dort? Weil ja kein neuer Wert zugewiesen
wird, muss der Wert von y1 ja eigentlich den letzten zugewiesenen Wert
beibehalten. Aber jetzt gilt: Behalten=Speichern.
Blöde Situation...
Die Simulation sagt: speichern
die Synthese sagt: nicht speichern
Und: beide haben recht.
Die Simulation umgeht das Problem, indem ja sofort als erstes beim
nächsten Takt der "alte" Wert überschrieben wird, und daher das
Speicherverhalten hinfällig ist, weil der gespeicherte Wert nicht
verwendet wird.
Und die Synthese macht sich zu Nutzen, dass die Variable y1 nicht
ausserhalb des Prozesses verwendet wird.
Sobald ich das nämlich mache, brauche ich weitere 32 Flipflops:
1
entityversuchmachtkluchis
2
port(x:ininteger;
3
y_1:outinteger;
4
y_2:outinteger;
5
y_3:outinteger;
6
clk:instd_logic);
7
endversuchmachtkluch;
8
9
architectureBehavioralofversuchmachtkluchis
10
11
signaly2,y3:integer;
12
13
begin
14
process(clk)
15
variabley1:integer;
16
begin
17
if(clk'eventandclk='0')then
18
y1:=3*y2;
19
y2<=x+2;
20
y3<=y1+y2;
21
endif;
22
y_1<=y1;-- y1 nach aussen geben
23
endprocess;
24
25
y_2<=y2;
26
y_3<=y3;
27
endBehavioral;
1
Macro Statistics
2
# Registers : 96
3
Flip-Flops : 96
Klar, denn jetzt MUSS auch y1 speichernd sein!
Alex schrieb:> nun habe ich aber zwei unterschiedliche meinungen bekommen
Interessanter ist doch eigentlich, was deine Meinung zum Thema ist...
:-/
Hallo Lothar!
meine meinung war die zweite tabelle und damit dass die musterlösung
falsch ist, ich konnte es nur nicht so gut begründen und war nicht
sicher.
vielen dank für die ausführliche antwort! :)
Alex schrieb:> dass die musterlösung falsch istDas habe ich nicht behauptet. Die Musterlösung entspricht der
Hardware: sofort nachdem sich y2 ändert, ändert sich auch die Variable
y1. Sie passt aber nicht zur Simulation, denn dort ändert sich y1 erst
beim nächsten Takt...
Der Fehler liegt eigentlich darin, dass es absolut sinnlos ist, einer
Variablen, die 1.) ausserhalb des Prozesses nicht existiert und 2.)
keinen Zeitbezug hat, ausserhalb eines Prozesses in ein Zeitdiagramm
einzuzeichnen...
> Die Musterlösung entspricht der Hardware.
Was aber hier irrelevant ist, weil eben keine Schaltung mit den
Abgriffen gezeigt ist, sondern nur eine Beschreibung dazu. Und da man
nicht von irgendeiner bestimmten Art der Synthese ausgehen kann, ist nur
IMO das wichtig, was ein Simulator aus der Beschreibung produziert. Und
da ist es vom Ablauf her klar definiert, dass es in dem einen Durchlauf
keine Rückwirkungen von Signalzuweisungen auf Variablen gibt. Das würde
ja auch dann nie zu einem Fixpunkt führen. Denn warum sollte man die
Signale dann nicht gleich wieder updaten wollen, wenn sich eine Variable
geändert hat, die die Grundlage dazu ist...
> Der Fehler liegt eigentlich darin, dass es absolut sinnlos ist...
Genau...
Und aus dem Grund sage ich meinen Studis, dass es für die simplen
Aufgaben in den Klausuren/Praktika&Co keine Variablen braucht. Und wer
sie doch hernimmt, zu 99.9999% damit garantiert einen Fehler macht
und/oder die Aufgabe nicht verstanden hat.
Ich nehm sie selber ab und zu her, aber eigentlich immer nur, um das
Schreiben von oft benutzen Ausdrücken bzw. Bedingungen in einem Prozess
zu vermeiden. Dass sie über einen Takt hinaus speichern müssen, ist
gaaaanz selten. Debugging mit/von Variablen ist ja auch eine mühsame
Angelegenheit...
Georg A. schrieb:> Und da ist es vom Ablauf her klar definiert, dass es in dem einen> Durchlauf keine Rückwirkungen von Signalzuweisungen auf Variablen gibt.
Es ist sogar noch schlimmer: obwohl sich eine Variable ändert, und diese
Änderung eigentlich eine Neuberechnung eines Prozesses nötig machen
würde, wird dieser Prozess nicht neu berechnet, weil die Variable
nicht in die Sensitivliste aufgenommen werden kann!
Das führt dann wieder zum Klassiker im
Beitrag "Re: Variable vs Signal"
> Es ist sogar noch schlimmer: obwohl sich eine Variable ändert, und diese> Änderung eigentlich eine Neuberechnung eines Prozesses nötig machen> würde, wird dieser Prozess nicht neu berechnet, weil die Variable> nicht in die Sensitivliste aufgenommen werden kann!
Und genau das zeigt recht deutlich, dass Variablen eigentlich nur ein
kleines syntaktisches Feature von VHDL sind, um sowas
if komplizierte_berechnung(a,b,c,d) and x then...
end if;
if !komplizierte_berechnung(a,b,c,d) and y then...
end if;
durch
v:=komplizierte_berechnung(a,b,c,d);
if v and x then...
endif
if !v and y then...
endif
ersetzen zu können. Also eine Art manuelles CSE, um den Code wart/lesbar
zu halten und im BehaviouralMode einfacher SW schreiben zu können.
Georg A. schrieb:> Die Zuweisung auf y1 nimmt den Wert von y2, der beim Start des Prozesses> aktuell ist
Ich glaube dass,wir dasselbe meinen.vielleicht falsch ausgedruckt.sorry
wie Lothar es schön sagt,die Synthese unterscheidet sich von der
Simulation sehr,hier was Variablen angeht.