Próbuję zacząć korzystać z DSP na mojej płycie Spartan-3. Zrobiłem płytę AC97 z układem ze starej płyty głównej i do tej pory udało mi się zrobić ADC, pomnożyć próbki dla liczby <1 (zmniejszyć głośność), a następnie DAC.
Teraz chciałbym zrobić kilka podstawowych rzeczy DSP, takich jak filtr dolnoprzepustowy, górnoprzepustowy itp. Ale jestem naprawdę zdezorientowany co do reprezentacji numerycznej (liczby całkowite? Punkt stały? Q0.15? Przepełnienie lub nasycenie?).
Chcę tylko przykładowy kod rzeczywistego prostego filtra, aby zacząć. Brak wysokiej wydajności, szybkości lub czegoś podobnego. Tylko filtr teoretyczny zaimplementowany w VHDL.
Szukałem, ale właśnie znalazłem wzory teoretyczne - rozumiem, ale nie rozumiem, jak przetwarzać podpisane 16-bitowe próbki audio 48 KHz, które otrzymuję z ADC. Korzystałem z tych bibliotek: http://www.vhdl.org/fphdl/ . Jeśli pomnożę próbki przez 0,5, 0,25 itd., Słyszę różnicę. Ale większy filtr daje mi tylko szum.
Dzięki.
Odpowiedzi:
Wygląda na to, że musisz najpierw zrozumieć aspekty DSP, a następnie wprowadzić implementację w FPGA.
Jeśli chodzi o typy danych, możesz dobrze używać liczb całkowitych.
oto przykładowy kod na początek. Pamiętaj, że brakuje wielu problemów w świecie rzeczywistym (na przykład resetowania, zarządzania przepełnieniem) - ale mam nadzieję, że jest pouczający:
źródło
Najprostszy filtr dolnoprzepustowy FIR, jaki możesz wypróbować, to y (n) = x (n) + x (n-1). Możesz to dość łatwo zaimplementować w VHDL. Poniżej znajduje się bardzo prosty schemat blokowy sprzętu, który chcesz wdrożyć.
Zgodnie ze wzorem potrzebne są bieżące i poprzednie próbki ADC, aby uzyskać odpowiednią moc wyjściową. Co należy zrobić, to zatrzasnąć przychodzące próbki ADC na zboczu opadającym zegara i wykonać odpowiednie obliczenia na zboczu narastającym, aby uzyskać odpowiednią moc wyjściową. Ponieważ dodajesz dwie wartości 16-bitowe razem, możliwe, że otrzymasz 17-bitową odpowiedź. Powinieneś zapisać dane wejściowe w 17-bitowych rejestrach i użyć 17-bitowego sumatora. Twój wynik będzie jednak niższymi 16 bitami odpowiedzi. Kod może wyglądać mniej więcej tak, ale nie mogę zagwarantować, że będzie działał całkowicie, ponieważ go nie testowałem, nie mówiąc już o jego syntezie.
Jak widać, można użyć tego ogólnego pomysłu, aby dodać bardziej skomplikowane formuły, na przykład o współczynnikach. Bardziej skomplikowane formuły, takie jak filtry IIR, mogą wymagać użycia zmiennych, aby uzyskać poprawną logikę algorytmu. Wreszcie, łatwym sposobem na obejście filtrów, które mają liczby rzeczywiste jako współczynniki, jest znalezienie współczynnika skali, aby wszystkie liczby były jak najbardziej zbliżone do liczb całkowitych. Ostateczny wynik będzie musiał zostać zmniejszony o ten sam współczynnik, aby uzyskać poprawny wynik.
Mam nadzieję, że to może ci się przydać i pomóc w toczyć piłkę.
* Zostało to zmodyfikowane, aby blokowanie danych i blokowanie danych wyjściowych odbywało się w osobnych procesach. Również używając podpisanych typów zamiast std_logic_vector. Zakładam, że twoje wejście ADC będzie sygnałem std_logic_vector.
źródło
Kolejny prosty fragment kodu (tylko wnętrzności). Uwaga: Nie napisałem VHDL bezpośrednio, użyłem MyHDL do wygenerowania VHDL.
Jest to bezpośrednie wdrożenie. Będzie to wymagało mnożników. Synteza tego obwodu, ukierunkowana na Altera Cyclone III, nie wykorzystywała żadnych wyraźnych mnożników, ale wymagała 350 elementów logicznych.
To jest mały filtr FIR i będzie miał następującą odpowiedź (niezbyt dobrą), ale powinien być przydatny jako przykład.
Ponadto mam kilka przykładów tu i tutaj , które mogą być przydatne.
Wydaje się również, że pytanie brzmi: „jaka jest odpowiednia reprezentacja punktu stałego?” Często podczas implementacji funkcji DSP używana jest reprezentacja punktu stałego, ponieważ upraszcza to analizę filtrów. Jak wspomniano, punkt stały jest po prostu całkowitym artymetykiem. Rzeczywista implementacja po prostu działa z liczbami całkowitymi, ale nasza wcześniejsza reprezentacja jest ułamkowa.
Problemy zwykle pojawiają się podczas konwersji z liczby całkowitej implementacji (punkt stały) na zmiennoprzecinkowy projekt / z powrotem.
Nie wiem, jak dobrze obsługiwane są typy stałoprzecinkowe i zmiennoprzecinkowe VHDL. Będą działać dobrze w symulacji, ale nie wiem, czy będą syntetyzować za pomocą większości narzędzi do syntezy. Stworzyłem do tego osobne pytanie .
źródło
OpenCores ma wiele przykładów DSP, IIR i FIR, w tym BiQuad. Musisz się zarejestrować, aby pobrać pliki.
edytuj
Rozumiem komentarz Kortuka na temat martwych linków i jeśli umrze link do OpenCores, odpowiedź stanie się bezużyteczna. Jestem przekonany, że tak się nie stanie; mój link jest ogólny i umrze tylko wtedy, gdy zniknie cała domena OpenCores.
Próbowałem poszukać przykładów, których mógłbym użyć dla tej odpowiedzi, ale są one zbyt długie, aby je tu przedstawić. Będę się więc trzymał mojej rady, aby zarejestrować się na stronie (musiałem przeprowadzić się do Nowego Jorku, ponieważ moje rodzinne miasto nie zostało zaakceptowane) i rzucić okiem na kod tam przedstawiony.
źródło
Próbowałem zaimplementować skrypty do automatycznej implementacji filtrów IIR, w których można określić, czy projekt powinien być tak szybki, jak to możliwe (aby każde zwielokrotnienie odbywało się za pomocą dedykowanego mnożnika), czy jak najmniejsze (aby każdy mnożnik był ponownie wykorzystywany).
Źródła zostały opublikowane na alt.sources jako „Behawioralna, ale możliwa do syntezy implementacja filtrów IIR w VHDL” (można go również znaleźć w archiwum Google: https://groups.google.com/group/alt.sources/msg/c8cf038b9b8ceeec ? dmode = źródło )
Wpisy do alt.sources są w formacie „shar”, więc musisz zapisać wiadomość jako tekst i oddzielić ją (za pomocą narzędzia „unshar”), aby uzyskać źródła.
źródło
Co powiesz na to? https://github.com/MauererM/VIIRF
Implementuje filtr IIR oparty na biquad (SOS, sekcje drugiego rzędu), który zajmuje się implementacją punktu stałego. Zawiera również skrypty Pythona do projektowania i weryfikacji filtra. Nie wykorzystuje konstruktorów FPGA specyficznych dla Dostawców i możesz wybrać kompromis między szybkim i niskim obszarem użytkowania.
źródło