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
elsifrising_edge(fClk)then
10
caserunStateis
11
12
whenNORMAL_RUN=>
13
14
if(TRG='1'orclockCnt=definedClockCnt)then-- wenn getriggert oder der counter den vordefinierten wert erreicht hat -> flanke
15
oCLK<=notoCLK;
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
endif;
22
23
clockCnt<=(others=>'0');
24
25
else
26
clockCnt<=clockCnt+1;--sonst counter erhöhen
27
endif;
28
29
whenGLITCHING=>
30
31
if(clockCnt=definedGlitchCnt)then--dauer der glitche -> flanke
32
oCLK<=notoCLK;
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
endif;
41
42
else
43
clockCnt<=clockCnt+1;--counter erhöhen
44
endif;
45
46
whenPOST_TRIGGER=>
47
48
if(clockCnt=definedClockCnt)then--normaler takt
49
oCLK<=notoCLK;
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
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...
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.
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
elsifrising_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...
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
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...
>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.
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.