Hay tres maneras de hacerlo (enumeradas a continuación para completar) y se trata de compensaciones espacio-temporales:
¿Se hacen los cálculos con antelación (espacio de almacenamiento) o se hacen los cálculos sobre la marcha (compensación de tiempo)?
1) Tabla de búsqueda. Haz los cálculos con antelación y almacena la información en una ROM/tabla. Al darse cuenta de que sólo tiene que almacenar 1/4 de la forma de onda puede disminuir la cantidad que necesita para almacenar. Sin embargo... dependiendo de la precisión y el número de pasos puede llevar a una tabla muy grande
2) LUT interpolada. Un compromiso entre una tabla de búsqueda y los cálculos completos. El avance del cambio entre entradas puede estar bien dentro de los errores aceptados. A veces sólo se requieren 3 puntos (NOTA: el ejemplo de 3 puntos es sólo para atan)
3) CORDIC. (COordinate Rotation DIgital Computer). Básicamente es un algoritmo de caza que puede reducirse a simples sumas y desplazamientos. La precisión se rige más o menos por el número de pasos computacionales
4) Ampliación completa de taylor. Si la precisión es primordial, la velocidad es importante pero el almacenamiento local no es una opción
Mi consejo. Busca un CORDIC. Hay un montón de ejemplos de cordics en VHDL y una FPGA es perfecta para un CORDIC. Un proyecto en el que estoy trabajando en este momento utiliza en gran medida cordic's (12bit, 14 ciclos para establecerse)
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 FPGAs http://www.uio.no/studier/emner/matnat/ifi/INF5430/v12/undervisningsmateriale/dirk/Lecture_cordic.pdf