Forum: FPGA, VHDL & Co. Timer asynchron setzten


von Pope (Gast)


Lesenswert?

Mal eine Frage an die erfahrenen FPGA bändiger. Folgender Code generiert 
mir combinatorische Latches das ist klar, aber wie verboten ist es?
1
  -- ------------------------------------------------------------------------------------
2
  -- MILISECOND TIMER PROCESS
3
  -- ------------------------------------------------------------------------------------
4
  timer_ms_proc   : PROCESS(rst_i, clk_i)
5
  BEGIN
6
    IF rst_i = '1' THEN
7
      timer_ms <= (OTHERS => '0');
8
    ELSIF setTimer_ms = '1' THEN
9
      timer_ms <= timer_ms_newVal;
10
    ELSIF rising_edge(clk_i) THEN
11
      IF clk_1kHz_synch = "01" THEN
12
        IF timer_ms > 0 THEN
13
          timer_ms <= timer_ms - 1;
14
        END IF;
15
      END IF;
16
    END IF;
17
  END PROCESS timer_ms_proc;

Grund dafür ist, ich habe eine Statemachine in der verschiedene Timer us 
- s Basis genutzt werden. Mit dieser Implementation kann ich aus dem 
Prozess der Statemachine mittels setTimer und timer_newVal den Counter 
innerhalb eines Clockzyklus neu setzten.

Oder kennt jemand eine bessere Lösung ohne, dass ich riesige Register 
brauche um Sekunden zu zählen?

von chris (Gast)


Lesenswert?

Wenn ein Timer z.B. mit einem Takt von 1ms getaktet wird und man mach 
einen asynchronen Reset gibt es meiner Meinung nach zwei Möglichkeiten:

1. der Reset kommt z.B. bei 9,3ms dann kann der Timer beim nächsten 
Tick, also bei 10ms auf 0 gesetzt werden. Dann braucht der Timer nur 1ms 
Auflösung.
2. soll der Reset aber innerhalb eines FPGA-Systemclocks zurückgesetzt 
werden, braucht man einen Timer mit der vollen Auflösung.

von King Julian (Gast)


Lesenswert?

Kombinatorische Schleifen lassen sich eigentlich immer vermeiden. Wenn 
du die clocks einsynchronisierst, warum dann die Zustandsabfrage nicht 
einfach an den Anfang des Hauptprozesses. Damit sparst du dir sogar das 
setTimer Signal und das newVal Register.
In der Statemachine kannst du dann einfach den Timer nach belieben 
setzten.

von chris (Gast)


Lesenswert?

Gestern habe ich mal in diesem Buch geblättert:
https://www.dpunkt.de/buecher/11821/9783864901737-fpgas-f%C3%BCr-maker.html

Dort empfehlen sie synchrone Designs.
Soweit ich gesehen habe, werden dort alle vorgestellten Funktionsblöcke 
mit dem schnellen Systemclock versorgt.
Wenn man dann z.B einen Block braucht, der mit 1ms getaktet wird, wird 
zusätzlich ein Pulssignal mit 1ms Periode und 20ns Dauer durchgeroutet.
Der langsame Takt ist also dann kein symmetrisches Rechtecksignal, 
sondern nur ein Puls, der sich mit der langsamen Rate wiederholt.

von King Julian (Gast)


Lesenswert?

Ich generiere mir für meine Designs meisst dedizierte counter clocks, 
sprich ich hab z.B. 50MHz Systemtakt und dann jeweils einen Teiler für 
1MHz, 1kHz und 1Hz. Diese Takte werden dann in die jeweiligen Blöcke 
"gespiesen" und dort in ein 2-Bit Schieberegister gepackt für die 
Flankenerkennung. Mit diesem Schieberegister kann man dann bequem 
weiterarbeiten und muss nicht x-Mal einen Frequenzteiler implementieren 
für ein und den selben Takt.

von chris (Gast)


Angehängte Dateien:

Lesenswert?

>Diese Takte werden dann in die jeweiligen Blöcke
>"gespiesen" und dort in ein 2-Bit Schieberegister gepackt für die
>Flankenerkennung.

Das jedes Modul extra noch mal ein Schieberegister zur Flankenerkennung 
braucht, scheint mir etwas aufwendig.

Ich vermute, dass es mit dem Pulsprinzip besser geht.

Der entscheidende Punkt ist der:
1
  process 
2
  begin
3
    wait until rising_edge(clk);
4
    if (pulse_ms='1') then
5
      speakerSignal <= not speakerSignal;
6
    end if;
7
  end process;

Getaktet wird mit der vollen Systemfrequenz "clk", aber das 
speakerSignal wird mit dem Puls gekippt.

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


Lesenswert?

Pope schrieb:
> Mal eine Frage an die erfahrenen FPGA bändiger. Folgender Code generiert
> mir combinatorische Latches das ist klar
Das ist mir eigentlich nicht klar. Die Latches passieren offenbar 
ausserhalb des geposteten Codes. Du hast da nochmal irgendwo einen 
gewaltigen Bock drin...

> Mit dieser Implementation kann ich aus dem Prozess der Statemachine
> mittels setTimer und timer_newVal den Counter innerhalb eines
> Clockzyklus neu setzten.
Such mal nach meinen "Postulaten" hier im Forum. Und lies dann gleich 
die paar Zeilen drumrum. Dort haben andere Leute auch sowas 
zusammengebastelt ud ihre Probleme damit.

> aber wie verboten ist es?
Sieh dir das Handbuch deines Synthesizers an. Wenn es dort nicht 
ausdrücklich empfohlen wird, dann solltest du ganz, ganz genau wissen, 
was du da tust. Das ist nicht der Fall.

> aber wie verboten ist es?
Ein solcher Code ist ein Kündigungsgrund.
Als ich neu im FPGA-Geschäft war, haben wir von einem Dienstleister mal 
genau solchen Code bekommen, der asynchrone kombinatorische Resets und 
Loads enthielt. Bei der Fehlersuche an diesem Code lernte ich, dass man 
auch von "Profis" schlechten Code bekommen kann und dass man solche 
Dinge wie asynchrone kombinatorische Resets besser nicht macht.


> Oder kennt jemand eine bessere Lösung ohne, dass ich riesige Register
> brauche um Sekunden zu zählen?
Mach den ms-Timertic einfach zum synchronen Clock-Enable. So wie es der 
Rest der Welt auch tut. Und so wie ich es hier im Lauflicht mit dem 
Weiterschalttakt mache:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Ich könnte mit dem dort erzeugten 3-Hz-Clock-Enable viele Lauflichter 
mit der selben Frequenz ansteuern.

Wenn du also einen 1ms Clock-Enable machst (oder einen mit 100ms), ist 
deine Zeitbasis fürderhin nur noch 1ms (oder 100ms) statt 20ns (bei 
50MHz FPGA-Takt) und die ganzen Zähler werden wesentlich kürzer.

: Bearbeitet durch Moderator
von chris (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch das Bildchen für den Clockdivider.

Jetzt müsste man mal ähnliches für den Zähler zeigen.

von chris (Gast)


Angehängte Dateien:

Lesenswert?

Tschuldigung, falsches File. Hier das richtige.

von chris (Gast)


Lesenswert?

>Wenn du also einen 1ms Clock-Enable machst (oder einen mit 100ms), ist
>deine Zeitbasis fürderhin nur noch 1ms (oder 100ms) statt 20ns (bei
>50MHz FPGA-Takt) und die ganzen Zähler werden wesentlich kürzer.

100ms ... dort ist dann halt das Problem der "Granularität" die ich oben 
versucht habe, zu beschreiben.

Die Frage ist: muss nach dem Reset der nächste Tick in genau 100ms 
kommen, oder kann es eine Zeitspanne von 0..100ms sein.

Da ist die Frage an den "Pope": Was brauchst Du?

von chris (Gast)


Angehängte Dateien:

Lesenswert?

>Mach den ms-Timertic einfach zum synchronen Clock-Enable. So wie es der
>Rest der Welt auch tut. Und so wie ich es hier im Lauflicht mit dem
>Weiterschalttakt mache:
>http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
1
architecture Behavioral of Clockdivider is
2
signal clkdiv : integer range 0 to fclk/frequenz := 0;
3
begin
4
   process begin
5
      wait until rising_edge(clk);
6
      if (clkdiv < fclk/frequenz) then
7
         clkdiv <= clkdiv+1;
8
         clken  <= '0';
9
      else
10
         clkdiv <= 0;
11
         clken  <= '1';
12
      end if;
13
   end process;
14
end Behavioral;

Aha, das ist ja quasi die gleiche Implementierung.
Mittlerweile meine ich aber ein Problem zu Erkennen: Der Puls aus aus 
dem Clockdivider und der Clock selbst haben die steigende und fallende 
Flanke quasi gleichzeitig, deshalb könnte es abhängig vom Routing im 
FPGA in der nächsten Stufe zu einer Race-Condition kommen, d.h. die 
Flanke des clk könnte leicht nach der vom Puls kommen.

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


Lesenswert?

chris schrieb:
> Mittlerweile meine ich aber ein Problem zu Erkennen: ...Race-Condition...
Dass genau das nicht passiert, garantiert mir der FPGA-Hersteller. Ich 
bezahle ihn dafür, dass er mir einen Baustein liefert, in dem der Takt 
im gesamten FPGA gleichzeitig ist. Denn nur so funktioniert ein 
synchrones Design:
1. Es kommt ein Takt, der die Daten an den Flipflopeingängen übernimmt.
2. Jetzt kommt Hektik ins FPGA, es werden neue Zustände oder 
Zählerstände berechnet.
3. Kurz vor dem nächsten Takt muss alles fertig und stabil sein, damit 
das ganze Spiel von vorn losgehen kann.

von chris (Gast)


Lesenswert?

>Dass genau das nicht passiert, garantiert mir der FPGA-Hersteller. Ich
>bezahle ihn dafür, dass er mir einen Baustein liefert, in dem der Takt
>im gesamten FPGA gleichzeitig ist.

Signale ohne Laufzeit. Schade, dass das Einstein nicht mehr erleben 
durfte ;-)

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


Lesenswert?

chris schrieb:
> Signale ohne Laufzeit.
Deine Interpretation meiner Worte ist falsch, weil du "gleichzeitig" mit 
"sofort" verwechselst.
Stichworte dazu sind "balanced clock tree" und "zero skew clock". Und da 
geht es eben nicht darum, den Takt vom Pin sofort an die Flipflops zu 
bekommen, sondern das Ziel ist, ihn gleichzeitig an den Flipflops 
ankommen zu lassen.

: Bearbeitet durch Moderator
von Burkhard K. (buks)


Angehängte Dateien:

Lesenswert?

chris schrieb:
> Der Puls aus aus
> dem Clockdivider und der Clock selbst haben die steigende und fallende
> Flanke quasi gleichzeitig

Mitnichten:

1. Der Puls (sowas nennt man auch Tick) liegt eine volle Periodendauer 
am Ausgang des FlipFlops an, die fallende Taktflanke kommt bereits nach 
einer halben Periode.

2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig 
vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange 
danach (Hold-Time).
N.B.: Der (Logik-)Simulator weiss nichts von Setup- und Hold-Time, 
deswegen erscheinen dort Takt- und Signalflanke zum selben Zeitpunkt.


Werden in Deinem Design die Setup- und/oder Hold-Time eines Signals 
aufgrund zu langer Wege nicht eingehalten, dann macht Deine Toolchain 
die rote Ampel an: sie meldet eine Timing-Violation.

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


Lesenswert?

Burkhard K. schrieb:
> N.B.: Der (Logik-)Simulator weiss nichts von Setup- und Hold-Time,
> deswegen erscheinen dort Takt- und Signalflanke zum selben Zeitpunkt.
NB2: Nur falls jetzt einer auf eine gloriose Idee kommt: es ist keine 
gute Idee, in Code, der für die Verhaltenssimulation bestimmt ist, 
vorsorglich eine Laufzeit einzubauen. Sowas also:
1
   process (clk)
2
   begin
3
      if rising_edg(clk) then
4
         Ausgang <= Eingang after 10ns;
5
      end if;
6
   end process;
Das hatten wir letzthin im 
Beitrag "Re: CPU in VHDL designen"

von C. A. Rotwang (Gast)


Lesenswert?

Pope schrieb:
> Mal eine Frage an die erfahrenen FPGA bändiger. Folgender Code generiert
> mir combinatorische Latches das ist klar, aber wie verboten ist es?

Das ist einfach zu beantworten: "Only fools and Genius uses latches"

von chris (Gast)


Angehängte Dateien:

Lesenswert?

Meiner Meinung nach ist die fallende Flanke für das Timing unwichtig. 
Wichtiger wäre, dass man in der Simulation den Unterschied zwischen A 
und B sieht.

>2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig
>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange
>danach (Hold-Time).

Wo kann man das einstellen?

>----------------------------------------------------------------------- -
P.s.: Entschuldigt meine Übungen mit dem Wacom-Tablet.
Ich muss mich noch daran gewöhnen ...

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


Lesenswert?

chris schrieb:
> Meiner Meinung nach ist die fallende Flanke für das Timing unwichtig.
Stimmt, wenn das Design nur auf die steigende Flanke reagiert.

> Wichtiger wäre, dass man in der Simulation den Unterschied zwischen A
> und B sieht.
Du sehnst dich nach den symbolischen Verzögerungen, die ich als 
verwirrend und unnötig bechrieben habe.
Denn der zeitliche Ablauf ist in der Verhaltenssimulation unwichtig, 
weil es nur ein "vor dem Takt" und "den Takt" selber gibt: vor dem Takt 
wurde ein bestimmter Zustand berechnet, der mit dem Takt übernommen und 
daraus eine neuer Zustand berechnet wird, der wiederum beim nächsten 
Takt übernommen wird. Und dann geht das Spiel immer wieder im Kreis: 
Takt-Berechnen-Takt-Berechnen...
In der Praxis wird dann per Constraints (das wichtigste Constraint ist 
die Taktfrequenz) angegeben, wie schnell diese Berechnung ablaufen muss, 
dass sie rechtzeitig (um die Setupzeit einzuhalten) vor dem Takt fertig 
ist.

chris schrieb:
>> 2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig
>>>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange
>>>danach (Hold-Time).
> Wo kann man das einstellen?
Wie gesagt: du gibst in den Contraits die gewünschte Taktfrequenz an. 
Die Toolchain sorgt dann dafür, dass die eingehalten wird. Oder sie gibt 
dir einen Fehler aus, wenn sie es nicht schafft.

von Burkhard K. (buks)


Lesenswert?

chris schrieb:
>>2. Per Timing-Constraint wird sichergestellt, dass der Tick rechtzeitig
>>vor der Taktflanke (Setup-Time) anliegt und noch ausreichend lange
>>danach (Hold-Time).
>
> Wo kann man das einstellen?

Hier lohnt sich u.U. ein Blick in die Literatur, Stichwort: "Statische 
Timing-Analyse", z.B.:

 - Kesel, Bartholomä: "Entwurf von Digitalen Schaltungen mit HDLs und 
FPGA", 2. Auflage; Kapitel 4.1.3 bis 4.1.5
 - Pong P. Chu: "RTL Hardware Design Using VHDL", Kapitel 16  "Clock and 
Synchronization" (insbesondere 16.1 und 16.2)
 - und last but not least: der passende "User Guide" Deines 
FPGA-Herstellers

: Bearbeitet durch User
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.