Hay tres formas de hacer esto (enlistadas para completar) y se trata de compensaciones de espacio-tiempo:
¿Realiza los cálculos antes de tiempo (espacio de almacenamiento) o realiza los cálculos sobre la marcha (compensación de tiempo)
1) Buscar tabla. Haga los cálculos antes de tiempo y amp; almacenar la información en una ROM / tabla. Al darse cuenta de que solo tiene que almacenar 1/4 de la forma de onda, puede disminuir la cantidad que necesita almacenar. Sin embargo ... dependiendo de la precisión y amp; el número de pasos puede llevar a una tabla muy grande
2) LUT interpolada. Un intercambio entre una tabla de búsqueda y cálculos completos. Anticipar el cambio entre las entradas podría estar dentro de los errores aceptados. A veces solo se requieren 3 puntos (NOTA: el ejemplo de 3 puntos es solo para atan)
3) CORDIC. (Ordenador digital de rotación coordinada). Básicamente, un algoritmo de búsqueda que se puede reducir a simples agregados y desplazamientos. La precisión está bastante controlada por el número de pasos computacionales
4) Expansión taylor completa. Si la precisión es primordial, la velocidad es importante pero el almacenamiento local no es una opción
Mi consejo. Mira en un córdico. Hay muchos ejemplos de cuerdas en VHDL y un FPGA es perfecto para un CORDIC. Un proyecto en el que estoy trabajando en este momento utiliza mucho los cordic's (12 bits, 14 ciclos para liquidar)
Ejemplo cordic en python
#http://code.activestate.com/recipes/576792-polar-to-rectangular-conversions-using-cordic/
def to_polar(x, y):
'Rectangular to polar conversion using ints scaled by 100000. Angle in degrees.'
theta = 0
for i, adj in enumerate((4500000, 2656505, 1403624, 712502, 357633, 178991, 89517, 44761)):
sign = 1 if y < 0 else -1
x, y, theta = x - sign*(y >> i) , y + sign*(x >> i), theta - sign*adj
return theta, x * 60726 // 100000
def to_rect(r, theta):
'Polar to rectangular conversion using ints scaled by 100000. Angle in degrees.'
x, y = 60726 * r // 100000, 0
for i, adj in enumerate((4500000, 2656505, 1403624, 712502, 357633, 178991, 89517, 44761)):
sign = 1 if theta > 0 else -1
x, y, theta = x - sign*(y >> i) , y + sign*(x >> i), theta - sign*adj
return x, y
#if __name__ == '__main__':
# print(to_rect(471700, 5799460)) # r=4.71700 theta=57.99460
# print(to_polar(250000, 400000)) # x=2.50000 y=4.00000
Notas sobre CORDICS y FPGA's
enlace