Ich versuche, mit DSP in meinem Spartan-3-Board zu beginnen. Ich habe eine AC97-Karte mit einem Chip von einem alten Motherboard hergestellt und bisher ADC ausgeführt, die Samples mit einer Zahl <1 multipliziert (Lautstärke verringern) und dann DAC.
Jetzt möchte ich einige grundlegende DSP-Aufgaben ausführen, z. B. einen Tiefpassfilter, einen Hochpass usw. Aber ich bin wirklich verwirrt über die numerische Darstellung (Ganzzahlen? Festpunkt? Q0.15? Überlauf oder Sättigung?).
Ich möchte nur einen Beispielcode eines tatsächlichen einfachen Filters, um mich anzufangen. Keine hohe Effizienz, schnell oder so etwas. Nur der theoretische Filter, der in VHDL implementiert ist.
Ich habe gesucht, aber ich finde nur theoretische Formeln - ich verstehe, was ich nicht verstehe, ist, wie man die signierten 16-Bit-48-kHz-Audio-Samples verarbeitet, die ich vom ADC erhalte. Ich habe diese Bibliotheken verwendet: http://www.vhdl.org/fphdl/ . Wenn ich meine Samples mit 0,5, 0,25 usw. multipliziere, kann ich den Unterschied hören. Aber ein größerer Filter gibt mir nur Rauschen.
Vielen Dank.
Antworten:
Es hört sich so an, als müssten Sie zuerst die DSP-Aspekte herausfinden und dann eine Implementierung in FPGA vornehmen.
In Bezug auf Datentypen können Sie ganzzahlige Zahlen verwenden.
Hier ist ein Beispielcode, der Sie zum Laufen bringt. Beachten Sie, dass viele reale Probleme fehlen (z. B. Zurücksetzen, Überlaufmanagement) - aber hoffentlich lehrreich:
quelle
Der einfachste Tiefpass-FIR-Filter, den Sie ausprobieren können, ist y (n) = x (n) + x (n-1). Sie können dies ganz einfach in VHDL implementieren. Unten finden Sie ein sehr einfaches Blockdiagramm der Hardware, die Sie implementieren möchten.
Gemäß der Formel benötigen Sie die aktuellen und vorherigen ADC-Beispiele, um die entsprechende Ausgabe zu erhalten. Was Sie tun sollten, ist, die eingehenden ADC-Abtastwerte an der fallenden Flanke des Takts zu speichern und die entsprechenden Berechnungen an der ansteigenden Flanke durchzuführen, um die entsprechende Ausgabe zu erhalten. Da Sie zwei 16-Bit-Werte addieren, erhalten Sie möglicherweise eine 17-Bit-Antwort. Sie sollten die Eingabe in 17-Bit-Registern speichern und einen 17-Bit-Addierer verwenden. Ihre Ausgabe sind jedoch die unteren 16 Bits der Antwort. Code sieht vielleicht so aus, aber ich kann nicht garantieren, dass er vollständig funktioniert, da ich ihn nicht getestet oder gar synthetisiert habe.
Wie Sie sehen können, können Sie diese allgemeine Idee verwenden, um kompliziertere Formeln hinzuzufügen, z. B. solche mit Koeffizienten. Kompliziertere Formeln wie IIR-Filter erfordern möglicherweise die Verwendung von Variablen, um die Algorithmuslogik korrekt zu machen. Eine einfache Möglichkeit, Filter mit reellen Zahlen als Koeffizienten zu umgehen, besteht darin, einen Skalierungsfaktor zu finden, damit alle Zahlen so nahe wie möglich an ganzen Zahlen liegen. Ihr Endergebnis muss um denselben Faktor verkleinert werden, um das richtige Ergebnis zu erhalten.
Ich hoffe, dies kann Ihnen von Nutzen sein und Ihnen helfen, den Ball ins Rollen zu bringen.
* Dies wurde so bearbeitet, dass sich das Daten-Latching und das Output-Latching in getrennten Prozessen befinden. Verwenden Sie auch signierte Typen anstelle von std_logic_vector. Ich gehe davon aus, dass Ihr ADC-Eingang ein std_logic_vector-Signal sein wird.
quelle
Ein weiteres einfaches Code-Snippet (nur der Mut). Hinweis: Ich habe die VHDL nicht direkt geschrieben, sondern MyHDL zum Generieren der VHDL verwendet.
Dies ist eine direkte Implementierung. Es werden Multiplikatoren benötigt. Die Synthese dieser Schaltung, die auf einen Altera Cyclone III abzielte, verwendete keine expliziten Multiplikatoren, sondern erforderte 350 Logikelemente.
Dies ist ein kleiner FIR-Filter und hat die folgende Antwort (nicht so gut), sollte aber als Beispiel nützlich sein.
Außerdem habe ich hier und hier ein paar Beispiele, die nützlich sein könnten.
Außerdem scheint Ihre Frage zu lauten: "Was ist eine angemessene Festpunktdarstellung?" Bei der Implementierung von DSP-Funktionen wird häufig die Festpunktdarstellung verwendet, da dies die Analyse der Filter vereinfacht. Wie bereits erwähnt, ist der Festpunkt nur eine ganzzahlige Arthimetik. Die eigentliche Implementierung arbeitet einfach mit ganzen Zahlen, aber unsere vorgefertigte Darstellung ist gebrochen.
Probleme treten normalerweise beim Konvertieren von Implementierungs-Ganzzahlen (Festkomma) in Design-Gleitkomma auf.
Ich weiß nicht, wie gut die VHDL-Festkomma- und Gleitkommatypen unterstützt werden. Sie werden in der Simulation gut funktionieren, aber ich weiß nicht, ob sie mit den meisten Synthesewerkzeugen synthetisieren werden. Ich habe dafür eine separate Frage erstellt .
quelle
OpenCores verfügt über eine Reihe von DSP-Beispielen, IIR und FIR, einschließlich BiQuad. Sie müssen sich registrieren, um die Dateien herunterladen zu können.
edit
Ich verstehe Kortuks Kommentar zu toten Links, und wenn der Link zu OpenCores stirbt, wird die Antwort nutzlos. Ich bin ziemlich zuversichtlich, dass dies nicht passieren wird. Mein Link ist generisch und stirbt nur, wenn die gesamte OpenCores-Domain verschwindet.
Ich habe versucht, nach Beispielen zu suchen, die ich für diese Antwort verwenden könnte, aber sie sind alle zu lang, um hier dargestellt zu werden. Also werde ich mich an meinen Rat halten, mich selbst für die Site zu registrieren (ich musste nach New York ziehen, weil meine Heimatstadt nicht akzeptiert wurde) und mir den dort präsentierten Code ansehen.
quelle
Ich habe versucht, Skripte für die authomatische Implementierung von IIR-Filtern zu implementieren, in denen Sie festlegen können, ob das Design so schnell wie möglich (damit jede Multiplikation mit einem dedizierten Multiplikator durchgeführt wird) oder so klein wie möglich (damit jeder Multiplikator wiederverwendet wird) sein soll.
Die Quellen wurden auf alt.sources als "Verhaltensbezogene, aber synthetisierbare Implementierung von IIR-Filtern in VHDL" veröffentlicht (Sie finden sie auch im Google-Archiv: https://groups.google.com/group/alt.sources/msg/c8cf038b9b8ceeec) dmode = source )
Beiträge zu alt.sources sind im "shar" -Format, daher müssen Sie die Nachricht als Text speichern und die Freigabe (mit dem Dienstprogramm "unshar") aufheben, um Quellen abzurufen.
quelle
Wie wäre es damit? https://github.com/MauererM/VIIRF
Es implementiert einen Biquad-basierten IIR-Filter (SOS, Abschnitte zweiter Ordnung), der sich um die Festkomma-Implementierung kümmert. Es enthält auch Python-Skripte zum Entwerfen und Überprüfen des Filters. Es werden keine herstellerspezifischen FPGA-Konstrukte verwendet, und Sie können den Kompromiss zwischen Hochgeschwindigkeits- und Niedrigbereichsnutzung wählen.
quelle