Guten Morgen,
irrtümlich hatte ich angenommen, dass in solch einem Block:
1
process(clk)
2
begin
3
ifrising_edge(clk)then
4
ifreset='1'then
5
-- initialisierung
6
else
7
-- sonstiges
8
endif;
9
endif;
10
endprocess;
die Initialisierungen im reset-Teil nach der Konfiguration des FPGAs
ausgeführt werden würden, was aber nicht passiert.
Der Reset hängt bei mir an einem externen Taster - ich brauche ihn aber
eigentlich nie.
Was spricht dagegen, den Reset und alle reset-Ifs einfach wegzulassen
und die Initialisierung quasi einmalig mit Default-Werten durchzuführen?
(besp: signal data : std_logic_vector(31 downto 0) := (others => '0') )
Die Reset-Blöcke verbrauchen unnötig viel Resourcen, für das, dass
niemals der Reset ausgelöst wird.
Falls ein Reset notwendig sein müsste - weil sich irgendwas verklemmt
hat - könnte man doch genauso gut das FPGA neu konfigurieren?
Viele Grüße,
Mampf
Mampf F. schrieb:> Was spricht dagegen, den Reset und alle reset-Ifs einfach wegzulassen> und die Initialisierung quasi einmalig mit Default-Werten durchzuführen?
Da spricht nichts dagegen, wenn du die Reset Funktion eigentlich nie
brauchst.
Mampf F. schrieb:> Was spricht dagegen, den Reset und alle reset-Ifs einfach wegzulassen> und die Initialisierung quasi einmalig mit Default-Werten durchzuführen?
Dagegen spräche nur, dass dein Synthesizer oder dein FPGA keine
Initialwerte kann. Wenn sowohl der Synthesizer als auch das FPGA mit
Initwerten umgehen kann, dann musst du keine Reset-Pfade einbauen, wenn
du keine brauchst.
Siehe zu dieser immer wiederkehrenden Frage auch den
Beitrag "FlipFlop initial value bei MachXO2?" und die darin enthaltenen
Links...
Je nach FPGA mag es noch einzelne Besonderheiten geben, die einem nicht
auf den ersten Blick offensichtlich werden.
Bei (zumindest manchen) Altera/Intel Käfern führt ein von '0'
verschiedener Initialwert beispielsweise dazu, dass sich solche Register
nicht mehr in die IOB's verschieben lassen, die
"FAST_OUTPUT_REGISTER"-Option also unwirksam wird.
Markus F. schrieb:> Bei (zumindest manchen) Altera/Intel Käfern führt ein von '0'> verschiedener Initialwert beispielsweise dazu, dass sich solche Register> nicht mehr in die IOB's verschieben lassen, die> "FAST_OUTPUT_REGISTER"-Option also unwirksam wird.
Das liegt daran, dass das FPGA (zumindest bei der Cyclone Familie)
eigentlich keine Init-Werte unterstützt. Alle FFs wachen immer mit 0
auf. Für Register, die eine 1 bekommen sollen, baut der Synthesizer vor
und hinter das FF einen Inverter. Das geht bei IO Zellen natürlich
nicht.
Markus F. schrieb:> Bei (zumindest manchen) Altera/Intel Käfern führt ein von '0'> verschiedener Initialwert beispielsweise dazu, dass sich solche Register> nicht mehr in die IOB's verschieben lassen, die> "FAST_OUTPUT_REGISTER"-Option also unwirksam wird.
Oha, das wusste ich nicht!
Ich hatte tatsächlich vorher erst den Fall, dass ich einen Init-Wert von
'0' auf '1' ändern musste und ich mich danach gewundert habe, wieso das
Design plötzlich 5MHz weniger kann.
Da D. schrieb:> Das liegt daran, dass das FPGA (zumindest bei der Cyclone Familie)> eigentlich keine Init-Werte unterstützt. Alle FFs wachen immer mit 0> auf. Für Register, die eine 1 bekommen sollen, baut der Synthesizer vor> und hinter das FF einen Inverter. Das geht bei IO Zellen natürlich> nicht.
Ist tatsächlich ein Intel/Alter Cyclone (10 LP).
Das heißt, es könnte sinnvoller sein, die Init-Werte zu entfernen und
beim Start des FPGAs den Reset intern einmal zu triggern, damit alles
korrekt initialisiert wird?
Mampf F. schrieb:> Das heißt, es könnte sinnvoller sein, die Init-Werte zu entfernen und> beim Start des FPGAs den Reset intern einmal zu triggern, damit alles> korrekt initialisiert wird?
Ja, für Intel ist die Designstrategie normalerweise einen asynchronen
Reset zu beschreiben, und diesen Reset mit '1' zu initialisieren. Sobald
alle PLLs gelockt sind (bzw. alle Taktquellen stabil sind), wird der
Reset synchron zum Takt auf 0 gesetzt.
Da D. schrieb:> Ja, für Intel ist die Designstrategie normalerweise einen asynchronen> Reset zu beschreiben, und diesen Reset mit '1' zu initialisieren. Sobald> alle PLLs gelockt sind (bzw. alle Taktquellen stabil sind), wird der> Reset synchron zum Takt auf 0 gesetzt.
Ok, verstanden :)
Das heißt, ich muss aber im Reset-Teil nur Signale / Variablen
initialisieren, die einen anderen Init-Wert als '0' haben, richtig?
Mampf F. schrieb:> Das heißt, ich muss aber im Reset-Teil nur Signale / Variablen> initialisieren, die einen anderen Init-Wert als '0' haben, richtig?
Nein :)
Und zwar aus 2 Gründen:
1) Du möchtest nicht, dass ein Teil der Logik schon los läuft, während
andere Register noch im Reset gehalten werden.
2) In einem Prozess nur manche Register zu resetten hat mehr
Logikverbrauch zur folge. Das ist nicht ganz offensichtlich. Folgendes
Beispiel:
1
process(all)
2
begin
3
ifresetthen
4
a<='0';
5
elsifrising_edge(clock)
6
a<=x;
7
b<=y;
8
endif;
9
endprocess;
Welches Verhalten ist nun für das FF 'b' beschrieben? Da steht,
übernehme den Wert 'y', aber nur wenn nicht der reset = 1 ist. Und diese
zusätzliche Bedingung (wenn nicht ...) muss extra in Logik abgebildet
werden.
Auch wenn mir viele, vor allem Xilinx, Entwickler widersprechen, ich
bleibe dabei. Jede finite Schaltung braucht einen Reset. Favorisieren
tue ich eine asynchronen, der von einem Reset Generator, ACPI Reset etc.
ausgelöst werden kann. Aber in Grunde genommen ist es egal, ob synchron
oder asynchron.
Betrachte es etwas makroskopischer ..... was war der Urknall ausser ein
gigantischer alles erreichender Reset ;)
cfgardiner schrieb:> Aber in Grunde genommen ist es egal, ob synchron oder asynchron.
Auf jeden Fall muss so ein Reset aber synchron deaktiviert werden.
Sonst geht das garantiert irgendwann schief. Designs mit vollkommen
asynchronem Reset sind solche, die manchmal nicht richtig "anlaufen".
Wenn sie es aber tun, dann laufen sie tagelang ohne Probleme...
cfgardiner schrieb:> Jede finite Schaltung braucht einen Reset.
Kannst du das auch begründen? Oder sollen wir das einfach glauben, weil
du das halt so sagst?
Da D. schrieb:>> Jede finite Schaltung braucht einen Reset.>> Kannst du das auch begründen? Oder sollen wir das einfach glauben, weil> du das halt so sagst?
Mei, das wäre tatsächlich eine Möglichkeit. Allerdings gehört es nicht
zu meinen Lebenszielen möglichst viele "Followers" zu haben. Wenn du
andere Meinung bist und es läuft bei dir ....
Allerdings zur Begründung vielleicht zwei Anregungen:
1) Simulierst du? Schreibst du dein HDL möglichst so, dass es über
Hersteller hinweg portable ist? Arbeitest du mit einem verschiedenen
Simulatoren? Mache mal ein Paar Testcases mit und ohne Reset und
vergleiche die dabei entstehende Probleme, Zeitaufwände etc.
2) Ich behaupte die meisten FPGAs können als Ansammlung von FSMs
betrachtet werden, ausser vielleicht wenn es rein um Datenschieber geht,
bei dem die 'X' Zustände irgendwann aus dem Datenpfad ausgepustet
werden. Der nächste Zustand eines FSM ist abhängig vom aktuellen Zustand
+ die neue Stimuli. Wenn ich aber den aktuellen Zustand nicht genau
kenne weil ich keinen definierten Startzustand hatte, was macht meine
Logik dann? Ist es reproduzierbar?
Ich kann nur für wenige Tools und einge Versionen sprechen:
Altera: seit sicher 7.x werden in HDL Initial Values
unterstützt, mindestens ab Cyclone1 (hab ich Heute noch
für RetroComputing-Sachen in Betrieb, an meinen letzen
Reset für's Defaulten kann ich mich beim besten Willen
nicht mehr erinnern).
Xilinx: bis ISE 4.x (oder 5.x???) kann man zwar
Initial Values angeben, es wird aber eine Warnung
ausgegeben (Value wird ignoriert). Ab ISE 6.x dagegen
werden Initial Values unterstützt (kann aber sein,
dass einige Devices dies nicht unterstützen).
Lattice: ab mindestens Diamond 2.x (ältere auch?) werden
auch hier Initial Values unterstützt, evtl. Deviceabhängig,
ich kenne nur wenige Lattice FPGAs/CPLDs. Bei ICE40 etc.
gibt's eigene Entwicklungstools, bei denen kenne ich mich
aber nicht aus.
Von jedem dieser Entwicklungstools kenne ich nicht nur
den Konfigurationsvorgang, ich habe an konkreten DevBoards
Powerup-Sequenzen per LA nachvollzogen (man will sich
ja nicht böse überraschen lassen).
Oben wurde behauptet, Altera's QuartusII kann FFs mit
InitialValues nicht in IO-Zellen packen. Auch dass kann
ich nicht bestätigen bzw. halte ich für falsch. Z.B.
kann per IP-Wizard IO-FFs erzeugt und mit Default-Werten
zugeordnet werden, ebenso per HDL erzeugte FFs mit
Constraints sind in IOs plazierbar.
Neben den schon zahlreichen Anmerkungen sollte man auch noch
berücksichtigen, dass etliche "harte" Funktionsblöcke in FPGA einen
synchronen Reset voraussetzen, so z.B. Block RAMs. Wird jedoch ein
asynchroner Reset verwendet, kann dies dazu führen, dass stattdessen ein
Gattergrab synthetisiert wird.