Das Blockschaltbild der HBF-Kaskade

In der ersten Annäherung bekommen wir einen Datenstrom von Samples vom ADC im 1 MHz Takt und liefern Samples mit 1 MHz durch 256. Dafür brauchen wir mindestens einen Speicher für Daten und Koeffizienten, einen MAC (z.B. DSP48E1 bei Xilinx) und eine etwas komplexe Ablaufsteuerung, die das ganze organisiert.

Erst mal müssen wir uns überlegen was wir für einen Speicher brauchen. Die erste Randbedinung ist die Geschwindigkeit für den Datenzugriff. Die Eingangsdaten kommen mit 1 MHz bei einem Verarbeitungstakt von 100 MHz (es geht auch mit 200, aber gehen wir es gemütlich an). Die erste Stufe des HBFs wird also nur alle 200 Takte aktiviert (es wird ja nur jeder zweite Wert berechnet). Für die Berechnung werden 4 Koeffizienten und neun Daten gelesen und ein Wert geschrieben. Damit wären 14 der 200 Takte belegt. Die nächste Stufe wird nur alle 400 Takte benötig u.s.w. so dass durch die ersten 6 Stufen vielleicht 26 der 200 Takte belegt sind, also 13 %, die letzten beiden HBF haben mehr Koeffizienten, aber da haben wir noch reichlich Luft.

Die zweite Rahmenbedingung ist der Speicherbedarf. Wir brauchen zyklischen Speicherzugriff für die Eingangsdaten, die Basisadresse muss also ein vielfaches des 2X Datenspeichers sein. Die Filterlänge der ersten Stufen ist 15, da wäre mit 32 als Puffergröße also ausreichend Luft. Die Stufe 7 hat 23 Koeffizienten und kommt auch mit 32 aus. Einzig Stufe 8 mit 67 Koeffizienten braucht mit 128 Werten richtig Platz. Dazu kommen die Koeffizienten mit 4 für die ersten 6 Stufen, die aber nur ein mal vorhanden sein müssen, 6 Koeffizienten für Stufe 7 und 17 für Stufe 8. Insgesamt brauchen wir also mindestens 128 + 7 *  32 + 17 + 7 + 4 =  380, also 512. Das heißt auch hier kommen wir mit einem normalen Blockram von 16/18 kBit aus, selbst wenn wir auf höhere Bitbreiten für Daten oder Koeffizienten gehen wollen.

Da wir mit Initialisierung nur 5 MAC-Operationen pro Filterung brauchen ist dieser deutlich weniger belegt als das RAM, hier haben wir also kein Problem mit dieser Ressource auszukommen.

Jetzt kommt es zum Eingemachten. Der Ablaufsteuerung. Wir benötigen Kontrolle über die verschiedenen Zeiger (Schreib-/Lesezeiger) und Zähler (wie viele Daten in einem Teilvektor gültig sind). Das könnte man in einer Ablaufsteuerung hinbekommen, aber ich will da auf eine alte Tradition zurückgreifen. Der Mikroprogrammierung. Das wird bestimmt lustig.

Blockdchaltbild HBF-Kaskade

Das Signal kommt von links und wird im RAM gepuffert. Die Ablaufsteuerung kümmert sich um die korrekte Adressierung des DPRAMs, taktet die Notwendigen Daten in die Übergaberegister des MAC und steuert diesen über seine Control-Leitungen.

Die Zwischenergebnisse der Berechnungen werden wieder unter Kontrolle der Ablaufsteuerung in das RAM geschrieben und das Endergebnis direkt ausgegeben (dazu wird natürlich auch ein Clock-Enable erzeugt, welches hier nicht eingezeichnet wurde).

Bereich Startadresse Größe (Worte) Endadresse Bemerkung
Stufe 8 0x0000 128 0x007F
Stufe 7 0x0080 32 0x009F
Stufe 6 0x00A0 32 0x00BF
Stufe 5 0x00C0 32 0x00DF
Stufe 4 0x00E0 32 0x00FF
Stufe 3 0x0100 32 0x011F
Stufe 2 0x0120 32 0x013F
Stufe 1 0x0140 32 0x015F
Coeff 8 0x0160 32 0x017F
Coeff 7 0x0180 8 0x0187
Coeff 6 0x0188 4 0x018B
Coeff 5 0x018C 4 0x018F
Coeff 4 0x0190 4 0x0193
Coeff 3 0x0194 4 0x0197
Coeff 2 0x0198 4 0x019B
Coeff 1 0x019C 4 0x019F
Alignment 0x01A0 352 0x02FF Padding auf 512-128
Param 8 0x0300 8 0x0307
Param 7 0x0308 8 0x030F
Param 6 0x0310 8 0x0317
Param 5 0x0318 8 0x031F
Param 4 0x0320 8 0x0327
Param 3 0x0328 8 0x032F
Param 2 0x0330 8 0x0337
Param 1 0x0338 8 0x033F
Reserved 0x0340 448 0x04FF Restlicher Speicher