Forum: FPGA, VHDL & Co. Toggle - FlipFlop


von M. T. (yohojoe)


Lesenswert?

So Frohe Ostern erstmal :)

ich versuche mich gerade an meinem ersten vhdl projekt dass wir im 
rahmen eines praktikums erstellen sollen. Für die realisierung benötige 
ich allerdings einen frequenzhalbierer, also einen Toggle-FlipFlop (DFF 
mit rückgekoppelten invertierten ausgang).

Hier ist der code:
1
entity Frequenzhalbierer is
2
    Port ( clk50 : in  STD_LOGIC;
3
          clk25 : out STD_LOGIC
4
   
5
   );
6
           
7
end Frequenzhalbierer;
8
9
architecture Behavioral of Frequenzhalbierer is
10
11
12
signal Q: std_logic;
13
signal D: std_logic;
14
15
begin
16
Process (clk50)
17
18
19
    begin
20
    IF (clk50'event AND clk50='1') THEN
21
    Q <= '1';
22
    D <= '0';
23
    end if;
24
    
25
    IF (clk50'event AND clk50='1' AND D='0') THEN
26
    Q <= '0';
27
    D <= '1';
28
    end if;
29
    
30
    end process;
31
32
clk25 <= Q;
33
34
end Behavioral;

Mir wird allerdings ein Error ausgegeben:"Signal D cannot be 
synthesized, bad synchronous description. The description style you are 
using to describe a synchronous element (register, memory, etc.) is not 
supported in the current software release." (Xilinx Webpack 12.4).

Ich weiß noch nichtmal genau ob der code das bewirkt was er soll, würde 
ihn gern testen aber das geht ja leider nicht. Hatte davor schon einige 
andere Errors konnte sie aber beheben wobei ich bei diesem wirklich 
keine ahnung habe :(

wäre sehr nett wenn mir jemand da weiter helfen könnte

von Hmm (Gast)


Lesenswert?

Ein Frequenzhalbierer ist das leider nicht.

Wenn Du steigende Flanke siehst, dann wird eine 1 ausgeben. Was ist das 
anderes als eine steigende Flanke?
Wenn Du eine fallende Flanke siehst, dann wird eine 0 ausgegeben. Was 
ist das anderes als eine fallende Flanke.

Aber mal was anderes: Lösche doch D einfach, da es in deinem Design zu 
nichts nutze ist. Ich vermute aber mal, das der Code, die zensierte 
Variante ist, sonst würde ISE nicht meckern.

von Schlumpf (Gast)


Lesenswert?

M. T. schrieb:
> DFF mit rückgekoppelten invertierten ausgang

Du hast ja eigentlich schon selber geschrieben, was du benötigst.
Jetzt musst du das nur in VHDL BE-schreiben.
1
-- Das Datenregister:
2
Process (clk50)
3
begin
4
    IF (clk50'event AND clk50='1') THEN
5
        Q <= D;
6
    end if;
7
end process;
8
-- Die invertierte Rückkopplung
9
D <= not Q;
10
11
-- oder zusammengefasst:
12
Process (clk50)
13
begin
14
    IF (clk50'event AND clk50='1') THEN
15
        Q <= not Q;
16
    end if;
17
end process;

Wenn du allerindings vor hast, mit dem so generierten clk50 weitere 
Register in deinem Design zu takten, dann kann das problematisch werden, 
da dein Design dann nicht mehr synchron ist.
Besser ist es, JEDES Register im Design mit dem gleichen Takt zu takten 
und das Signal aus deinem Frequenz-Halbierer als Enable-Signal für 
nachfolgende Register zu verwenden und nicht als Takt.

Also so NICHT:
1
-- "langsames" Register:
2
Process (Q)
3
begin
4
    IF (Q'event AND Q='1') THEN
5
        Q25 <= D25;
6
    end if;
7
end process;

sondern so:
1
-- "langsames" Register:
2
Process (clk50)
3
begin
4
    IF (clk50'event AND clk50='1') THEN
5
       IF (Q = '1') then
6
          Q25 <= D25;
7
       end if;
8
    end if;
9
end process;

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


Lesenswert?

Und noch ein Wort zum eigentlichen Fehler: da sind 2 Takte in 1 Prozess. 
Das können Synthesizer heutzutage noch nicht...

von Schlumpf (Gast)


Lesenswert?

Lothar Miller schrieb:
> da sind 2 Takte in 1 Prozess.
> Das können Synthesizer heutzutage noch nicht...

Auf den ersten Blick ist es der gleiche Takt, auf den zweiten sind es 
aber zwei Takte.
Der clk50 und dann noch clk50, der "gated" ist. Es müssten also zwei 
Register entstehen. Eines, welches mit clk50 getaktet ist und ein 
anderes,welches mit einer kombinatorischen Verknüpfung aus clk50 und D 
getaktet ist.
Beide Register würden aber Q und D treiben. Und das geht in die Hose

von Hmm (Gast)


Lesenswert?

Oops. Da war ja doch noch ein D. Sorry. Mein Fehler.

von M. T. (yohojoe)


Lesenswert?

vielen dank für die zahlreichen antworten :) haben mir sehr geholfen!

von M. T. (yohojoe)


Lesenswert?

So jetzt muss ich doch nochmal nerven:

hier ist der finale code
1
entity Frequenzhalbierer is
2
    Port ( clk50 : in  STD_LOGIC;
3
          clk25 : out STD_LOGIC
4
   
5
   );
6
           
7
end Frequenzhalbierer;
8
9
architecture Behavioral of Frequenzhalbierer is
10
11
12
signal Q: std_logic;
13
signal D: std_logic;
14
15
begin
16
17
    Process (clk50)
18
      begin
19
          IF (clk50'event AND clk50='1') THEN
20
          Q <= D;
21
          end if;
22
      end process;
23
24
25
          D <= not Q;
26
27
          clk25 <= Q;
28
29
end Behavioral;


Die Testbench (ISim) bereitet mir jetzt allerdings probleme, clk50 wird 
ganz normal als ein taktsignal angezeigt wobei aber clk25 "U" ist, 
wahrscheinlich undefined denke ich zumindest. Sollte mir die Testbench 
nicht einfach einen Takt mit der halben frequenz von clk50 bei clk25 
anzeigen?

von Schlumpf (Gast)


Lesenswert?

Das ist schon korrekt mit dem "U".

Dadurch, dass dein Register keinen definierten "Startwert" hat, wird 
jetzt mit jedem Takt ein "U" invertiert. Und das ist eben wieder ein "U" 
;-)

Darum gibt man sinnvollerweise noch einen Reset vor, wenn das später mal 
synthetisiert werden soll.

Wenn du nur simulieren willst, dann kannst du einfach bei der 
Deklaration von D einen Default-Wert mit angeben:

signal D: std_logic := '0';

Auf dem PLD gibt es aber kein "U". Beim Start wird das Signal D immer 
entweder "O" oder "1" sein. Daher ist hier für die Funktion auf dem PLD 
kein Reset-Wert oder Startwert erforderlich. Für die Simulation hingegen 
schon.

von Thomas_L (Gast)


Lesenswert?

Wie wäre es Damit:
1
    
2
process begin
3
     wait until rising_edge(clk50);
4
     Q <= not Q;
5
end process;
6
     clk25 <= Q;

von daniel__m (Gast)


Lesenswert?

Schlumpf schrieb:
> Und das ist eben wieder ein "U"
> ;-)

nicht ganz: eine Operation mit 'U' ist 'X'.

Schlumpf schrieb:
> Darum gibt man sinnvollerweise noch einen Reset vor, wenn das später mal
> synthetisiert werden soll.

zumindest bei Xilinx ist ein Reset für so etwas absolut unnötig und 
erhöht im allgemeinen nur den Resourcenbedarf, die Init-Werte werden 
auch in der Synthese korrekt abgebildet. Ich lehne mich jetzt mal aus 
dem Fenster und sage das gilt für alle FPGA Toolchains. Das gilt für 
ASICs (glaub ich) nicht und auch wenn das Design während der Laufzeit 
neugestartet werden soll.

Die Init-Werte sind insbesondere dann hilfreich/notwendig, wenn ganze 
Block-RAMs z.b. als ROMs vorbelegt werden müssen.

grüße

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


Lesenswert?

Ich biete das hier:
1
signal q : std_logic := '0';
2
:
3
    Q <= not Q when rising_edge(clk50);
4
    clk25 <= Q;

Zum Thema "Xilinx und die Resets" such einfach mal den Thread mit genau 
diesem Titel...

von Klaus (Gast)


Lesenswert?

Schlumpf schrieb:
> Darum gibt man sinnvollerweise noch einen Reset vor, wenn das später mal
> synthetisiert werden soll.
>
> Wenn du nur simulieren willst, dann kannst du einfach bei der
> Deklaration von D einen Default-Wert mit angeben:
>
> signal D: std_logic := '0';

Das war mal im letzten Jahrtausend. Heute können die Synthesizer genauso 
den Defaultwert beachten. Der Wert wird dann direkt bei der 
Konfiguration aus dem Bitstream ins FF geladen.

von Schlumpf (Gast)


Lesenswert?

Natürlich richtet die Synthese eine nicht explizit vorgegebene 
reset-Struktur, indem sie implizit das aus dem Bitfile für jedes 
Register extrahiert. Aber ein 'sauberer' Anlauf ist das nicht. Die 
Verwendung des GSR und Verknüpfung mit der PLL ist auf jeden Fall 
empfehlenswert.
Und ob die Beschreibung eines Resets aus dem letzten Jahrtausend ist, 
darf natürlich gerne nochmal diskutiert werden, wenn es daran geht, ein 
Design für einen ASIC zu machen :-)

von Klaus (Gast)


Lesenswert?

Schlumpf schrieb:
> Und ob die Beschreibung eines Resets aus dem letzten Jahrtausend ist,
> darf natürlich gerne nochmal diskutiert werden, wenn es daran geht, ein
> Design für einen ASIC zu machen :-)

Was soll immer das ASIC Argument, wenn man über FPGAs diskutiert? Ich 
bau in mein Auto ja kein Bremsfallschirm, weil wenn ich damit mal ins 
Weltall will, brauch ich den beim Wiedereintritt...

Schlumpf schrieb:
> Und ob die Beschreibung eines Resets aus dem letzten Jahrtausend ist

Ich schrieb nicht, dass die Beschreibung des Resets aus dem letzten 
Jahrtausends ist, sondern die Tatsache, dass der default wert bei der 
Synthese nicht geht, stammt aus dem letzten Jahrtausend. Die  explizite 
Beschreibung des Resets ist davon unabhängig natürlich noch aktuell.

von Schlumpf (Gast)


Lesenswert?

Klaus schrieb:
> Was soll immer das ASIC Argument, wenn man über FPGAs diskutiert?

Weil man´s eben bei FPGAs auch gleich "richtig" machen kann, so dass es 
theoretisch auch auf einen ASIC portierbar wäre.
Das Argument, dass dadurch mehr Ressourcen im FPGA benötigt werden, kann 
ich nämlich nicht so stehen lassen.
Das GSR-Netz ist vorhanden, ob man es nutzt, oder brach liegen lässt, 
ist dem Die schnuppe.

Aber du hast natürlich recht, dass die Synthese-Tools heute soweit sind, 
dass sie die Default-Wert-Zuweisungen dann für dich hinstricken.
Allerdings muss ich gestehen, dass ich nicht exakt sagen kann, wie das 
dann im FPGA abgebildet wird. Ich vermute aber sehr stark, dass der 
Reset dann vollkommen asynchron ist, der Zustand der PLL nicht mit 
verknüpft ist und man eigentlich nicht so 100% sicher sein kann, dass 
das in allen Fällen zuverlässig funktioniert.

Klaus schrieb:
> sondern die Tatsache, dass der default wert bei der
> Synthese nicht geht, stammt aus dem letzten Jahrtausend.

Ich habe nie behauptet, dass das nicht geht, sondern ich habe gesagt, 
dass man SINNVOLLERWEISE noch einen Reset vorgibt, wenn man den Code 
synthetisieren will. Und dan dieser Aussage halte ich aus o.g. Gründen 
nach wie vor fest. Auch wenn es dir als ein Relikt aus dem letzten 
Jahrtausend erscheinen mag :-)

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


Lesenswert?

Schlumpf schrieb:
> Das Argument, dass dadurch mehr Ressourcen im FPGA benötigt werden, kann
> ich nämlich nicht so stehen lassen.
> Das GSR-Netz ist vorhanden, ob man es nutzt, oder brach liegen lässt,
> ist dem Die schnuppe.
Siehe die WP272 und WP275 von Xilinx...
Es ist vor allem ein Unterschied, ob der Reset einer synchronen 
Beschreibung asynchron ausgeführt ist. Dann ergeben sich abhängig von 
der Architektur durchaus signifikante Unterschiede. Dazu siehe auch 
den Beitrag "Xilinx und die Resets" incl. der darin 
enthaltenen Links.

> ich habe gesagt, dass man SINNVOLLERWEISE noch einen Reset vorgibt,
> wenn man den Code synthetisieren will.
Ich mache es genau andersrum (möglichst kein Reset, und falls doch, dann 
nur lokal) und habe in zigtausend ausgelieferten Geräten keinerlei 
Probleme damit...

von Schlumpf (Gast)


Lesenswert?

Ich habe die WP´s grad nur überflogen und falls ich dabei etwas 
übersehen habe bitte ich, das zu entschuldigen:

Über die Problematik asynchroner Resets und deren Skew und daraus 
resultierenden Setup-Zeit-Verletzungen bin ich mir bewusst. Daher 
synchronisiere ich die asynchronen Resets zentral ein. Zumindest den 
Übergang von "aktiv" nach "inaktiv".
Damit ist der Synthese der Bezug zwischen Takt und Reset bekannt und 
falls es zu einer Setupzeitverletzung käme, würde sie meckern.
Ich hatte mit dieser Methode ebenfalls noch nie Probleme und sehe den 
Vorteil einfach darin, dass z.B. bei einem "Stolperer" der PLL das 
Design wieder in einen definierten Zustand zurückfindet.

Dass mit dieser Methode der Ressourchenverbrauch signifikant gestiegen 
sei, konnte ich bisher nicht feststellen.

Aber vielleicht habe ich auch zu sehr die ASIC-Brille auf, da die 
meisten meiner Designs eigentlich nur zu Testzwecken auf FPGAs laufen 
und am Ende dann in fest verdrahteten 180nm-Strukturen "enden" ;-)

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


Lesenswert?

Schlumpf schrieb:
> Über die Problematik asynchroner Resets und deren Skew und daraus
> resultierenden Setup-Zeit-Verletzungen bin ich mir bewusst. Daher
> synchronisiere ich die asynchronen Resets zentral ein.
Und jetzt kommt der Kanckpunkt: verwendest du diesen "synchronen Reset" 
dann im Design asynchron oder synchron? Denn genau da sind abhängig 
von der Architektur Unterschiede zu finden. Hier der direkte Link auf 
ein paar kleine Tests: 
Beitrag "Re: Hardware mit VHDL "richtig" beschreiben."

Und hier der Text zum Bild:
Wenn ein FF bei Xilinx mit asynchronem Reset beschreiben wird, dann wird 
das Flipflop in den "asynchronen Modus" versetzt und hat keine 
synchronen Set und Reset Eingänge (FDRSE) mehr, sondern nur noch die 
asynchronen Clear und Preset (FDCPE). Und wenn dann ein Zähler synchron 
zurückgesetzt wird, braucht es zusätzliche Logik, und ein Eingang der 
vorgeschalteten LUT wird verbraten. Das bedeutet im schlechtesten Fall, 
dass ein zusätzliche LUT und damit ein weitere Konbinatorikebene 
eingefügt werden muss, was zudem die Taktfrequenz reduziert.

von Schlumpf (Gast)


Lesenswert?

Ich synchronisiere das Deaktivieren des Resets (also "release") ZENTRAL 
an einer Stelle für den ganzen Chip ein.
Dieses synchronisierte Signal wird dann über das GSR an alle Register 
geführt und dort als asynchroner Reset beschrieben.

von Schlumpf (Gast)


Lesenswert?

Aber natürlich hast du Recht, wenn du sagst, dass dann dieser asynchrone 
SET/RESET nicht mehr für irgendwelche Optimierungsmechanismen zur 
Verfügung steht. Sprich: Ein, ich nenn es jetzt mal "funktionaler" 
Reset, der sich aufgrund des Designs ergeben könnte, kann dann nur als 
Kombinatorik über die vorgeschaltete LUT abgebildet werden und belegt 
dort Ressourcen, wogegen er bei einem "unbenutzen" Reset des Registers 
an diesen herangeführt werden könnte.

Ok, ich stimme dir zu. In solchen Fällen steigt dann der 
Ressourcenverbrauch und damit ggf. die Logiktiefe und damit ggf. die 
Laufzeit, wenn man einen asynchronen Reset beschreibt.

Daher muss ich meine pauschale Aussage von vorhin, dass es quasi keine 
Rolle spielt, zurücknehmen und durch ein "kommt drauf an.." ersetzen ;-)

von Christian R. (supachris)


Lesenswert?

Schlumpf schrieb:
> Ich vermute aber sehr stark, dass der
> Reset dann vollkommen asynchron ist, der Zustand der PLL nicht mit
> verknüpft ist und man eigentlich nicht so 100% sicher sein kann, dass
> das in allen Fällen zuverlässig funktioniert.

Doch kann man, man kann nämlich zumindest bei Xilinx einstellen, dass 
der Startup des FPGA solange verzögert wird, bis alle benutzten DCMs und 
PLLs stabil sind und das Locked bringen. Wenn man dann überall die 
Default-Werte ordentlich zugewiesen hat, läuft das Design zumindest aus 
einem Config-Reset immer zuverlässig an.

von Schlumpf (Gast)


Lesenswert?

Christian R. schrieb:
> Doch kann man, man kann nämlich zumindest bei Xilinx einstellen, dass
> der Startup des FPGA solange verzögert wird, bis alle benutzten DCMs und
> PLLs stabil sind und das Locked bringen.

Ok, wenn das alles so geht, dann ist es auch kein Problem, wenn man 
einfach nur Default-Werte zuweist.
Wie gesagt, meine Designs landen am Ende meistens in einem ASIC und da 
stehen solche Möglichkeiten nicht zur Verfügung. Vielleicht ist daher 
meine Sicht auf die Dinge etwas "rudimentärer"

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


Lesenswert?

Schlumpf schrieb:
> Sprich: Ein, ich nenn es jetzt mal "funktionaler"
> Reset, der sich aufgrund des Designs ergeben könnte, kann dann nur als
> Kombinatorik über die vorgeschaltete LUT abgebildet werden und belegt
> dort Ressourcen, wogegen er bei einem "unbenutzen" Reset des Registers
> an diesen herangeführt werden könnte.
Richtig, das kommt zum Thema "Flipflop im Async-Mode wegen asynchronem 
Reset" noch dazu: ein Zähler, der vom Resettaster oder von einem 
Zählerendwert zurückgesetzt werden soll, braucht genau dieses 
"Oder-Gatter" zusätzlich vor seinem Reset-Eingang (und weil es dort 
nicht geht, dann eben als Zustandsverküpfung vor dem Flipflop).

Schlumpf schrieb:
> Wie gesagt, meine Designs landen am Ende meistens in einem ASIC
Und da musst du dich selber sogar noch um das Taktrouting kümmern (oder 
es wenigstens der Toolchain sagen). Auch das ist beim FPGA anders: ich 
darf erwarten, dass das der FPGA-Hersteller das Taktnetz so ausgelegt 
hat, dass keine Race-Conditions auftreten können...

von Schlumpf (Gast)


Lesenswert?

@ Lothar:
Dann hab ich verstanden, auf was du hinaus wolltest und gebe dir 
natürlich Recht.
Beim FPGA kann es also durchaus sinnvoll sein, auf eine dedizierte 
Reset-Beschreibung zu verzichten, und somit der Synthese diese Ressource 
nicht wegzuschnappen :-)

Und klar, beim ASIC sieht die Welt wieder ganz anders aus. Da bleibt 
viel mehr "Handarbeit".

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.