Hallo
ich arbeite zur Zeit daran ein Mikrofon mit einem Pulsdichtemoduliertem
1Bit-breiten Sigma-Delta Ausgang mittels VHDL an einem Spartan3-FPGA
anzusprechen. Dazu wollte ich einen CIC-Decimation Filter (Hogenhauer
Filter, N=5, R=256, M=1) zusammen mit einem nachgeschalteten
FIR-Compensation Filter (61 taps) verwenden. Im Endeffekt soll der FPGA
8Bit PCM-Samples mit 9000Hz über eine RS232-Schnittstelle an einen PC
übertragen.
Der FIR-Filter selber kommt als IP-Core daher, die Koeffizienten hab
ich. Den CIC-Teil muss ich selbst implementieren.
Leider tu ich mich da sehr schwer... Das Ausgangssignal der Simulation
mit bereits geschriebenem VHDL-Code und einem Testsample hört sich
übelst an. So als ob das Mikrofon stark übersteuert. Also begebe ich
mich auf Fehlersuche...
In Matlab hab ich so einen Filter stehen. Bei der Übertragung in VHDL
habe ich zwar eigentlich auch keine Fehler gemacht... Aber fangen wir
von vorne an. Könnte vielleicht mal jemand einen Blick drauf werfen,
seinen Senf geben? Erst eine Funktion um ein Sample zu Filtern, dann das
Plotten der Impulsantwort. Matlab/Octave.
Den Filter hatte ich in kompliziert auch schon geschrieben, aber dann
nochmal aus einer übersichtlichen Diplomarbeit[1] übernommen. Der Code
für den CIC-Filter sieht ja ganz nett aus, aber ich stehe vor dem
Problem das Ergebnis zu interpretieren.
Wenn ich eine Impulsantwort generiere, sollte ich doch aus der
Fouriertransformierten den Frequenzgang erstellen können? Denjenigen
welchen ich herausbekomme kann man aber gar nicht mit dem für CIC-Filter
auf Einschlägigen Seiten vergleichen. Ich vermisse die "Nebenkeulen",
die "Aliasbänder", das "nachhoppeln" der Kennlinie...
Für kleine Werte von R (zB R=4) kommt beim Frequenzgang Mumpitz heraus,
aber das schiebe ich mal auf Rundungsfehler in Octave?
[1] http://opus.haw-hamburg.de/volltexte/2009/750/
Ein super Trick bei FIR Filtern ist einfach mal alle Koeffizienten bis
auf einen zu Null zu setzen. Wenn dann immer noch Blödsinn herauskommt,
liegt es nicht an der Übertragungsfunktion.
Versuch das Problem in einzelne Blöcke zu teilen.
Du könntest Deinen CIC-Teil mit einer vordefinierten Datenfolge aus dem
internen RAM füttern und dir die Impulsantwort anschauen.
Ebenso kannst Du dir einen Test-Generator für das pulsdichtemodulierte
Signal bauen und so den Decimation-Teil testen.
Leider bringt es nix fünf ungetestete Teile zusammen zu dengeln und
hinterher zu fragen, warum das Gesamtsystem es nicht tut.
marvin schrieb:
> Den CIC-Teil muss ich selbst implementieren.
Bei Xilinx gibt es im Coregen den CIC-Compiler. Vielleicht kann der Dir
weiterhelfen.
Ansonsten, wie mischu schon schrieb, teile und herrsche:
Da Du ein Referenzmodell hast kannst Du Deinen VHDL-Code simulieren
(Stichwort VHDL Testbench) und die Werte vergleichen.
Duke
Ja das ist ja auch mein Gedanke gewesen. Deswegen wollte ich sicher
gehen das mein CIC-Modell in Matlab richtig arbeitet. Eben weil die
Ergebnisse nicht das sind, was ich erwarten würde. Den Frequenzgang
würde ich gar nicht so erwarten wie ich ihn im ersten Post angehängt
hab...
Den CIC-Compiler kann ich leider nicht nehmen da ich aus völlig
unverständlichen Gründen die Xilinx Version 10.4 verwenden muss, welche
nur den CIC-Compiler 3.0 mitliefert -- dieser Version fehlt aber der
Support für meinen Spartan3!
hallo, möchte fragen.
ist es möglich eine genau R=1000 zu setzen? oder muss ich
in konstellation bitzahl (hier=1024) nehmen?
mir ist noch verwirren.. Vielen Dank..
Hi Steve
klar, theoretisch beziehungsweise in Matlab/Octave kannst du jedes R
nehmen, wie du willst. Aber die Hardwareimplementierung wird
effizienter, wenn du Potenzen von 2 als Teiler nimmst -- einfach weil du
einen Zähler- und Vergleichbaustein brauchst, welcher alle 1000 Samples
die nächste Stufe antippt. So ein Zähler ist aber in einer Schaltung
einfacher zu bauen, wenn er nur alle 1024 Samples tippen muss.
Hallo Marvin,
danke dir für deine Aufklärung..
kannst du (oder anderen) mir nochmal erklaren bitte.
es steht in der Literatur M=Delay.
(nach der Noble-identity, wo R steht zwischen Integrator und Comb)
ist M verhält sich als Teiler von R? was spielt eigentlich M hier?
meine Aufgabe besteht darin, dass ich
aus bereit abgetastete Eingangssignal 192Mhz
um 192Khz dezimiere, also welche Werte R und M wähle ich?
ich habe die Werte von Frequenz 192Mhz, M=1 und R=1000 ohne Skalierung
einfach eingeben, aber irgendwie
geht mein Rechner sehr langsam. Danke nochmals..
Steve
Antwort mit eigener Frage angehängt ;-)
-----------------------------------------------------------
Ich würde mir mal das Paper von Eugene Hogenhauer ansehen, wo er die
CIC-Filter beschreibt (einfach bei Google suchen, da gibts nichts
anderes). Finde ich im Nachhinein(!) am hilfreichsten, wenn auch nicht
am übersichtlichsten.
R ist der Rate-Change -- also der Frequenz-Faktor zwischen dem linken
und rechten Teil der Schaltung. Das ist die Eigenschaft um eine
Dezimation zu erreichen.
M ist der Unit-Delay, und sagt aus, wie lange die Comb-Sektionen jeweils
ein Signal zwischenspeichern sollen, bevor es wieder subtrahiert wird.
Dieser Parameter sorgt für breitere "Gaps" zwischen den "Beulen" im
Frequenzgang und ist normalerweise sowieso 1 oder 2. Ich denke mal du
bist mit 1 gut beraten!
N ist die Anzahl der Integrator- und Comb-Stufen. Er sorgt für steilere
Flanken im Frequenzgang. Das hängt von deiner Anwendung ab, was du da
haben willst -- Werte von 1 bis 5 sind vielleicht "üblich".
Wenn du ein 192Mhz Signal auf 192kHz downsamplen willst, scheinst du
durchaus einen glatten 1000er als Teiler nehmen zu können. Das die
Berechnung aufwendig ist stellt auch niemand in Frage ;-)
-----------------------------------------------------------
Ich hab vielleicht aber noch eine Frage an das geneigte Publikum. Wie
sollte denn die Antwort eines CIC-Filters auf ein Rechtecksignal
aussehen? Wie also verhält sich der Ausgang bei einem Sprung auf "1" am
Eingang?
Meiner Meinung nach sollte doch jeder reguläre Filter irgendwann auch 1
erreichen. Meine implementierung erreicht aber irgendwie genau -1. Auch
wenn ich -1 an den Eingang lege komm -1 heraus... Seltsames Verhalten
oder Realität?
Ich hab mal einen Plot des Problems angehängt (Hier die Version mit -1
am Eingang, der Ausgang ist aber der gleiche wie bei +1... Das kann ich
mir nicht erklären, wo ich noch einen Fehler gemacht haben sollte in
meinem VHDL-Code... Nicht das der Ausgang am Ende doch immer so
aussieht...???