Preciso de computação atan2(x,y)
em um FPGA com um fluxo contínuo de dados de entrada / saída. Consegui implementá-lo usando kernels CORDIC desenrolados e em pipeline, mas, para obter a precisão necessária, tive que executar 32 iterações. Isso levou a uma quantidade bastante grande de LUTs dedicadas a essa tarefa. Tentei alterar o fluxo para usar kernels CORDIC parcialmente desenrolados, mas então precisei de uma freqüência de relógio multiplicada para executar loops repetidos, mantendo um fluxo contínuo de entrada / saída. Com isso, eu não consegui encontrar o tempo.
Então agora estou buscando formas alternativas de computação atan2(x,y)
.
Pensei em usar tabelas de pesquisa de RAM de bloco com interpolação, mas como existem 2 variáveis, eu precisaria de 2 dimensões de tabelas de pesquisa, e isso consome muitos recursos em termos de uso de RAM de bloco.
Pensei então em usar o fato atan2(x,y)
relacionado ao atan(x/y)
ajuste de quadrante. O problema disso é que ele x/y
precisa de uma verdadeira divisão, já que y
não é uma constante, e as divisões nos FPGAs consomem muitos recursos.
Existem novas maneiras de implementar atan2(x,y)
em um FPGA que resultariam em menor uso de LUT, mas ainda assim fornecessem boa precisão?
fonte
atan2
. Não tenho certeza se você pode sobreviver sem uma divisão, no entanto.atan2
. Você ainda precisará de uma divisão.Respostas:
Você pode usar logaritmos para se livrar da divisão. Para(x,y) no primeiro quadrante:
Figura 1. Gráfico deatan(2z)
Você precisaria aproximaratan(2z) no intervalo −30<z<30 para obter a precisão necessária de 1E-9. Você pode tirar proveito da simetria atan(2−z)=π2−atan(2z) ou, alternativamente, garantir que(x,y) esteja em um octante conhecido. Para aproximar olog2(a) :
Figura 2. Gráfico dolog2(c)
Para seus requisitos de precisão, interpolação linear e amostragem uniforme,214+1=16385 amostras do log2(c) e 30×212+1=122881 amostras de atan(2z) para 0<z<30 devem ser suficientes. A última tabela é bem grande. Com isso, o erro devido à interpolação depende muito de z :
Figura 3.atan(2z) aproxima o maior erro absoluto para diferentes faixas de z (eixo horizontal) para diferentes números de amostras (32 a 8192) por unidade de intervalo de z . O maior erro absoluto para 0≤z<1 (omitido) é ligeiramente menor que para o floor(log2(z))=0 .
A tabelaatan(2z) pode ser dividida em várias subtabelas que correspondem a 0≤z<1 e piso diferente ( log 2 ( z ) )floor(log2(z)) com z≥1 , o que é fácil de calcular. Os comprimentos da tabela podem ser escolhidos como guiado pela Fig. 3. O índice dentro da subtabela pode ser calculado por uma simples manipulação de cadeia de bits. Para seus requisitos de precisão, as subtabelas atan(2z) terão um total de 29217 amostras se você estender o intervalo de z para 0≤z<32 por simplicidade.
Para referência posterior, aqui está o script Python desajeitado que eu usei para calcular os erros de aproximação:
O erro máximo local de aproximação de uma funçãof(x) por interpolação linear f ( x ) a partir de amostras de f ( x ) , feita por amostragem uniforme com intervalo de amostragem Δ x , pode ser aproximada analiticamente por:f^(x) f(x) Δx
ondef′′(x) é a segunda derivada de f(x) e x está no máximo local do erro absoluto. Com o exposto, obtemos as aproximações:
Como as funções são côncavas e as amostras correspondem à função, o erro ocorre sempre em uma direção. O erro absoluto máximo local pode ser reduzido pela metade se o sinal do erro for alternado para frente e para trás uma vez a cada intervalo de amostragem. Com interpolação linear, é possível obter resultados próximos ao ideal pré-filtrando cada tabela com:
wherex and y are the original and the filtered table both spanning 0≤k≤N and the weights are c0=98,c1=−116,b0=1516,b1=18,b2=−116 . The end conditioning (first and last row in the above equation) reduces error at the ends of the table compared to using samples of the function outside of the table, because the first and the last sample need not be adjusted to reduce the error from interpolation between it and a sample just outside the table. Subtables with different sampling intervals should be prefiltered separately. The values of the weights c0,c1 were found by minimizing sequentially for increasing exponent N the maximum absolute value of the approximate error:
for inter-sample interpolation positions0≤a<1 , with a concave or convex function f(x) (for example f(x)=ex ). With those weights solved, the values of the end conditioning weights b0,b1,b2 were found by minimizing similarly the maximum absolute value of:
for0≤a<1 . Use of the prefilter about halves the approximation error and is easier to do than full optimization of the tables.
Figure 4. Approximation error oflog2(a) from 11 samples, with and without prefilter and with and without end conditioning. Without end conditioning the prefilter has access to values of the function just outside of the table.
This article probably presents a very similar algorithm: R. Gutierrez, V. Torres, and J. Valls, “FPGA-implementation of atan(Y/X) based on logarithmic transformation and LUT-based techniques,” Journal of Systems Architecture, vol. 56, 2010. The abstract says their implementation beats previous CORDIC-based algorithms in speed and LUT-based algorithms in footprint size.
fonte