Hallo,
Ich frage mich wie ein auf 1-Setzen eines Signals 'A' programmiert
werden kann, welches vom Zustand eines anderen Signals 'B' abhängig ist.
Dabei soll das auf 1 zu setzende Signal 'A' nur 1 Clk, nach setzen des
Signals 'B' wieder rückgesetzt werden.
--> Wie z.b. im Userguide UG586 des MIG Version 2.4 auf Seite 162,
Figure 1-74.
Hier wird ein Signal 'A' gesetzt, während gleichzeitig ein Signal 'B'
rückgesetzt wird.
Nach Setzen des Signals 'B' ist dass Signal 'A' lediglich noch 1 Clk
lang auf 1.
Mir fällt nur diese Lösung ein:
Initialisierung :
wdf_rdy <= 1;
wdf_rdy_merk <= 0;
1
ifrising_edge(SYS_clk)then
2
wdf_rdy_merk<=wdf_rdy;
3
ifwdf_rdy_merk='1'then--Daten übernommen
4
wdf_wren<='0';
5
state<=idle;
6
else--Kommando anlegen
7
wdf_wren<='1';
8
endif;
9
endif;
Es scheint denkbar, dass im 1. Clk, der wdf_rdy_merk sowie wdf_wren auf
1 gesetzt werden.
Beim 2. Clk ist wdf_rdy_merk = '1', folglich wird wdf_wren = 0.
Warum ist wdf_wren nun > 1 CLK lang auf 1?
Ich denke Dein Code zeigt ein häufig auftretendes Mißverständnis:
Nämlich, dass der Code, genau wie ein imperatives Programm zu
interpretieren ist. Du siehst eine Folge von:
wdf_rdy_merk <= wdf_rdy;
if wdf_rdy_merk = '1' then --Daten übernommen
und nimmst an, dass die Bedingung des if (im Kontext mit dem früher
geschriebenen wdf_rdy <= 1;) wahr sein müsste, weil ja wdf_rdy_merk eine
1 zugewiesen wurde.
Das aber ist so nicht richtig.
Vielmehr beschreibst Du in VHDL Strukturen. Die "Zuweisung" wdf_rdy_merk
<= 1 ist eine Struktur. Die "if-Anweisung" ist eine Struktur. Beide sind
unabhängig voneinander und sind nicht kausal verbunden. (Jedenfalls in
einem anderen Sinne, als Du das annimmst).
Das ist der tiefere Sinn, des hier so oft zu lesenden Einwurfs: In VHDL
schreibt man keine Programme sondern man beschreibt Strukturen.
Matze schrieb:> Hier wird ein Signal 'A' gesetzt, während gleichzeitig ein Signal 'B'> rückgesetzt wird.
Ist das Setzen des zweiten Signals nicht eher eine Folge des gesetzten
ersten Signals? Denn "gleichzeitig" gibt es nicht in der Hardware.
Sondern es gibt eine Taktflanke und einen Zustand davor, der zu einem
Zustand danach führt. Und dann kommt wieder eine Taktflanke... usf...
> Ich frage mich wie ein auf 1-Setzen eines Signals 'A' programmiert> werden kann, welches vom Zustand eines anderen Signals 'B' abhängig ist.>> Dabei soll das auf 1 zu setzende Signal 'A' nur 1 Clk, nach setzen des> Signals 'B' wieder rückgesetzt werden.> --> Wie z.b. im Userguide UG586
Du hättest da einfach einen Screenshot anhängen können...
Wie auch immer: was dort zu sehen ist, ist stinknormales synchrones
Design ohne jegliche Merker oder sonstwas. Der Code für diese Reaktion
ist einfach sowas:
Du kannst diesen Code übrigens ohne jegliche Änderung im
Syntheseergebnis(!!!) auch so schreiben:
1
ifrising_edge(SYS_clk)then
2
ifwdf_rdy_merk='1'then--Daten übernommen
3
wdf_wren<='0';
4
state<=idle;
5
else--Kommando anlegen
6
wdf_wren<='1';
7
endif;
8
wdf_rdy_merk<=wdf_rdy;
9
endif;
Denn ein jedes Signal übernimmt den "neuen" Wert erst am Ende eines
Prozesses oder beim nächsten wait...
Matze schrieb:> Ich frage mich wie ein auf 1-Setzen eines Signals 'A' programmiert> werden kann
Warum heißt es VHDL und nicht VHPL? Weil es eine "Description Language"
und keine "Programming Language" ist. Du musst also deine Hardware
beschreiben. Und dazu musst du dir erst mal vorstellen, wie diese
Hardware aussehen soll. Das tust du nicht, sondern du "programmierst"
einfach mal drauf los...
Zu einem Zeitpunkt x wird wdf_wren = 1 gesetzt.
Zum Zeitpunkt x+1,
soll für den fall dass wdf_rdy zu Zeitpunkt x = 1 war, wdf_wren = 0
werden.
falls wdf_rdy zu Zeitpunkt x = 0 war, so soll wdf_wren = 1 bleiben.
--> wdf_wren soll so lange auf 1 bleiben.
--> Bis festgestellt wird dass wdf_rdy im unmittelbar vorhergehenden
Zustand --> 1 war.
Meine Variante braucht 2 Zyklen, um wdf_wren = 0 zu setzen, nachdem
wfd_rdy = 1 ist.
Denn im Takt 4 wird der Merker erst mit 1 beschrieben.
Bis wdf_wren = 0 wird, braucht es noch einen Takt.
Ist der beigefügte Ablauf korrekt?
Und wenn ja, wie kann ein Rücksetzen von wdf_wren zum Takt 4 erfolgen?
Matze schrieb:> Zum Zeitpunkt x+1, soll für den fall dass wdf_rdy zu Zeitpunkt x = 1> war, wdf_wren = 0 werden.> falls wdf_rdy zu Zeitpunkt x = 0 war, so soll wdf_wren = 1 bleiben.
Wenn ich nur das und genau das umsetzen soll und keine weiteren
Forderungen bestehen, dann könnte ich das so beschreiben:
1
ifrising_edge(SYS_clk)then
2
wdf_wren<=notwdf_rdy;
3
endif;
Matze schrieb:> --> wdf_wren soll so lange auf 1 bleiben.> --> Bis festgestellt wird dass wdf_rdy im unmittelbar vorhergehenden> Zustand --> 1 war.
Ok, dann diese Beschreibung:
1
ifrising_edge(SYS_clk)then
2
:
3
:
4
ifwdf_rdy='1'then
5
wdf_wren<='0';
6
endif;
7
:
8
:
9
endif;
Kommt dir das bekannt vor? Ja, ich hatte es schon mal gepostet...
Dort steht: wenn zur steigenden Flanke vom Takt wdf_rdy high ist, dann
wird als Folge das Flipflop wdf_wren auf low gesetzt.
Nun, dann lass doch den Merker einfach weg. Dessen setzen führt erst die
Verzögerung ein. Ein gedankliches Problem dabei ist auch oft, ab wann
man die Takte zählt, bzw. ob man einen Zustand bei der Flanke betrachtet
(das ist ja die Aussage des Codes) oder ob man eine Änderung während der
Zeit zwischen zwei Flanken betrachtet.
In Deinem Code kommt etwas wie "state <= idle" vor. Du benutzt also
vermutlich ohnehin eine Zustandsmaschine. Das kannst Du ja nutzen, in
dem ein Zustand auch ein "Merker" ist.
Setzen wir voraus, Du kommst von einem Zustand "Initiate-Command" in
einen Zustand "Enabled-Wait-Ready" in dem wren bei Übergang dahin auf 1
gesetzt wurde und in dem Du auf 'ready' wartest. Etwa so:
state
Initiate-Command wdf_wren <= '1'; state <= Enabled-Wait-Ready;
Enabled-Wait-Ready if wdf_rdy = '1' then state <= Ready; else state
<= Enabled-Wait-Ready;
Ready wdf_wren <= '0'; -- rdy war im vorherigen Takt 1
state <= Following-State;
Following-State
Dieser Zwischenzustand Enabled-Wait-Ready sorgt dafür, dass noch ein
weiterer Takt vergehen muss, ehe wren wieder auf 0 gesetzt wird.
Das wäre wörtlich, das Verhalten, dass Du mit dem Satz: "soll für den
fall dass wdf_rdy zu Zeitpunkt x = 1 war, wdf_wren = 0
werden." beschreibst.
Falls aber wren bei dem nächsten Takt gesetzt werden soll, nachdem rdy =
1 geworden ist, dann lässt Du den Zwischenzustand einfach weg.
state
Initiate-Command wdf_wren <= '1'; state <= Enabled-Wait-Ready;
Enabled-Wait-Ready if wdf_rdy = '1' then wdf_wren <= '0'; state <=
Following-State; else state <= Enabled-Wait-Ready;
Following-State