Potrzebuję przetwarzania atan2(x,y)
na FPGA z ciągłym strumieniem danych wejściowych / wyjściowych. Udało mi się to zaimplementować za pomocą rozwijanego, potokowego jądra CORDIC, ale aby uzyskać wymaganą dokładność, musiałem wykonać 32 iteracje. Doprowadziło to do poświęcenia dość dużej liczby LUT temu jednemu zadaniu. Próbowałem zmienić przepływ, aby używać częściowo rozwiniętych jąder CORDIC, ale potem potrzebowałem zwielokrotnionej częstotliwości taktowania, aby wykonywać powtarzane pętle, zachowując ciągły przepływ wejścia / wyjścia. Dzięki temu nie mogłem dotrzymać terminu.
Teraz sięgam po alternatywne sposoby obliczeń atan2(x,y)
.
Pomyślałem o użyciu tabel przeglądowych bloków RAM z interpolacją, ale ponieważ istnieją 2 zmienne, potrzebowałbym 2 wymiarów tabel przeglądowych, a to jest bardzo zasobochłonne pod względem wykorzystania blokowych pamięci RAM.
Potem pomyślałem o użyciu faktu atan2(x,y)
związanego atan(x/y)
z dostosowaniem kwadrantu. Problem polega na tym, że x/y
wymaga prawdziwego podziału, ponieważ y
nie jest stały, a podziały na układy FPGA są bardzo wymagające pod względem zasobów.
Czy są jakieś nowatorskie sposoby implementacji atan2(x,y)
na FPGA, które skutkowałyby mniejszym wykorzystaniem LUT, ale nadal zapewniałyby dobrą dokładność?
źródło
atan2
. Nie jestem jednak pewien, czy dasz sobie radę bez podziału.atan2
. Nadal jednak będziesz potrzebować podziału.Odpowiedzi:
Możesz użyć logarytmów, aby pozbyć się podziału. Dla( x , y) w pierwszej ćwiartce:
Rycina 1. Wykresatan ( 2z)
Aby uzyskać wymaganą dokładność 1E-9, musisz zbliżyćatan ( 2z) w zakresie - 30 < z< 30 . Możesz skorzystać z symetrii atan ( 2- z) = π2)- atan ( 2z) lub alternatywnie upewnij się, że( x , y) jest w znanej liczbie oktanowej. Aby przybliżyćlog2)( ) :
Ryc. 2. Wykreslog2)( c )
Dla twoich wymagań dokładności wystarczy interpolacja liniowa i jednorodne próbkowanie,2)14+ 1 = 16385 próbek log2)( c ) i 30 × 212+ 1 = 122881 próbek atan ( 2z) dla 0 < z< 30 . Ten drugi stół jest dość duży. Dzięki niemu błąd spowodowany interpolacją zależy w dużej mierze od z :
Ryc. 3. największy błąd bezwzględny aproksymacjiatan(2z) dla różnych zakresów z (oś pozioma) dla różnych liczb próbek (od 32 do 8192) na przedział jednostkowy z . Największy błąd bezwzględny dla 0≤z<1 (pominięty) jest nieco mniejszy niż dla floor(log2(z))=0 .
Do późniejszego wykorzystania oto niezgrabny skrypt Pythona, którego użyłem do obliczenia błędów aproksymacji:
Lokalna maksymalna błędu z zbliżony funkcjęf(x) przez interpolację liniową f ( x ) z próbek f ( x ) , wykonane z jednolitego próbek z próbek przedział Δ x może być w przybliżeniu analitycznie:f^(x) f(x) Δx
Ponieważ funkcje są wklęsłe, a próbki pasują do funkcji, błąd jest zawsze w jednym kierunku. Lokalny maksymalny błąd bezwzględny można by zmniejszyć o połowę, gdyby znak błędu pojawiał się naprzemiennie tam iz powrotem raz na każdy interwał próbkowania. Dzięki interpolacji liniowej można uzyskać prawie optymalne wyniki, wstępnie filtrując każdą tabelę poprzez:
W tym artykule prawdopodobnie przedstawiono bardzo podobny algorytm: R. Gutierrez, V. Torres i J. Valls, „ Implementacja FPGA atan (Y / X) w oparciu o transformację logarytmiczną i techniki oparte na LUT ”, Journal of Systems Architecture , tom . 56, 2010. Streszczenie mówi, że ich implementacja przewyższa poprzednie algorytmy oparte na CORDIC pod względem prędkości, a algorytmy oparte na LUT pod względem wielkości powierzchni.
źródło