Hallo,
ich würde gerne ein Signal um eine beliebige Anzahl von Takten
verzögern.
Die Forumsuche habe ich schon verwendet, jedoch bin ich nur auf den
Lösungsansatz mit dem Schieberegister gekommen. Wenn ich diese Variante
für mein Design verwende, verbrauche ich zuviele Ressourcen. Ich würde
gerne ein 4KHz Signal um mindestens 2 Perioden permanent verzögern. Hab
schon einwenig recherchiert, dass man es mit einem Counter realisieren
kann. Nun meine Frage, ob jemand einen Beispiel-Code von so einer
Verzögerung mittels Counter hat.
lg
Christoph M. schrieb:> Hab schon einwenig recherchiert, dass man es mit einem Counter> realisieren kann.
Das ist wie wenn ich schreibe:
Ich hab gehört, dass man ein Auto mit Stahl realisieren kann...
> Nun meine Frage, ob jemand einen Beispiel-Code von> so einer Verzögerung mittels Counter hat.
Was du brauchst ist ein Ringpuffer, mit einer Speichertiefe von
2*fadc/4kHz Worten. Wenn du also dien Signal z.B. mit 48kHz abtastest,
dann brauchst du einen Speicher mit 2*48/4 = 24 Worten
> Ich würde gerne ein 4KHz Signal
WAS für ein signal? Analog/Digital?
> um mindestens 2 Perioden permanent verzögern.
Um 2 Perioden von was?
Ist die Frequenz des Signals konstant?
Welche Abtastrate hat dein ADC?
Und richtig: zur Realisierung eines Ringpuffers brauchst du (mindestens)
einen Zähler. Aber viel wichtiger ist der Speicher...
Danke für die schnelle Antwort.... :)
Lothar Miller schrieb:> Christoph M. schrieb:>> Hab schon einwenig recherchiert, dass man es mit einem Counter>> realisieren kann.> Das ist wie wenn ich schreibe:> Ich hab gehört, dass man ein Auto mit Stahl realisieren kann...
Ja war ein bisschen blöd formuliert... :)
Lothar Miller schrieb:>> Ich würde gerne ein 4KHz Signal> WAS für ein signal? Analog/Digital?>> um mindestens 2 Perioden permanent verzögern.> Um 2 Perioden von was?> Ist die Frequenz des Signals konstant?> Welche Abtastrate hat dein ADC?
Es handelt sich um ein Rechtecksignal mit 4 KHz welches konstant bleibt.
Dieses Signal möchte ich mit dem FPGA um 2 Perioden von diesen 4 Khz
verzögern und wieder ausgeben.
Das ganze hat nichts mit einem ADC zu tun ich möchte nur dieses 4 KHz
Signal verzögern.
Mir ist schon klar, ich muss einen Counter verwenden, wenn ein
vorgegebener Wert erreicht ist habe ich dann auch meine Verzögerung
erreicht. Jedoch wie gebe ich dann das Signal aus. Ich denk mal es ist
ganz einfach nur ich komm da im Moment nicht weiter. Ich weiss nicht wie
ich es ausgeben soll (das verzögerte 4 KHz Signal)
lg
Christoph M. schrieb:> Ich hab mir mal 1us als Grenze gesetzt.
Dann wäre das gerade mal ein Schieberegister mit 250 Stellen. Das sind
gerade mal 16 Luts, wenn die als Schieberegister geschaltet werden.
Kleiner bekommst du das auch mit irgendwelchen Zählern und Speichern
niemals hin...
Du brauchst also
1. einen Zähler, der die die 1us Sample-Zeit erzeugt, und dann
2. das Schieberegister.
Nehmen wir mal 50MHz FPGA-Takt. Dann sieht das so aus:
Hallo
danke für deine Code, hab mein Taktfrequenz angepasst und siehe da es
funktioniert :)
Danke vielmals,
einmal muss ich noch lästig sein, ist es möglich die Einstellung der
Verzögerung sprich den Wert der Verzögerung variable zu machen?
Christoph M. schrieb:> siehe da es funktioniert :)
Klar. ;-)
> Danke vielmals,
De nada.
> einmal muss ich noch lästig sein, ist es möglich die Einstellung der> Verzögerung sprich den Wert der Verzögerung variable zu machen?
Ja.
Lothar Miller schrieb:> Aber wenn du das zur Laufzeit machen willst, wird dich das Ressourcen> kosten, weil dann keine LUTs mehr als Schieberegister verwendet werden> können...
dann kann man ein Block-RAM opfern und einen synchronen FIFO bauen. Ist
zwar auch Verschwendung, aber das RAM ist eh' auf dem Chip vorhanden.
Bei einem 2k*9 RAM koennte man sogar 2048*9 Werte fuer ein Signal
speichern...
berndl schrieb:> dann kann man ein Block-RAM opfern und einen synchronen FIFO bauen.
Das wäre auch elegant, dann könnte man auch den Jitter noch deutlich
reduzieren und vor allem: dann brauchen wir wieder den bereits erwähnten
Zähler.. ;-)
Hier mal die obige Lösung mit 255 Abgriffen:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entityDelaylineis
6
Port(clk:inSTD_LOGIC;
7
input:inSTD_LOGIC;
8
output:outSTD_LOGIC;
9
delay:inSTD_LOGIC_VECTOR(7downto0));
10
endDelayline;
11
12
architectureBehavioralofDelaylineis
13
signaloneus_cnt:integerrange0to49:=0;
14
signalwrptr:unsigned(7downto0):=(others=>'0');-- unsigned wegen des kostenlosen wrap-arounds... ;-)
15
signalrdptr:unsigned(7downto0):=(others=>'0');-- unsigned wegen des kostenlosen wrap-arounds... ;-)
16
typespeicherisarray(0to255)ofSTD_LOGIC;
17
signalmemory:speicher;
18
begin
19
20
processbegin
21
waituntilrising_edge(clk);-- 50MHz
22
if(oneus_cnt=49)then
23
memory(to_integer(wrptr))<=input;
24
wrptr<=wrptr+1;
25
rdptr<=wrptr-unsigned(delay);
26
oneus_cnt<=0;
27
else
28
oneus_cnt<=oneus_cnt+1;
29
endif;
30
endprocess;
31
32
output<=memory(to_integer(rdptr));
Und tatsächlich: es wird hier ein DP-RAM erkannt, das dann aber wegen
des geringen Speicherbedarfs in LUTs abgebildet:
1
INFO:Xst:3231 - The small RAM <Mram_memory> will be implemented on LUTs in
2
order to maximize performance and save block RAM resources. If you want to
3
force its implementation on block, use option/constraint ram_style.
Hallo,
ich hab mir die Realisierung mittels des Speichers nochmal angeschaut.
Kann es sein, dass die Läösung mit den 255 Abgriffen aber nur eine
Periode verzögter oder?
Ich hab es mal angepasst für 2 Perioden bzw. ich denke es sollte so
funktionieren.
Bin ich hier richtig von meiner Denkweise? Wenn ich das die Delay auf
den Wert 500 einstelle, dann sollte das Signal um 2 Perioden verzögert
sein oda?
lg
Leuchtet mir alles ein, nur wieso passt denn Lothars Lösung rein? Ich
dachte ein Schieberegister passt NICHT?
Sonst wär mir nur ein entsprechend langsamer Takt eingefallen. Phase von
dem Rechtecksignal ist vermutlich konstant?
Hallo,
ja ist konstant!
Sagen wir es mal so....
Er kann VHDL ich noch nicht so gut.. :)
Theoretisch müsste ich aber die 1us auch noch reduzieren können oder??
Könnte es mit 100ns noch klappen?
Christoph M. schrieb:> Bin ich hier richtig von meiner Denkweise? Wenn ich das die Delay auf> den Wert 500 einstelle, dann sollte das Signal um 2 Perioden verzögert> sein oda?
Was sagt denn deine Simulation?
Meine sagt (für meinen Code) auf jeden Fall: Ja, stimmt.
Hallo,
ok die Größe vom Array war falsch
jetzt sagt die meine Simulation auch, dass es passt.. :)
danke!
und noch zur Frage der Genauigkeit. Dazu müsste ich den oneus_cnt
counter und das Array anpassen oder?
lg
Christoph M. schrieb:> und noch zur Frage der Genauigkeit.
Fachwort: Jitter
> Dazu müsste ich den oneus_cnt counter und das Array anpassen oder?
Ja, du müsstest öfter abtasten: Wenn du alle 500ns abtastest, dann
brauchst du doppelt soviel Speicher und bekommst den halben Jitter.
Wenn man Dein Bild so anschaut, dann sieht das aus wie ein Taktsignal.
Wenn man einen Takt um das Vielfache einer Periodendauer verzögert, dann
hat man wieder das selbe Taktsignal, lediglich mit einer einzigen
Verzögerung am Anfang. Wenn die 4kHz fest sind, dann kannst Du diese
Einschaltverzögerung mit einem x-beliebigen Zähler und einem clock gate
bauen.
Ansonsten natürlich ein Schieberegister...
Gruß
Marcus