Forum: FPGA, VHDL & Co. ungewöhliche Reihenfolge eines Async-Resets


von Daniel (Gast)


Lesenswert?

Hallo Leute,

ich habe da mal einen (mir zumindest) ungewöhlichen Vorschlag eines 
async. Resets.

Die übliche Reihenfolge ist ja (Variante a):
1
process(clk, rst)
2
begin
3
  if rst = '1' then
4
    a <= '0';
5
  elsif rising_edge(clk) then
6
    ...
7
    a <= xyz;
8
    ...
9
  end if;
10
end process;

Jetzt birgt diese Reihenfolge jedoch einen Fallstrick. Wenn im 
getakteten Zweig noch andere Signalen Werte zugewiesen werden, baut die 
Synthese für diese Signal eine "Hold"-Logik auf, die das Signal beim 
Reset vor Veränderung bewahrt. Das ist zwar evtl. nicht beabsichtigt, 
wurde aber so beschrieben und benötigt zumindest Routing-Ressourcen.

In einem Process gilt ja die letzte Zuweisung eines Signals, so dass 
sync. Resets auch gerne so geschrieben werden:
1
if rising_edge(...) then
2
  ..
3
  a <= xyz;
4
  b <= abc;
5
  ...
6
  if rst = '1' then
7
    a <= '0';
8
  end if;
9
end if;

Was spricht jetzt also dagegen, diese Reihenfolge auch beim async. Reset 
zu verwenden (Variante b)?
1
process(clk, rst)
2
begin
3
  if rising_edge(clk) then
4
    ...
5
    a <= xyz;
6
    b <= abc;
7
    ...
8
  end if;
9
10
  if rst = '1' then
11
    a <= '0';
12
  end if;
13
end process;

Diese Reihenfolge ist mir noch nie untergekommen, jedoch funktioniert 
sie hervorragend mit der Xilinx-Toolchain (getestes mit 13.2).

Ist das laut VHDL-Standard verboten? Oder ist es "nur" nicht empfohlen, 
weil z.B. andere Toolchains damit nicht umgehen können? Wäre das dann 
dort nicht ein Fehlverhalten?

grüße

von user (Gast)


Lesenswert?

der VHDL Standard erlaubt alle deine Beschreibungen, ist also reine 
Geschmackssache

von Ingenieur (Gast)


Lesenswert?

Der Punkt ist der , dass alles, was unter risign-edge steht nur in einem 
infintisimalen Zeitfenster gilt und der rst da überlagert.

du solltest dich aber - gerade bei xilinx - von asynchronen resets 
verabschieden!

die gehören maximal an eine pll und auch nur an eine einzige master pll

von Daniel M. (daniel__m)


Lesenswert?

mir ist sehr wohl bekannt, dass man sich sehr gut überlegen muss, ob man 
Sets und Resets (sei es sync. oder async: gilt für beide!!) überhaupt 
verwendet. Diese Überlegung ist nicht auf Design oder Entity-Ebene zu 
fällen, sondern einzeln für jedes Signal neu, und zwar so: wie bekomme 
ich mein vorgeschriebenes Verhalten mit minimalen sync. oder async. 
Set/Resets hin?

Ingenieur schrieb:
> du solltest dich aber - gerade bei xilinx - von asynchronen resets
> verabschieden!

Kannst du das weiter ausführen oder die App-Note nennen? Wenn es bei 
Xilinx bald keine asynchronen Set/Reset mehr gibt, dann wäre es sehr 
schlecht für uns und wir können diese Chips nicht einsetzen.

Wir haben halt die Vorgabe, dass das System sich zu jedem Zeitpunkt und 
egal in welchen Zustand wieder in einen vorgegebenen Zustand gesetzt 
werden kann. Und sync. Resets sind da ungeeignet, da ich immer noch 
einen Takt dafür benötige.

Und was meinst du mit
> infintisimalen Zeitfenster
? Wenn ich mir das Syntheseegebnis anschaue, dann macht er für die 
resetteten Signal genau die gleiche Netzliste, wie die Variante a, nur 
dass ich nicht darauf achten muss, dass alle im Prozess verwendete 
Signale im Reset-Zeig auch aufgeführt werden, um unnötige Logik zu 
vermeiden.

Grüße

von Christian R. (supachris)


Lesenswert?

Daniel M. schrieb:
> Kannst du das weiter ausführen oder die App-Note nennen? Wenn es bei
> Xilinx bald keine asynchronen Set/Reset mehr gibt, dann wäre es sehr
> schlecht für uns und wir können diese Chips nicht einsetzen.

WP272 von Xilinx. Aber geben wirds die aus den von dir genannten Gründen 
sicherlich noch lange. Man muss sich halt bewusst sein, dass sie 
Ressourcen fressen und evtl. das ganze Design verlangsamen. Wenn man die 
ganz bewusst an einzelnen Signalen einsetzt (und das Reset-Release dann 
synchronisiert) ist das ja völlig legitim. Man sollte halt nur nicht das 
ganze System asynchron reseten wie das in fast allen VHDL Büchern steht.

von Daniel M. (daniel__m)


Lesenswert?

Christian R. schrieb:
> WP272

kenn ich.

Das führt mich ja auch zu meiner ursprünglichen Frage mit der Variante 
b. Ich habe diese Variante halt noch nie gesehen, weder von Xilinx noch 
von "alten Hasen" (z.B. von Lothar ;) ). Damit kann ich einzelne Signal 
gezielt resetten, ohne die anderen Signale:

a) mit resetten zu müssen, damit der Zeig vollständig ist (gut, bei 
std_logic-basierten Signalen kann ich '-' zuweisen, das geht auch, aber 
was mache ich bei boolean oder integer?)

b) zu ignorieren, was zusätzliche "Hold"-Logik erzeugt

c) in eine anderen Prozess auslagern zu müssen, welcher keinen 
Reset-Zweig hat. Das ist aber spätestens bei komplexeren State-Machines 
ungünstig, da ich die Dekodierung u.u. doppelt angeben muss (Thema 
Wartbarkeit). Und ist übrigens syntheseidentisch mit der Variante b.

Grüße

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


Lesenswert?

Daniel M. schrieb:
> Das führt mich ja auch zu meiner ursprünglichen Frage mit der Variante
> b. Ich habe diese Variante halt noch nie gesehen, weder von Xilinx noch
> von "alten Hasen" (z.B. von Lothar ;) ). Damit kann ich einzelne Signal
> gezielt resetten, ohne die anderen Signale:
Dann hat der "Reset" seinen Namen nicht verdient. Wenn schon ein Reset, 
dann
sollte der den ganzen entsprechenden Beschreibungsteil in einen 
definierten Zustand versetzen, nicht nur die Hälfte...

> b. Ich habe diese Variante halt noch nie gesehen, weder von Xilinx noch
> von "alten Hasen" (z.B. von Lothar ;) ).
Je weiter du von der "üblichen", dekumentierten und empfohlenen 
Schreibweise wegkommst, umso mehr läufst du Gefahr, bei der nächsten 
Softwaregeneration vor einem Schrotthaufen zu stehen.

Und wie gesagt: "Xilinx", "synchrones Design" und "asynchrone Resets" 
passen nicht zusammen. Mehr dazu in den Links vom 
Beitrag "Xilinx und die Resets"

von Daniel M. (daniel__m)


Lesenswert?

Warum sollte ich einen komletten Beschreibungsteil in einen Reset 
zwingen, wenn nur wenige Signale Reset-relevant sind?

kleines Beispiel:
1
...
2
  signal cnt : integer range -1 to 12345;
3
..
4
process(clk,rst)
5
begin
6
  if rising_edge(clk) then
7
    case state is
8
      when IDLE =>
9
        cnt <= 12345;
10
        if start = '1' then
11
          state <= RUNNING;
12
        end if;
13
14
      when RUNNING =>
15
        if cnt < 0 then
16
          state <= IDLE;
17
        else
18
          cnt <= cnt - 1;
19
        end if;
20
    end case;
21
  end if;
22
23
  if rst = '1' then
24
    state <= IDLE;
25
  end if;
26
end process;

Der Zähler löst ausserhalb des Prozesses keine Aktion aus. Im Reset-Fall 
(sei es nun async. oder sync.) reicht es daher, lediglich die SM zu 
resetten.

Das Synthesetool wird nun die (re)set-Eingänge der FF des cnt-Signals 
nutzen, um im state IDLE den Wert 12345 zu laden.

Würde ich im o.g. Beispiel den async. Reset oberhalb schreiben, gibt es 
2 Möglichkeiten:

a) ich gebe das cnt-Signal nicht an: die CE-Eingänge des cnt-Signals 
werden ein höhere Logik aufweisen, weil eine "HOLD"-Logik während des 
Reset benötigt wird.

b) ich Resette z.B. auf 0 oder 12345: die FF des cnt-Signals haben jetzt 
keinen sync. (re)set-Eingang mehr und der Startwert muss über die LUTs 
nachgebaut werden.

Klar, ich könnte das cnt-Signal in einen neuen Prozess auslagern und 
dort zählen lassen, aber ich hätte der Übersichtlichkeit wegen gern 
relevante Dinge zusammen.

Daher die Frage: kennt jemand Fälle, in der diese Variante des Resets 
nicht funktionieren würde?

von Klaus (Gast)


Lesenswert?

Daniel M. schrieb:
> Das Synthesetool wird nun die (re)set-Eingänge der FF des cnt-Signals
> nutzen, um im state IDLE den Wert 12345 zu laden.

Nein, wird es nicht. Denn das sind asynchone Eingänge. Die werden nicht 
genutzt, um dort Taktsynchron einen Wert zu laden. Es wird viel mehr ein 
Multiplexer am D Eingang der zum Counter gehörenden Register erzeugt.

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


Lesenswert?

Daniel M. schrieb:
> Im Reset-Fall
Wann tritt der denn auf? Und warum?
Ist das der brüchtigte Taster für den Entwickler?

von Daniel M. (daniel__m)


Lesenswert?

Klaus schrieb:
> Daniel M. schrieb:
>> Das Synthesetool wird nun die (re)set-Eingänge der FF des cnt-Signals
>> nutzen, um im state IDLE den Wert 12345 zu laden.
>
> Nein, wird es nicht. Denn das sind asynchone Eingänge. Die werden nicht
> genutzt, um dort Taktsynchron einen Wert zu laden. Es wird viel mehr ein
> Multiplexer am D Eingang der zum Counter gehörenden Register erzeugt.

auch wenn die Antwort kindisch ist: doch!

Die Eingänge sind erst dann async., wenn ich den async. (re)set nutze. 
Beschreibe ich keinen (expliziten) (a)sync. Reset, wird das Synthesetool 
die Eingänge nach eigenem gutdünken nutzen. Das zeigt mir die Netzliste 
nach der Synthese!

Das was du beschreibst, macht die Synthese, wenn ich einen async. Reset 
explizit nutze und das Signal z.B. auf 12345 setze.

Grüße

von Klaus (Gast)


Lesenswert?

Daniel M. schrieb:
> Die Eingänge sind erst dann async., wenn ich den async. (re)set nutze.
> Beschreibe ich keinen (expliziten) (a)sync. Reset, wird das Synthesetool
> die Eingänge nach eigenem gutdünken nutzen. Das zeigt mir die Netzliste
> nach der Synthese!
>
> Das was du beschreibst, macht die Synthese, wenn ich einen async. Reset
> explizit nutze und das Signal z.B. auf 12345 setze.

Bei Xillinx lassen sich die set und reset Eingänge der FFs auch als 
synchrone Eingänge konfigurieren? Wenn dem so ist: Dann hast du 
natürlich vollkommen recht. Das wusste ich nicht, dass das geht.

von Daniel M. (daniel__m)


Lesenswert?

Das Reset-Signal ist z.B. eine Board-Reset/Freigabe-Leitung und wird 
durch einen Supervisor-Chip erzeugt. Dort laufen mehrere Status-Signale 
diverser Hardware-Komponenten zusammen und wenn ein Fehlverhalten 
erkannt wird, kann einzeln oder global ein Reset ausgelöst werden.

Und das Signal wird nicht direkt verwendet, sondern durch einen 
Synchronizer verlängert, so dass es synchronisiert gelöst wird. Man kann 
also sagen, es geht asynchron in den Reset (also auch ohne Takt), aber 
nur synchron raus. In diesen Synchronizer werden u.a. auch diverse 
PLL/MMCM/DCM/etc. berücksichtigt.

Grüße

von Daniel M. (daniel__m)


Lesenswert?

Klaus schrieb:

> Bei Xillinx lassen sich die set und reset Eingänge der FFs auch als
> synchrone Eingänge konfigurieren?

Je nach FPGA werden unterschiedlich viele LUT-FF Paare in Slices 
zusammengefasst und für jedes Slice wird festgelegt, ob der (re)set 
sync. oder async. ist.

Geht das bei anderen Herstellern nicht? Das würde mich jetzt aber 
wundern.

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


Lesenswert?

Klaus schrieb:
> Bei Xillinx lassen sich die set und reset Eingänge der FFs auch als
> synchrone Eingänge konfigurieren? Wenn dem so ist: Dann hast du
> natürlich vollkommen recht. Das wusste ich nicht, dass das geht.
Du hast meinen Post oben im 
Beitrag "Re: ungewöhliche Reihenfolge eines Async-Resets" und den Verweis auf 
die Links nicht gesehen? Lies dazu mal das WP275...

Daniel M. schrieb:
> es geht asynchron in den Reset (also auch ohne Takt), aber
> nur synchron raus.
Dann nimm doch gleich einen synchronen Reset. Und lies auch mal das 
WP275...

von Lattice User (Gast)


Lesenswert?

Lothar Miller schrieb:
> Daniel M. schrieb:
>> es geht asynchron in den Reset (also auch ohne Takt), aber
>> nur synchron raus.
> Dann nimm doch gleich einen synchronen Reset. Und lies auch mal das
> WP275...

Bei allem Respekt, das ist nicht das gleiche. Das was Daniel macht ist 
übrigens die in WP272 empfohlene Vorgehensweise für einen Reset der auch 
ohne Clock funktionieren muss.

Ausserdem wette ich dass Daniel auch WP275 gelesen hat, deswegen will er 
ja das Reset auf so wenig FF wie möglich wirken lassen. Er sucht dazu 
nur eine Beschreibung die (für ihn) übersichtlicher ist als die 
Aufteilung in mehrere Prozesse.

von Daniel M. (daniel__m)


Lesenswert?

Lattice User schrieb:
> Lothar Miller schrieb:
>> Daniel M. schrieb:
>>> es geht asynchron in den Reset (also auch ohne Takt), aber
>>> nur synchron raus.
>> Dann nimm doch gleich einen synchronen Reset. Und lies auch mal das
>> WP275...
>
> Bei allem Respekt, das ist nicht das gleiche. Das was Daniel macht ist
> übrigens die in WP272 empfohlene Vorgehensweise für einen Reset der auch
> ohne Clock funktionieren muss.
>
> Ausserdem wette ich dass Daniel auch WP275 gelesen hat, deswegen will er
> ja das Reset auf so wenig FF wie möglich wirken lassen. Er sucht dazu
> nur eine Beschreibung die (für ihn) übersichtlicher ist als die
> Aufteilung in mehrere Prozesse.

Danke, genau meine Absicht. Ich habe schon befürchtet, dass ich mich 
(mal wieder) nicht verständlich ausdrücken konnte.

von Daniel M. (daniel__m)


Lesenswert?

Lothar Miller schrieb:
> Daniel M. schrieb:
>> es geht asynchron in den Reset (also auch ohne Takt), aber
>> nur synchron raus.
> Dann nimm doch gleich einen synchronen Reset. Und lies auch mal das
> WP275...

Das hat nicht das gleiche Verhalten.

Beispiel: der FPGA würde für eine Motorsteuerung verwendet und lässt den 
Motor normal anlaufen. Irgendwann fällt (warum auch immer) der Takt aus. 
Wenn der Reset synchron wäre, könnte ich den FPGA jetzt nicht in einen 
neutralen Zustand zwingen und der Motor würde weiterlaufen (da ich ja 
immer noch einen Takt benötige). Mit dem asynchronen Reset geht das ohne 
Probleme.

Aber ich möchte nur die nötigen Signale behandeln und trotzdem 
übersichtlichen, verständlichen und damit wartungsfreundlichen Code 
erzeugen.

von Ingenieur (Gast)


Lesenswert?

Daniel M. schrieb:
> Und das Signal wird nicht direkt verwendet, sondern durch einen
>
> Synchronizer verlängert, so dass es synchronisiert gelöst wird. Man kann
>
> also sagen, es geht asynchron in den Reset (also auch ohne Takt), aber
>
> nur synchron raus. In diesen Synchronizer werden u.a. auch diverse
>
> PLL/MMCM/DCM/etc. berücksichtigt.


????

löst nicht das problem der nicht-gleizeitigkeit im system und unter 
betrachtung der komponenten braucht es das nicht, weil dann auch jder 
einzeln synchronieren kann

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


Lesenswert?

Lattice User schrieb:
> Lothar Miller schrieb:
>> Daniel M. schrieb:
>>> es geht asynchron in den Reset (also auch ohne Takt), aber
>>> nur synchron raus.
>> Dann nimm doch gleich einen synchronen Reset. Und lies auch mal das
>> WP275...
> Bei allem Respekt, das ist nicht das gleiche.
Richtig, das mit dem asynchron setzen und synchron loslassen hatten wir 
vor kurzem schonmal im 
Beitrag "Re: Detailfrage Reset"

Und da ging es auch um solche pseudo-sicherheitskritische dinge wie das,
was Daniel M. schrieb:
> Beispiel: der FPGA würde für eine Motorsteuerung verwendet und lässt den
> Motor normal anlaufen. Irgendwann fällt (warum auch immer) der Takt aus.
> Wenn der Reset synchron wäre, könnte ich den FPGA jetzt nicht in einen
> neutralen Zustand zwingen und der Motor würde weiterlaufen (da ich ja
> immer noch einen Takt benötige). Mit dem asynchronen Reset geht das ohne
> Probleme.
Wenn es in diesem System etwas gibt, das erkennt, dass der Takt fehlt 
(Watchdog), dann hat der direkt auf die Motortreiber zu gehen. Denn was 
hilft es, das FPGA ohne Takt partiell zurückzusetzen, wenn evtl. dieser 
Resetzustand gar nicht bis zum Motortreiber durchkommt.

Man kann sich für alles ein Gedankengebilde zaubern, aber in der 
praxis wird Sicherheitstechnik mit getakteten Bauteilen (uCs) gemacht. 
Und das reicht offenbar aus...

von Klaus (Gast)


Lesenswert?

Also ich häng den Entwicklerreset Knopf, und auch den Reset-Controller 
für POR und Brownnout, einfach direkt an die nConfig-Leitung des FPGAs. 
Setzt garantiert und ohne eine Zeile Code das FPGA in den 
Ausgangszustand zurück =)

von Daniel M. (daniel__m)


Lesenswert?

Klaus schrieb:
> Setzt garantiert und ohne eine Zeile Code das FPGA in den
> Ausgangszustand zurück =)

Vorausgesetzt, ich will den kompletten FPGA resetten. Aber ein Vorteil 
von FPGAs ist ja die echte Parallelität. Ich könnte dann Module im FPGA, 
die thematisch etwas völlig anderes machen, nicht weiterlaufen lassen.

Des Weiteren ist der FPGA als Slave-Device konfiguriert. Mit dem nConfig 
würde ich doch ein erneutes Laden des Bitstroms einleiten, jedoch 
bekommt der FPGA bei uns seinen Bitstrom von einem externen 
SoC/DSP/Prozessor per parallelen Bus, welcher später für die reguläre 
Kommunikation zwischen denen genutzt wird.

Lothar Miller schrieb:
> Man kann sich für alles ein Gedankengebilde zaubern, aber in der
> praxis wird Sicherheitstechnik mit getakteten Bauteilen (uCs) gemacht.

Ja, kann man. Genauso, wie man für jedes Problem in der Regel auch 
mehrere Lösungen hat, die je nach Gewichtung unterschiedlich gut sind.

Ich wollte hier eigentlich keinen Glaubenskrieg anzetteln, von wegen 
Reset ist notwendig oder Teufelszeug, mit deren Varianten synchron, 
asynchron, partiell oder global.

Es ging mir nur darum, ob jemand eine Begründung kennt, warum die 
Variante b aus dem Start-Posting anscheinend keine Anwendung findet. 
Aussagen, wie "es ist unüblich" oder "das macht keiner", sind für mich 
dabei aber keine Begründung.

grüße

von SuperWilly (Gast)


Lesenswert?

Ich habe die Reset-Beschreibung
1
process(Clk, Reset)
2
begin
3
   if rising_edge(Clk) then
4
5
   end if;
6
7
   if (Reset = '1') then
8
9
   end if;

schon des Öfteren verwendet, hatte bislang keine Probleme damit. Einzig 
und allein Modelsim meckert, wenn man mit "vcom -synthesis_check" 
kompiliert, aber kommt ja auch von einem Simulator ;-)

VG, SuperWilly

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


Lesenswert?

Daniel M. schrieb:
> Es ging mir nur darum, ob jemand eine Begründung kennt, warum die
> Variante b aus dem Start-Posting anscheinend keine Anwendung findet.
1. Es ist nicht in den Büchern/Literatur dokumentiert.
2. Es wird an den (Hoch-)Schulen nicht gelehrt
3. Die Synthesizer konnten das früher nicht.
4. Es ist unüblich.
5. Das Wissen, dass das geht, ist nicht verbreitet.

> Aussagen, wie "es ist unüblich" oder "das macht keiner", sind für mich
> dabei aber keine Begründung.
Du wirst aber keinen besseren Grund finden.


Mein Standardformat eines synchronen Prozesses sieht so aus:
1
process begin
2
   wait until rising_edge(Clk);
3
   ....
4
end process;
Und mit Reset dann so:
1
process begin
2
   wait until rising_edge(Clk);
3
   ....
4
   if (Reset = '1') then
5
   ....
6
   end if;
7
end process;
Warum beschreiben nicht alle einen synchronen Prozess auf diese Art?
Antworten: siehe oben....

von SuperWilly (Gast)


Lesenswert?

;-)

process begin
   wait until Clk='1';
   ....
end process;

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


Lesenswert?

SuperWilly schrieb:
> wait until Clk='1';
Auch hübsch...   ;-)

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.