Hallo zusammen,
ich habe auf meinem DE0-Nano Board einen kleinen Test geschrieben, um
ein bisschen mit Initialwerten und dem Reset herumzuspielen. Dabei ist
mir eine, für mich überraschende, Sache aufgefallen:
Wenn ich ein Zählerregister mit einem Initialwert ungleich 0 versehe und
im asynchronen Reset einen Wert ungleich dem Initialwert setze, dann
wird der Initialwert ignoriert und beim Power On der Resertwert geladen.
Dabei kommt in Quartus die Meldung:
1
Critical Warning (18061): Ignored Power-Up Level option on the following registers
2
Critical Warning (18010): Register r_counter[0] will power up to Low
3
Critical Warning (18010): Register r_counter[1] will power up to Low
4
Critical Warning (18010): Register r_counter[2] will power up to Low
5
Critical Warning (18010): Register r_counter[3] will power up to Low
Die Warnung ist verständlich, da er den Initialwert nicht verwendet.
Ich dachte, dass der Initialwert beim Power On gesetzt wird und der
Resetwert erst beim Drücken der Resettaste.
Hier mein Testcode:
1
library IEEE;
2
use IEEE.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
5
entity chip_top is
6
port(
7
clk50mhz : in std_logic := '0';
8
reset_n : in std_logic := '0';
9
10
key : in std_logic := '0';
11
12
led : out std_logic_vector(7 downto 0) := (others => '0')
13
);
14
end chip_top;
15
16
architecture chip_top_behavioral of chip_top is
17
signal r_counter : unsigned(7 downto 0) := x"0F";
18
signal r_key_prev : std_logic := '0';
19
20
begin
21
22
counter_process : process(clk50mhz, reset_n)
23
begin
24
if reset_n = '0' then
25
r_counter <= x"FF";
26
elsif rising_edge(clk50mhz) then
27
if r_key_prev = '1' and key = '0' then
28
r_counter <= r_counter + 1;
29
end if;
30
r_key_prev <= key;
31
end if;
32
end process;
33
34
led <= std_logic_vector(r_counter);
35
36
end chip_top_behavioral;
Wenn ich den Reset synchron verwende, ist das Verhalten so wie ich es
oben erwarte. Der Initialwert liegt beim Power On an und beim Drücken
der Resettaste liegt der Resetwert an.
Meine Frage ist jetzt: Erkennt Quartus automatisch den asynchronen Reset
und reagiert entsprechend? Gibt es dazu ein Paper oder eine andere
Quelle?
Ich danke Euch für Eure Hilfe.
Liebe Grüße
Jan
Jan K. schrieb:> Ich dachte, dass der Initialwert beim Power On gesetzt wird und der> Resetwert erst beim Drücken der Resettaste.
Nein, der Initialwert ist i.A. nur für die Simu, aber nicht fürs real
life.
Bei Xilinx ist das anders, bei altera (wie bei deinem Board) gilt die
Regel, das PowerOnWerte (nur) durch einen Reset zu erreichen sind.
https://www.xilinx.com/support/documentation/white_papers/wp272.pdf
Ich plädiere dafür, den begriff 'Initialwert' aus den Bereich Hardware
zu verbannen und nur von Reset- resp. PowerOn-Wert zu sprechen.
Und in einer Signaldeklaration keine init-zuweisung zu verwenden.
Ich verwende Initialwerte seit 10 Jahren bei Altera(Cyclone 2-5) und
Xilinx(Virtex E bis 7er Series) ohne Probleme.
Benutze oft gar keine Resets, wenn überhaupt, dann immer synchrone
Resets.
Kann mir vorstellen, das der asynchrone Reset für den Power On Reset mit
verwendet wird und deswegen nicht unterschiedliche Werte geladen werden
können.
FPGAzumSpass schrieb:> Ich verwende Initialwerte seit 10 Jahren bei Altera(Cyclone 2-5) und> Xilinx(Virtex E bis 7er Series) ohne Probleme.> Benutze oft gar keine Resets, wenn überhaupt, dann immer synchrone> Resets.
Selbst bei älteren Altera-Produkten (APEX etc.) lassen sich
Initialwerte ohne Probleme verwenden, bei alten
Xilinx-FPGAs/CPLDs genauso. (ich glaube, schon bei den
XC2000ern liessen sich INIT-Werte definieren). Das Problem
bei älteren war aber, das da teils VHDL/Verilog erst in z.B.
ABEL oÄ übersetzt werden musste und dort dann kein INIT-Wert
unterstützt wurde.
Das Problem Oben ist leicht zu verstehen: der TO versucht
zum einen, einen INIT-Wert in der Definition zu setzen,
aber dann im Reset-Teil einen anderen Reset-Wert zu verwenden.
Es ist aber je FF nur ein INIT-Werte=Reset-Wert zugelassen.
Daraus folgt also der Konflikt.
Guten Morgen,
vielen Dank für Eure Antworten.
Ich habe die Implementierungen mal im RTL Viewer verglichen. Beim
asynchronen Reset legt Quartus das reset_n Signal auf den CLR Eingang
der Register. Beim synchronen Reset wird reset_n als Enable Signal
verwendet.
Des Weiteren ist mir aufgefallen, dass Initialwerte zusätzliche
Kombinatorik benötigen. Das ist eigentlich logisch, ich habe es nur
nicht bedacht.
Nochmals vielen Dank. Jetzt bin ich schon wieder ein ganzes Stück
weiter.
Jan K. schrieb:> Des Weiteren ist mir aufgefallen, dass Initialwerte zusätzliche> Kombinatorik benötigen. Das ist eigentlich logisch, ich habe es nur> nicht bedacht.
Nein, total falsch: INIT-Werte, egal welcher Pegel,
werden im Configurationstream abgelegt und beim
Start entsprechend gesetzt, und zwar ohne zusätzliche
Logik.
Sigi schrieb:> Nein, total falsch: INIT-Werte, egal welcher Pegel,> werden im Configurationstream abgelegt und beim> Start entsprechend gesetzt, und zwar ohne zusätzliche> Logik.
Ich verwende diesen Code:
Sigi schrieb:> Jan K. schrieb:>> Des Weiteren ist mir aufgefallen, dass Initialwerte zusätzliche>> Kombinatorik benötigen. Das ist eigentlich logisch, ich habe es nur>> nicht bedacht.>> Nein, total falsch: INIT-Werte, egal welcher Pegel,> werden im Configurationstream abgelegt und beim> Start entsprechend gesetzt, und zwar ohne zusätzliche> Logik.
Nicht bei Altera, bei xilinx ja. Siehe Generic Init im Template
Xilinx
1
-- FDCE: Single Data Rate D Flip-Flop with Asynchronous Clear and -- Clock Enable (posedge clk). -- Spartan-6 -- Xilinx HDL Libraries Guide, version 14.7
2
FDCE_inst:FDCEgenericmap
3
(INIT=>'0')-- Initial value of register ('0' or '1')
Jan K. schrieb:> Kann der Cyclone IV es nicht im Configurationstream oder denke ich nur> komplett falsch?
Meines Wissens kann es das FF im Cyclone nicht, das FF in xilinx dagegen
schon. Damit der HDL Code architekturunabhängig ist, sollte man zum init
allein das reset/set Netzwerk verwenden, dan passt es auch mit dem ASIC.
Und auch da kann man 'fehler' machen, die zu zusätzlichen Kombinatorik
führen, wie Ken Chapman für Xilinx gut erklärt:
https://www.xilinx.com/support/documentation/white_papers/wp275.pdf
Wenn man einen Reset statt Initwerte verwenden will, dann aber bitte
auch darauf achten, dass man als Reset den Startup Reset verwendet.
(z.b. Element ROC bei Xilinx)
Und nicht einfach eine globale Resetleitung, am besten noch direkt vom
Pin kommend.
Oh, mal wierder eine schöne FPGA-Reset-Diskussion!
Wort Kauer schrieb:> Damit der HDL Code architekturunabhängig ist, sollte man zum init> allein das reset/set Netzwerk verwenden, dan passt es auch mit dem ASIC.
Ja, aus wievielen FPGA-Designs werden ASICs gemacht?
Wo kann ich mir die ASICs günstig machen lassen, ohne 1 Mio.
Geldeinheiten mitbringen zu müssen? Schick wäre auch eine FAB für den
Keller. 130 nm würden mir für den Einstieg reichen...
Zurück zum Thema: Der Cyclone III konnte m.E. nur auf '0' initialisieren
und hat die Logik automatisch invertiert, wenn man doch eine '1' haben
wollte. Oder war es andersrum?
Auf jeden Fall musste man dann im Reveal sehr aufpassen, welche
Darstellungsweise man verwendet (physisch/logisch).
Duke
Duke Scarring schrieb:> Oh, mal wierder eine schöne FPGA-Reset-Diskussion!
Nein, die Urschleimdiskussion hinter dem TO-Problem ist nicht (nur) die
mit dem Slogan "To reset or not to reset" sondern "Ist VHDL eine
Programmiersprache oder eine Modellierungssprache?"
Nur wer VHDL mit eine Programmiersprache verwechselt, glaubt die Tools
werden aus der Signaldeklaration genau das Gewünschte - eine
Initialsierung zum Beginn der "Programmausführung" mit dem gewünschten
definierten Wert realisieren. Dabei können die tools nur aus den
vorhandenen Eigenschaften der Hardware auswählen und da ist
Initialisierung bei Power Up nicht in jedem IC eingebaut.
Also schreibt man den Code so, das da genau ein Verhaltensmodel aus dem
"Real life" entsteht. Und das sind 4 reproduzierbare Möglichkeiten:
Nach dem PowerUp stehen in den FF
a) zufällige/Unbekannte Werte ('U')
b) alle '0' und nichts anderes
c) alle '1' und nichts anderes
d) der, der Uservorgabe, der user kann entweder '0' oder '1' vorgeben
d1) macht der User keine Angabe werden alle mit dem selben default-Wert
(i.e. '0') initialisiert.
Und wie bekommt man raus welche Optionen bzgl Initialisiserung der IC
bietet?
Nun, der TO macht es richtig, er liest die Reports. Alternativ, das
Datasheet über den Aufbau der Logigcells oder den Synthesis Style guide
der toolchain. Und naturlich sollte man sich besonders die Warnings mit
dem O-Ton "Die tools machen jetzt was anderes als du mglw. gewollt hast"
anschauen. Genau dieser O-Ton hat nämlich die vom TO zitierte Warning:
1
"Ignored Power-Up Level option on the following registers ..."
(BTW, dickes Lob an den TO für die detailierte Problembeschreibung, da
kommt man ohne grosses Nachstochern und Nachfragen auf des Pudels Kern)
Weiss man nichts um die Init-Optionen beim vorliegenden IC, wählt man
Variante a (zufällige Werte nach PowerUp) und baut eine
Initialisierungsschaltung aka Reset (auch POR Power-On-Reset oder auch
ROC (Reset-On-Configuration) mit den im FPGA vorhandenen Ressourcen ein.
--
BTW:
Dem aufmerksamen Leser wird nicht entgangen sein, das sich die Antworten
nur auf eine Teilmenge der VHDL-Fragestellung beziehen.
Eine Signaldeklaration wird nicht ausschließlich zu einem FF/Register
umgesetzt, es kann (je nach weiterer Beschreibung im Code) auch eine
simple Leitung an einem Kombinatorikgatterausgang sein, ein fixer Wert
('0' oder '1' also GND oder Vcc), eine Leitung zum I/O-PAD oder eine RAM
Zelle oder ein Schieberregister (ohne bit-load-Schaltung) oder .... Und
bei denen stellt sich die Eingangsfrage, wie nun das PoweUp Verhalten
mit/ohne Initialisierungszuweisung bei Deklaration beschrieben wird,
neu.