Forum: FPGA, VHDL & Co. FPGA Clockgenerierung


von Igor (Gast)


Lesenswert?

Hi, ich versuche jetzt schon seit einigen Tagen einen vermeintlich 
einfachen VHDL Code auf einem Terasic DE0 Board zum Laufen zu bringen.

Im Grunde soll ich einen Takt erzeugen und in einem bestimmten 
Augenblick, wenn ein Triggersignal auf 1 geht, soll eine gewisse Anzahl 
an Glitchen in den Takt heinein gegeben werden um danach wieder zum 
Ausgangstakt zurückkehren. In der Simulation klappt das auch wunderbar, 
nur wenn ich das Ding am Logikanalysator anschließe sehe, dass der 
Counter manchmal über die Grenze läuft. Ich bin kein VHDL Guru und 
vielleicht kann mal wer einen Blick auf den Code werfen und erkennt den 
Fehler. Vielen Dank.
1
dly_clk : process (fCLK, ready)
2
  begin
3
    if (ready /= '1') then
4
        nextClockCnt <= (others => '0');
5
        clockCnt <= (others => '0'); --der counter für die takterzeugung
6
        glitchRep <= (others => '0'); --anzahl der glitche
7
        oCLK <= '0'; -- ausgangs takt signal
8
        runState <= NORMAL_RUN; --zustand wo nur der takt erzeugt wird
9
    elsif rising_edge(fClk)then
10
      case runState is
11
        
12
        when NORMAL_RUN =>
13
                  
14
          if (TRG='1' or clockCnt = definedClockCnt) then -- wenn getriggert oder der counter den vordefinierten wert erreicht hat -> flanke
15
            oCLK <= not oCLK;
16
            
17
            if (TRG = '1') then -- wir gehen in zustand glitching
18
              runState <= GLITCHING;
19
              glitchRep <= (others => '0'); -- anzahl der glitche auf 0
20
              nextClockCnt <= clockCnt; -- merken uns wo wir nacher wieder fortsetzen
21
            end if;
22
23
            clockCnt <= (others => '0');
24
            
25
          else
26
            clockCnt <= clockCnt + 1; --sonst counter erhöhen
27
          end if;
28
        
29
        when GLITCHING => 
30
          
31
          if (clockCnt = definedGlitchCnt) then --dauer der glitche -> flanke
32
            oCLK <= not oCLK;
33
            
34
            clockCnt <= (others => '0'); 
35
            glitchRep <= glitchRep + 1; --anzahl der glitche erreicht
36
            
37
            if (glitchRep = definedGlitchRep) then
38
              runState <= POST_TRIGGER; --zustand nach den glitchen
39
              clockCnt <= nextClockCnt; --fahren mit dem normalen takt dort fort wo wir aufgehört haben
40
            end if;
41
            
42
          else
43
            clockCnt <= clockCnt + 1; --counter erhöhen
44
          end if;
45
        
46
        when  POST_TRIGGER =>
47
          
48
          if (clockCnt = definedClockCnt) then --normaler takt
49
            oCLK <= not oCLK;
50
            
51
            clockCnt <= (others => '0');
52
                      
53
            if (TRG = '0') then --wenn trigger signal auf 0 gehen wir wieder in den normalen zustand rüber
54
              runState <= NORMAL_RUN;
55
              nextClockCnt <= (others => '0');
56
            end if;
57
        
58
          else
59
            clockCnt <= clockCnt + 1;
60
          end if;
61
          
62
        
63
      end case;
64
    end if;
65
        
66
  end process;

lg Igor

von Na Sowas (Gast)


Lesenswert?

Der Begriff Clock ist hier falsch angewandt. Denn Clock ist etwas 
statisches. Der Clock laeuft durch. Und Zwischenpulse in den Clock rein 
muessen daher asynchron sein, daher sowieso verboten.
Also du moechtest einen Subclock erzeugen, der nach Wunsch (Trigger) mit 
ein paar zusaetzlichen Pulsen angereichert werden kann.  Sowas ist 
machbar.
Ich bin auch kein Guru, und wuerd mit debuggen beginnen. Man kann sich 
im Simulator ja alles anzeigen lassen...

von Na Sowas (Gast)


Lesenswert?

Bevor der Hinweis mit dem Debuggen doof klingt... ausm Pogramm alles 
rauswerfen und soweit aufbauen, bis es nicht mehr geht. Dann so im 
Programm herausfinden , welches die heiklen Teile sind, die sich nicht 
nach der Simulation verhalten.

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


Lesenswert?

Igor schrieb:
> den Glitchen  ... der glitche
Vorweg: ein Glitch, mehrere Glitches.
Was sind das für "Glitches", die du da zählen willst?
Ein Glitch ist nämlich per Definition ein undefiniertes Verhalten 
einer kombinatorischen Schaltung. Den kann man nicht digital 
auswerten...

> wenn ein Triggersignal auf 1 geht
Was für ein Triggersignal? Woher kommt das?

> rising_edge(fClk)
Wieviele Takte (mit rising_edge() oder falling_edge() oder 'event) hast 
du in deinem Design?

1
    if (ready /= '1') then
2
       :
3
    elsif rising_edge(fClk)then
Warum gibt mir das so sehr zu denken? Woher kommt ready?


Na Sowas schrieb:
> welches die heiklen Teile sind, die sich nicht
> nach der Simulation verhalten.
Na ist doch klar: die asynchronen glitschigen Eingänge tun das nicht...

von Igor (Gast)


Lesenswert?

Hallo, also zunächst vielen Dank für die Antworten.

Die Verwendung des Wortes "Glitches" mag irreführend sein. Im Grunde 
möchte ich ein variables (Subclock) Taktsignal erzeugen. Dieses soll im 
Grunde (fast) immer einen einheitlichen Takt liefern, ausser wenn 
gewisse Bedingungen eintreffen (TRG=1), soll eine gewisse Anzahl an 
kürzeren/längeren Taktintervallen eingefügt werden. Danach soll mit dem 
ursprünglichen Signal weiter gemacht werden.

>Was für ein Triggersignal? Woher kommt das?
Das Triggersignal ist ein asynchrones Signal aus einer anderen 
(langsameren) Clock Domain, und ist über 2 Flip-Flops in die PLL 
Clock-domain (fCLK 300MHz) geschiftet worden.

>Wieviele Takte (mit rising_edge() oder falling_edge() oder 'event) hast
du in deinem Design?
Das ist variabel einstellbar (über einen Softcore) zw. 1 bis 2^32 - 1 
(unsigned definedClockCnt).

>Warum gibt mir das so sehr zu denken? Woher kommt ready?
ready wird auf 1 gezogen, sobald der definedClockCnt und weitere 
parameter über den Softcore eingestellt worden sind. Im Grunde soll es 
soetwas wie ein reset_n sein.

Was in der Simulation nie vorkommt, aber im realen Fall schon, ist, dass 
der clockCnt manchmal über den Wert von definedClockCnt überläuft, was 
ich mir auf Grund des Codes nicht erklären kann, da das in jedem Zustand 
eigentlich verhindert sein sollte. Wie kann es dazukommen? Alle signale 
sind unsigned 32 bit. Kann es sein, dass die 300 MHz zu hoch sind und es 
deswegen nicht funktioniert, obwohl der TimeQuest Analyzer sagt, dass 
diese Frequenz ok ist?

Danke & lg Igor

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


Lesenswert?

Igor schrieb:
> Kann es sein, dass die 300 MHz zu hoch sind
> Alle signale sind unsigned 32 bit.
32-Bit-Zähler mit 300MHz? 32-Bit-Vergleicher mit 300MHz?
300MHz sind nicht allzu leicht zu erreichen, da gehört schon einiges an 
Erfahrung dazu. Eine Logikebene zuviel und das wars...

> obwohl der TimeQuest Analyzer sagt, dass diese Frequenz ok ist?
Hat der das Richtige analysiert? Hast du ihm mitgeteilt, wieviel du 
haben willst?

> Was in der Simulation nie vorkommt, aber im realen Fall schon, ist, dass
> der clockCnt manchmal über den Wert von definedClockCnt überläuft
Eine amoklaufende Statemachine also (ein Zähler ist die einfachste Form 
einer FSM). Da kommt eine Weiterschaltbedingung zu spät, und so 
verstolpert sich der Zähler...

von Igor (Gast)


Lesenswert?

>32-Bit-Zähler mit 300MHz? 32-Bit-Vergleicher mit 300MHz?
Ok, 32 Bit brauch ich eigentlich eh nicht. Glaubst Du,
dass es mit 16 bzw. 10 Bit gehen würde, also dass man dann auf die 300 
MHz kommt?

>Hat der das Richtige analysiert? Hast du ihm mitgeteilt, wieviel du
>haben willst?
Ich glaube schon, ich habe derive_pll_clocks im SDC File und anfangs hat 
er gemeckert und gemeint, dass die PLL nur mit 190MHZ betrieben werden 
dürfe,
aber dann habe ich ein paar Pfade als false_path eingetragen und jetzt 
meint er, FMAX für die PLL wären ca. 350 MHz.

von _bla_ (Gast)


Lesenswert?

Mal ein paar Vorschläge von mir:

1. Zähle den Counter für die Glitches runter auf 0. Bewirkt am Ende das 
Gleiche, macht aber die Logik einfacher, denn so musst du nur noch mit 
einer statischen Null vergleichen und nicht mehr mit einem Wert der in 
irgendwelche Registern zwischengelagert werden muss.

2. Es ist nicht unwahrscheinlich, das du zu viele Pfade als false_path 
eingetragen hast.

3. Ich weiß nicht genau, wie das bei Altera ist, aber normalerweise gibt 
man Zielvorgaben an und schaut nicht auf irgendwelche FMAX Werte. Denn 
diese Timing Constrains haben auch Einfluss auf Synthese und Place & 
Route.

4. Wenn du das Ganze extern brauchst: Du kannst ein DDR Output Register 
verwenden und das gleiche Ergebnis auch mit nur 150 Mhz Clock erreichen.

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.