Forum: Digitale Signalverarbeitung / DSP / Machine Learning Probleme bei der IIR-Filter Realisierung


von Chris c. (chris78)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe Probleme eine geeignete Realisierung für mein Projekt zu finden 
und wollte fragen, ob jemand mit Erfahrungen in DSPs oder FPGAs evtl. 
eine geeignete Lösung oder eine andere Lösungsmöglichkeit kennt.
Es geht um die digitale Nachbildung eines analogen Kanalmodells.
Ich habe ein PDF-Dokument angehängt, um meine Probleme (Seite 6) und 
meinen Lösungsansatz möglichst kurz und genau zu beschreiben und wäre 
sehr dankbar, wenn Ihr euch das einmal anschauen und bewerten könntet. 
Ein Produktvorschlag, eine alternative Lösungsmöglichkeit oder ähnliches 
könnten mir vermutlich weiterhelfen.

Bitte nicht wundern, der angehängte Text war ursprünglich für einen 
meiner Professoren gedacht und klingt deshalb vielleicht manchmal noch 
etwas eigenartig. Auch habe ich versucht, mich möglichst kurz zu fassen, 
weshalb ich z.B. die Polstellenbetimmung u.a. nicht erwähne...

MfG
Christoph

von pumpkin (Gast)


Lesenswert?

Moin moin, ich kann versuchen zu helfen. Wenn ich recht verstanden habe 
ist dein Problem die schnelle Wandlung und die beschränkte 
Geschwindigkeit des DSP's (habe nur die Seite 6 gelesen)? Du hast aber 
einen Virtex an der Hand? Kann mir garnicht vorstellen, dass der DSP zu 
langsam ist (kenne aber das Modell nicht). Einen schnellen 
Codec/Coder/Decoder zu bekommen sollte nicht das Problem sein wenn du 
dich zur Lösung mit dem Virtex hinreissen lässt. Wieso willst du 
Aufsteckmodule an den DSP heften, der TI hat doch mit Sicherheit 
Möglichkeiten eigene Hardware zuzubauen (auch wenn man hier auf 
"fertige" Bibliotheken verzichten muss)?

Meine persönliche Meinung: FPGA mit zugesetztem AD/DA, auch wenn's 
wesentlich langweiliger ist  ;^)  .

pumpkin

von Chris c. (chris78)


Lesenswert?

>pumpkin wrote:
> Moin moin, ich kann versuchen zu helfen. Wenn ich recht verstanden habe
> ist dein Problem die schnelle Wandlung und die beschränkte
> Geschwindigkeit des DSP's (habe nur die Seite 6 gelesen)? Du hast aber
> einen Virtex an der Hand? Kann mir garnicht vorstellen, dass der DSP zu
> langsam ist (kenne aber das Modell nicht).

Bisher habe ich mit dem Texas Instruments DSK-Bord TMS320C6713 
gearbeitet , welches an der Grenze der Berechnungsgeschwindigkeit liegt. 
Ich könnte aber ziemlich sicher mit einem Virtex Bord arbeiten, habe 
allerdings keine Ahnung von VHDL Programmmierung und mich deshalb 
erstmal mit dem TI-DSK Bord beschäftigt, allerdings sollte der C-Code 
doch mit ein paar VHDL-Grundkenntnissen umzusetzen sein, oder gibts da 
vielleicht nen C++/VHDL-Compiler?

> Einen schnellen
> Codec/Coder/Decoder zu bekommen sollte nicht das Problem sein wenn du
> dich zur Lösung mit dem Virtex hinreissen lässt.

Kennst Du da vielleicht ein Produktbeispiel? Der AD/DA Wandler sollte 
1000€ nicht überschreiten (besser 500€).

> Wieso willst du
> Aufsteckmodule an den DSP heften, der TI hat doch mit Sicherheit
> Möglichkeiten eigene Hardware zuzubauen (auch wenn man hier auf
> "fertige" Bibliotheken verzichten muss)?

Ich war bisher der Meinung, dass ich bei einem Eigenentwurf mit solchen 
Geschwindigkeiten ziemliche EMV-Probleme mit Taktleitungen etc. bekomme?

> Meine persönliche Meinung: FPGA mit zugesetztem AD/DA, auch wenn's
> wesentlich langweiliger ist  ;^)  .

Wie steuert man solch einen AD/DA-Wandler denn an? Sollte so ein WAndler 
aus einem R-Netzwerk bestehen, oder anders aufgebaut sein?
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#DAC_.C3.BCber_mehrere_digitale_Ausg.C3.A4nge

MfG

von pumpkin (Gast)


Lesenswert?

> Bisher habe ich mit dem Texas Instruments DSK-Bord TMS320C6713
> gearbeitet , welches an der Grenze der Berechnungsgeschwindigkeit liegt.

Sicherlich in C/C++ progammiert?

> Ich könnte aber ziemlich sicher mit einem Virtex Bord arbeiten, habe
> allerdings keine Ahnung von VHDL Programmmierung und mich deshalb

Das ist eher schlecht. Frustfaktor ist bei VHDL imho recht hoch - das 
war zumindest bei mir so weil ich die Sprache für etwas inkonsistent 
halte.

> erstmal mit dem TI-DSK Bord beschäftigt, allerdings sollte der C-Code
> doch mit ein paar VHDL-Grundkenntnissen umzusetzen sein, oder gibts da
> vielleicht nen C++/VHDL-Compiler?

Keine Ahnung.

> Kennst Du da vielleicht ein Produktbeispiel? Der AD/DA Wandler sollte
> 1000€ nicht überschreiten (besser 500€).

Leider nicht, aber wenn du das selber aufbaust sollten diese Summen mehr 
als ausreichen.

> Ich war bisher der Meinung, dass ich bei einem Eigenentwurf mit solchen
> Geschwindigkeiten ziemliche EMV-Probleme mit Taktleitungen etc. bekomme?

Eher nicht wenn du das alles schön kompakt machst.

> Wie steuert man solch einen AD/DA-Wandler denn an? Sollte so ein WAndler
> aus einem R-Netzwerk bestehen, oder anders aufgebaut sein?

Kommt drauf an was das für einer ist, gerne seriell. Ich denke ein 
Flash-AD könnte eine gute Wahl sein.


pumpkin

von Chris c. (chris78)


Lesenswert?

Hi Pumpkin,
erstmal vielen Dasnk für Deine schnelle Hilfe

>pumpkin wrote:
> Sicherlich in C/C++ progammiert?
Ja, mit CodeComposerStudio 3.1.0.

> Das ist eher schlecht. Frustfaktor ist bei VHDL imho recht hoch - das
> war zumindest bei mir so weil ich die Sprache für etwas inkonsistent
> halte.
Wie komplex könnte folgendes Programm denn in VHDL werden?
1
#include "DSK6713_AIC23.h"          //codec-DSK file support
2
Uint32 fs=DSK6713_AIC23_FREQ_6.4MHZ;-)  //Da sich AD und DA-Wandler meist          
3
                                        //nicht getrennt initalisieren 
4
                                        //lassen, waehle ich die                                             
5
                              //am DA-Wandler geforderte Frequenz und neh-                                        
6
                              //me beim AD-Wandler bei 100-fach Over-                                        
7
                              //sampling nur jeden 100.Wert auf.
8
void main()
9
{
10
short sample_data;
11
12
double a0,a1,a2,b1,b2,u0=0,u1=0,u2=0,u3=0;  //Declare local variables
13
short u=0;    int j=100,k=0;
14
15
 a0 =  0.0957;     //Zählerkoeffizienten
16
 a1 =  0.1915;
17
 a2 =  0.0957;
18
 b1 = -0.5143;     //Nennerkoeffizienten
19
 b2 = -0.1028;
20
21
  comm_poll();                  //init DSK, codec, McBSP
22
  DSK6713_LED_init();
23
24
  while(1)            //infinite loop
25
  {
26
    if (j==100)
27
    {
28
    sample_data = input_sample(); //input sample mit 64KHz
29
    u0 = (double)sample_data;  //short/integer to double conversion
30
    j=0;
31
    k=0;
32
    };
33
    
34
//IIR 2.Ordnung mit 100fach Oversampling
35
    if (k<100)
36
    {
37
    u3 = a0*u0+u2;
38
    u2 = a1*u0-b1*u3+u1;
39
    u1 = a2*u0-b2*u3;
40
41
    u = (short)u3;    //double to short/integer conversion
42
    output_sample(u); //Ausgabe am DA-Wandler mit 6,4MHz
43
    k=k+1;  
44
    };
45
    j=j+1;
46
  }
47
}


> ...500€..., aber wenn du das selber aufbaust sollten diese Summen mehr
> als ausreichen. ...alles schön kompakt machst.
Würdest Du da mit Eagle eine mehrlagige Platine entwerfen oder reicht 
eine einfachere Realisierung?

> ...R-Netzwerk...Kommt drauf an was das für einer (AD/DA) ist, gerne
> seriell. Ich denke ein Flash-AD könnte eine gute Wahl sein.
Werd morgen mal schaun, was es dort so mit ausreichender 
Abtast-/Updaterate gibt, jetzt gehts ab ins Bett.

MfG

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

> double ...
> 100-fach Oversampling ...

Der C6713 ist ein sehr sehr schneller DSP. Er ist optimiert darauf genau 
das zu tun was du tust. Wenn der nicht mal einen IIR 2. O. bei der 
gewünschten Samplerate schafft, und du sogar noch anstrebst die 
Samplerate zu ver-x-fachen und die Ordnung auf 8 zu erhöhen, dann 
solltest du dir ernsthaft Gedanken machen ob dein Ansatz grundsätzlich 
überhaupt sinnvoll ist.

Aber bei der Implementierung dürfte sich noch einiges verbessern lassen, 
zwischen einem straightforward in C runtergeschriebenen Programm und 
einer auf die Hardware optimierten Version können bei einem DSP wie dem 
C6000 Welten liegen. Erst mal würde ich die if-Abfragen aus der inneren 
Schleife rauswerfen, die machen alles kaputt. Dann würde ich schauen ob 
es vielleicht eine optimierte Bibliotheksfunktion für IIR-Filter oder 
Assembler-Beispielcode gibt.

Der Virtex ist kein Allheilmittel. Bei Floating Point-Rechnungen und 
Abtastraten im MHz-Bereich erreicht man auch mit einem FPGA schnell das 
Ende der Fahnenstange.

Gruß
Andreas

von pumpkin (Gast)


Lesenswert?

C, dachte ich mir. Wenn dein DSP bei sowas frühzeitig in die Knie geht 
wundert mich das nicht, es handelt sich anscheinend um einen 
Festkomma-DSP. Da gibt es noch einen mächtigen Optimierungsbedarf. Ich 
denke der TI kann fractional rechnen, deine Bemühungen sollten sich 
darauf konzentrieren. Auch hardwareloops und circular buffering bringen 
einiges. Die Rechnerei mit Fließkomma ist hingegen keine gute Idee.

Doppelseitiges layout für einen/zwei Wandler plus Vogelfutter? Nein, das 
ist sicher nicht nötig.

Deine Berechnung ist in VHDL nicht viel länger.

Bett ist eine gute Idee  ;^)


pumpkin

p.s. Was ist das eigentlich für eine Sache mit dem ";-)" im code?
1
EQ_6.4MHZ;-)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Das ist ein Floating Point DSP. Ein IIR 8. Ordnung in Festkomma könnte 
ein wenig ungemütlich werden.

von Student (Gast)


Lesenswert?

Du rechnest jedes Sample einzeln aus. Das bringt natürlich einen 
ziemlichen Overhead beim Aufruf von 'input_sample()' und 
'output_sample()'.
Versuch mal vielleicht 100 Samples einzulesen, zu filtern und dann 
auszugeben. Das sollte schon einiges bringen.

von pumpkin (Gast)


Lesenswert?

FP, wusste ich nicht. Mir war so als wenn im Plichtenheft (das pdf) 
etwas von fixpoint stand. Aber wenn das so ist, dann vergiss den FPGA.

IIR 8. Ordnung würde hässlich werden, indeed! War in Gedanken bei den 
SOS'.


pumpkin

von Detlef _. (detlef_a)


Lesenswert?

Read the friendly datasheet: Der kleinste 6713 fängt an bei 334 MMACs, 
für nen IIR 8. Ordnung mit 17 MACs sind das also schlappe 20e6 maximale 
Samplerate. Für ne Abtastrate von 100*64Ks/s sind das immer noch Faktor 
3 mehr Leistung als Du brauchst. Nen 6713 für solch eine Aufgabe 
einzusetzen ist MAC-Verschwendung, das wird in der einschlägigen 
Industrie hart bestraft. Oder umgekehrt: Mit solch einem Geschoß kann 
man auch mal richtig große Filter rechnen!

IIR 8. Ordnung in 4*2.Ordnung zerlegen, das ist numerisch sehr viel 
günstiger, Berechnung geht dann auch in integer.

[Provokation] Richtige Signalverarbeiter nutzen sowieso nur integer. 
Signalverarbeiter, die in float rechnen haben ihre Systemdynamik nicht 
verstanden.
[/Provokation]

Cheers
Detlef

von Chris c. (chris78)


Lesenswert?

Hallo,
habe ein IIR-Filter Beispiel (in C) in der Hilfe gefunden, bin mir aber 
nicht ganz sicher was die bitverschiebung nach rechts (>>15) soll? ein 
short hat doch 32bit...
1
void iir(short x[],short y[],short c1, short c2, short c3)
2
{
3
  int i;  for (i=0; i<100; i++) {
4
       y[i+1] = (c1*x[i] + c2*x[i+1] + c3*y[i]) >> 15;
5
       }
6
}

werd meine Filter mal mit short-Werten programmieren. Versuche es auch 
mit einer 2er-Komplement-Darstellung oder gibt es vielleicht noch eine 
bessere Methode. Lohnt es sich da evt. MatLab o.ä. bei der Umrechnung 
zur Hilfe nehmen? Habe auch schon eine Möglichkeit gefunden asm-Dateien 
zu verwenden.

Das CodeComoserStudio enthält, wie ich gerade entdeckt habe, auch einige 
Codeoptimierungsoptionen,  die ich noch ausprobieren muss. Allerdings 
erkennt man danach seinen eigenen Code nicht mehr und das debuggen fällt 
schwer.
Werd mal nachmessen , was für einen Zeitgewinn ich durch diese beiden 
Punkte erreiche.

>pumpkin wrote:
> der TI kann fractional rechnen, deine Bemühungen sollten sich
> darauf konzentrieren. Auch hardwareloops und circular buffering bringen
> einiges.

Was bedeutet denn "fractional rechnen" und wie verwende ich 
Hardwareloops, worin unterscheiden sich diese zu einer Schlefe in 
Software?
Hoffe das ist keine Anfängerfrage.

>Student wrote:
> Du rechnest jedes Sample einzeln aus. Das bringt natürlich einen
> ziemlichen Overhead beim Aufruf von 'input_sample()' und
> 'output_sample()'.
> Versuch mal vielleicht 100 Samples einzulesen, zu filtern und dann
> auszugeben. Das sollte schon einiges bringen.

Ich vermute das ist das "circular buffering" was pumkin schon erwähnte?

>andreas wrote:
> Ein IIR 8. Ordnung in Festkomma könnte ein wenig ungemütlich werden.
>pumkin wrote:
>IIR 8. Ordnung würde hässlich werden, indeed! War in Gedanken bei den
>SOS'.

Könnt Ihr mir die Gründe dafür erklären? Oder wird das den Rahmen 
sprengen (zu kompliziert) ?

>pumpkin wrote:
> p.s. Was ist das eigentlich für eine Sache mit dem ";-)" im code?
1
EQ_6.4MHZ;-)

Da mein derzeitig verwndeter Codec nur mit max.96KHz arbeitet habe ich 
einfach mal 6,4MHz eingefügt, um keine Verwirrung zu stiften.

Danke
Chris

von Chris c. (chris78)


Lesenswert?

Hi Detlef,

> Read the friendly datasheet: Der kleinste 6713 fängt an bei 334 MMACs,
> für nen IIR 8. Ordnung mit 17 MACs sind das also schlappe 20e6 maximale
> Samplerate. Für ne Abtastrate von 100*64Ks/s sind das immer noch Faktor
> 3 mehr Leistung als Du brauchst. Nen 6713 für solch eine Aufgabe
> einzusetzen ist MAC-Verschwendung, das wird in der einschlägigen
> Industrie hart bestraft. Oder umgekehrt: Mit solch einem Geschoß kann
> man auch mal richtig große Filter rechnen!

Das heißt also das ich nur "besser" programmieren muss... OK.

> IIR 8. Ordnung in 4*2.Ordnung zerlegen, das ist numerisch sehr viel
> günstiger, Berechnung geht dann auch in integer.

Mit diesen Informationen werde ich mein Programm optimieren und noch mal 
messen. Mal sehen was ich gewinne.

Wenn ich mich kurz nochmal erinnere
kurzes Zitat aus dem Thread "Filter schneller berechnen, aber wie?":
> Ich würde sowas mit nem FPGA aufbauen, z.B. diesem Spartan 3 evalboard.
> Die Dinger haben, glaube ich, mehrere Multiplizierer drin und lassen
> sich mit etlichen 100MHz takten. Da kann so mancher DSP nicht
> gegenanstinken. Außerdem ist Signalverarbeitung auf FPGAs zukunftsfähig,
> man lernt mal VHDL und kann sehr flotte Sachen basteln.
Sehe ich das also richtig, dass Du nen Spatan3 verwenden würdest, der 
C6713 das aber auch schaffen muss ?!?

Wirklich nett, dass Du Dich nochmal damit beschäftigst.

MfG
Chris

von pumpkin (Gast)


Lesenswert?

> ...was die bitverschiebung nach rechts (>>15) soll

Short wird hier mit 16Bit implementiert sein, Integer haben 32Bit. Dann 
wird auch klar, dass es sich hier um eine Korrektur handelt (2^15 * 2^15 
= 2^30). Du willst aber das obere "Wort". Du wirst dich wundern, dass 
ich 2^15 geschrieben habe. 2^15 daher, weil es vorzeichenbehaftete Werte 
sind. Was mich gleich zum nächten Punkt kommen lässt:

> Was bedeutet denn "fractional rechnen"

Fractional rechnen bedeutet, dass du eine im 16Bit Bereich darstellbare 
(ganze [*1]) Zahl in den Zahlenraum von -1..0..1 [*2] "transformierst". 
Das heisst, +2^15 = +32767 ^~ +1 (genauer: 1 - 2^(-15)) und -2^15 = 
-32728 ^~ -1 (und zwar genau -1). Bedenke, dass das MSB das Vorzeichen 
ist. Der Sinn dahinter ist, dass man so prima ohne Überlaufe 
multiplizieren kann (<1 * <1 bleibt <1) und andere Sachen. Diese 
'fractionals' gibt es selbstverständlich auch vorzeichenlos und mit mehr 
Bits - je nachdem muss man der ALU sagen wie er das Bitmuster 
interpretieren soll. Näheres in der einschlägigen Progamming Reference 
zum DSP.

[*1] "Ganze Zahl" dient einer bequemeren Interpretation.
[*2] "..1" ist nicht ganz richtig. Da man die 0 auch darstellen muss, 
hat man im positiven Bereich ein Bit zu wenig um auf die 1 zu kommen.


> Hardwareloops

Das sind, wie der Name schon sagt, Schleifen, die nicht durch logische 
Abfragen im Programm beendet/wiederholt werden, sondern per direkten 
Registervergleich in der Hardware abgehandelt werden. In einfachen 
Worten: Ein Codesegment im Speicher wird solange wiederholt, bis der 
Wert im loop-counter-Register erreicht ist. Dazu muss man Anfangs- und 
Endadresse der Schleife bekannt geben.

> circular buffering

Ähnlich wie Hardwareloops. Man gibt der address-arithmetic-unit 
Anfangsadresse (Basis) und Länge eines Speicherbereiches bekannt. Zu 
diesem Angaben gehört ein Indexregister (aktueller Pointer in diesen 
Bereich). Nun kann man diesen Pointer incrementieren (o. 
decrementieren). Hardwaremäßig wird wieder geprüft, ob der angegebene 
Bereich verlassen wird, wenn ja gibts einen Reset des Zeigers auf die 
Basis.

Da diese beiden Sachen hardwaremäßig geschehen und parallel laufen 
(können) sind sie extrem schnell und effizient.

> IIR 8. Ordnung

...in Festkomma ist eine unmögliche Sache da das Rundungsrauschen alles 
untergehen lässt - mal einfach ausgedrückt. Umgehen kann man das indem 
man sein System x-ter Ordnung in verkettete SOS (second order sections, 
Systeme 2. Ordnung) aufteilt. Entweder man macht es händisch oder man 
bemüht MATLAB (die Funktionen roots() und zp2sos() helfen hier u.a. 
weiter) - aufpassen muss man allerdings auf die Maximalverstärkungen der 
Einzelstufen. Experimente die ich mal angestellt habe haben mir gezeigt, 
dass bei 3. Ordnung schon nichts brauchbares mehr kommt (16 Bit).


Hoffentlich hab ich nicht zuviel geschwafelt...  ;^)

pumpkin

von Detlef _. (detlef_a)


Lesenswert?

>> Industrie hart bestraft. Oder umgekehrt: Mit solch einem Geschoß kann
>> man auch mal richtig große Filter rechnen!
>
>Das heißt also das ich nur "besser" programmieren muss... OK.

Die ti DSPs, die ich kenne (der 6713 gehört nicht dazu) haben mehrere 
Multiplizierer, lange pipelines und führen mehrere Befehle gleichzeitig 
aus. Für C gibt es da einige Regeln, pragmas und keywords ('restrict'), 
die dem Compiler helfen, gut zu optimieren ('Programmers guide' oder 
so). In Assembler selbst zu schreiben ist extrem schwierig. Verfahren 
der Wahl ist es eigentlich immer, die APIs von ti zu nehmen, die kennen 
ihren Prozessor am besten. Die gibts für die Standards z.B. 2.Ordnung 
IIR sicher auch für den 6713, vielleicht hier: 
http://focus.ti.com/docs/toolsw/folders/print/sprc121.html

>> günstiger, Berechnung geht dann auch in integer.
>Mit diesen Informationen werde ich mein Programm optimieren und noch mal
>messen. Mal sehen was ich gewinne.

Mit dem 6713 bist Du von der verfügbaren Leistung auf der sicheren 
Seite. Da brauchst Du nicht auf integer downgraden, möchte mich also 
bißchen von meiner eigenen Aussage distanzieren. Die Aufteilung des 8er 
IIR in die 2er IIR ist auch recht fummelig und verlangt Sorgfalt, 
Genauigkeit und Zeit, sonst passiern da die dollsten Sachen.

>Sehe ich das also richtig, dass Du nen Spatan3 verwenden würdest, der
>C6713 das aber auch schaffen muss ?!?

Der 6713 muß das locker schaffen, der ist ja um Faktoren stärker als 
nötig. Den Spartan würde ich verwenden, um was Zukunftsträchtiges zu 
lernen. Für ne Diplomarbeit würde ich den 6713 nehmen, der ist ja wohl 
auch schon bewilligt. Da heißt es Schumi werden, der DSP ist extrem 
schnell aber nicht trivial zu fahren.

Gute Nacht
Detlef

von Chris c. (chris78)


Lesenswert?

Hallo,

hab folgendes im Datasheet gefunden:

Operating at 225 MHz, the C6713 delivers up to 1350 million 
floating-point operations per second (MFLOPS),
1800 million instructions per second (MIPS), and with dual 
fixed-/floating-point multipliers up to 450 million
multiply-accumulate operations per second (MMACS).

Da mein Filter mit max. 10.Ordnung (21MACs) bei 6,4 MHz gerade mal 134,4 
MMACs benötigt ist der TMS320C6713 mit 450MMACs nicht ausgelastet.

Also wie bereits vermutet, sauberer programmieren...

MfG

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.