Forum: FPGA, VHDL & Co. Signale und Variablen: Unklarheit bei Zuordnung


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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
signal y3, ye: integer;
2
3
process (clk)
4
   variable y: integer;
5
begin
6
   if (clk'event and clk='0' then
7
     y1 := 3*y2;
8
     y2 <= x+2;
9
     y3 <= y1+y2;
10
   end if;
11
end process;

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!

von Alex (Gast)


Lesenswert?

sorry korrektur im code:
es muss natürlich
1
signal y2, y3: integer;
2
3
process (clk)
4
   variable y1: integer;
5
begin
6
   if (clk'event and clk='0' then
7
     y1 := 3*y2;
8
     y2 <= x+2;
9
     y3 <= y1+y2;
10
   end if;
11
end process;

heißen. entschuldigung

von Mus (Gast)


Lesenswert?

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

von Alex (Gast)


Lesenswert?

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?

von Georg A. (georga)


Lesenswert?

> 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).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
entity versuchmachtkluch is
2
   port ( x : in integer;
3
          y_2 : out integer;
4
          y_3 : out integer;
5
          clk : in std_logic);
6
end versuchmachtkluch;
7
8
architecture Behavioral of versuchmachtkluch is
9
10
signal y2, y3: integer;
11
12
begin
13
  process (clk)
14
   variable y1: integer; 
15
  begin
16
   if (clk'event and clk='0') then
17
     y1 := 3*y2;
18
     y2 <= x+2;
19
     y3 <= y1+y2;
20
   end if;
21
  end process;
22
23
  y_2 <= y2;
24
  y_3 <= y3;
25
end Behavioral;
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
entity versuchmachtkluch is
2
   port ( x : in integer;
3
          y_1 : out integer;
4
          y_2 : out integer;
5
          y_3 : out integer;
6
          clk : in std_logic);
7
end versuchmachtkluch;
8
9
architecture Behavioral of versuchmachtkluch is
10
11
signal y2, y3: integer;
12
13
begin
14
  process (clk)
15
   variable y1: integer; 
16
  begin
17
   if (clk'event and clk='0') then
18
     y1 := 3*y2;
19
     y2 <= x+2;
20
     y3 <= y1+y2;
21
   end if;
22
   y_1 <= y1;     -- y1 nach aussen geben
23
  end process;
24
25
  y_2 <= y2;
26
  y_3 <= y3;
27
end Behavioral;
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... 
:-/

von Alex (Gast)


Lesenswert?

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! :)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alex schrieb:
> dass die musterlösung falsch ist
Das 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...

von Georg A. (georga)


Lesenswert?

> 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...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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"

von Georg A. (georga)


Lesenswert?

> 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.

von Mustafa (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.