| 7 |  | - Les coordonnées x et y sont des nombres entiers signés de -127 à +127. | 
                        | 8 |  | - L'angle est | 
                      
                        |  | 7 | - Le circuit prend en entrée | 
                        |  | 8 | - les coordonnées x_p et y_p qui sont des nombres entiers signés de -127 à +127. | 
                        |  | 9 | - L'angle a_p est exprimé en radian et il est représenté par un nombre en virgule fixe **non** signé 3-7. | 
                        |  | 10 | - À l'intérieur du circuit, c'est un nombre en virgule fixe 1-8-7. | 
                        |  | 11 | - Mais à l'interface, j'ai choisi une représentation non signée 3-7 (port a_p) pour avoir des angles entre 0 et presque 8 radians. | 
                        |  | 12 | La conversion se fait dans le circuit en recopiant les 10 bits de a_p dans les 10 bits de poids faible d'un registre de 16 bits représentant l'angle, puis en complétant avec des `0`à gauche. | 
                        |  | 13 | C'est un choix pour réduire le nombre de broches, mais vous pouvez faire un choix plus "propre" en codant l'angle en 1-3-7 et faire une conversion avec extension du signe. | 
                        |  | 14 | - le circuit reçoit aussi une horloge. | 
                        |  | 15 | - Le circuit produit en sortie les coordonnées (nx_p, ny_p) du vecteur après rotation. | 
                        |  | 16 | - Le protocole de communication en entrée et en sortie est FIFO. | 
            
                  
                          |  | 18 | {{{ | 
                          |  | 19 | #!c | 
                          |  | 20 | //----------------------------------------------------------------------------- | 
                          |  | 21 | // Calcul des points d'un cercle par l'algorithme Cordic | 
                          |  | 22 | //----------------------------------------------------------------------------- | 
                          |  | 23 | // cossin :  utilisation des fonctions cos et sin de la bibliothèque maths | 
                          |  | 24 | // cordic :  cordic en virgule fixe 8 chiffres après la virgules | 
                          |  | 25 | //----------------------------------------------------------------------------- | 
                          |  | 26 | #include <stdio.h> | 
                          |  | 27 | #include <math.h> | 
                          |  | 28 |  | 
                          |  | 29 | #ifndef M_PI | 
                          |  | 30 | #define M_PI 3.14159265358979323846 | 
                          |  | 31 | #endif | 
                          |  | 32 |  | 
                          |  | 33 | void cossin(double a_p, char x_p, char y_p, char *nx_p, char *ny_p) | 
                          |  | 34 | { | 
                          |  | 35 | *nx_p = (char) (x_p * cos(a_p) - y_p * sin(a_p)); | 
                          |  | 36 | *ny_p = (char) (x_p * sin(a_p) + y_p * cos(a_p)); | 
                          |  | 37 | } | 
                          |  | 38 |  | 
                          |  | 39 | short F_PI = (short)((M_PI) * (1<< 7)); | 
                          |  | 40 | short ATAN[8] = { | 
                          |  | 41 | 0x65,                 // ATAN(2^-0) | 
                          |  | 42 | 0x3B,                 // ATAN(2^-1) | 
                          |  | 43 | 0x1F,                 // ATAN(2^-2) | 
                          |  | 44 | 0x10,                 // ATAN(2^-3) | 
                          |  | 45 | 0x08,                 // ATAN(2^-4) | 
                          |  | 46 | 0x04,                 // ATAN(2^-5) | 
                          |  | 47 | 0x02,                 // ATAN(2^-6) | 
                          |  | 48 | 0x01,                 // ATAN(2^-7) | 
                          |  | 49 | }; | 
                          |  | 50 |  | 
                          |  | 51 | void cordic(short a_p, char x_p, char y_p, char *nx_p, char *ny_p) | 
                          |  | 52 | { | 
                          |  | 53 | unsigned char i, q; | 
                          |  | 54 | short a, x, y, dx, dy; | 
                          |  | 55 |  | 
                          |  | 56 | // conversion en virgule fixe : 7 chiffres après la virgule | 
                          |  | 57 | a = a_p; | 
                          |  | 58 | x = x_p << 7; | 
                          |  | 59 | y = y_p << 7; | 
                          |  | 60 |  | 
                          |  | 61 | // normalisalion de l'angle pour être dans le premier quadrant | 
                          |  | 62 | q = 0; | 
                          |  | 63 | while (a >= F_PI/2) { | 
                          |  | 64 | a = a - F_PI/2; | 
                          |  | 65 | q = (q + 1) & 3; | 
                          |  | 66 | } | 
                          |  | 67 |  | 
                          |  | 68 | // rotation | 
                          |  | 69 | for (i = 0; i <= 7; i++) { | 
                          |  | 70 | dx = x >> i; | 
                          |  | 71 | dy = y >> i; | 
                          |  | 72 | if (a >= 0) { | 
                          |  | 73 | x -= dy; | 
                          |  | 74 | y += dx; | 
                          |  | 75 | a -= ATAN[i]; | 
                          |  | 76 | } else { | 
                          |  | 77 | x += dy; | 
                          |  | 78 | y -= dx; | 
                          |  | 79 | a += ATAN[i]; | 
                          |  | 80 | } | 
                          |  | 81 | } | 
                          |  | 82 |  | 
                          |  | 83 | // produit du résultat par les cosinus des angles : K=0x4E=1001110 | 
                          |  | 84 | x = ((x>>6) + (x>>5) + (x>>4) + (x>>1))>>7; | 
                          |  | 85 | y = ((y>>6) + (y>>5) + (y>>4) + (y>>1))>>7; | 
                          |  | 86 |  | 
                          |  | 87 | // placement du points dans le quadrant d'origine | 
                          |  | 88 | switch (q) { | 
                          |  | 89 | case 0: | 
                          |  | 90 | dx = x; | 
                          |  | 91 | dy = y; | 
                          |  | 92 | break; | 
                          |  | 93 | case 1: | 
                          |  | 94 | dx = -y; | 
                          |  | 95 | dy = x; | 
                          |  | 96 | break; | 
                          |  | 97 | case 2: | 
                          |  | 98 | dx = -x; | 
                          |  | 99 | dy = -y; | 
                          |  | 100 | break; | 
                          |  | 101 | case 3: | 
                          |  | 102 | dx = y; | 
                          |  | 103 | dy = -x; | 
                          |  | 104 | break; | 
                          |  | 105 | } | 
                          |  | 106 | *nx_p = dx; | 
                          |  | 107 | *ny_p = dy; | 
                          |  | 108 | } | 
                          |  | 109 |  | 
                          |  | 110 | int main() | 
                          |  | 111 | { | 
                          |  | 112 | FILE *f; | 
                          |  | 113 | double t,K; | 
                          |  | 114 | int i; | 
                          |  | 115 | printf("PI/2 = %x %x\n", F_PI/2i, 128<<7); | 
                          |  | 116 | for (i=0, t=1, K=1; i < 8; i++, t=t/2) { | 
                          |  | 117 | printf("B_%d = 0x%x\n", i, (short)(round(atan(t)*(1<< 7)))); | 
                          |  | 118 | K = K * cos (atan(t)); | 
                          |  | 119 | } | 
                          |  | 120 | printf("K = %g, 0x%x\n", K, (short)(round(K*(1<< 7)))); | 
                          |  | 121 |  | 
                          |  | 122 | f = fopen("cossin.dat", "w"); | 
                          |  | 123 | for (double a = 0; a <= M_PI * 2; a += 1. / 256) { | 
                          |  | 124 | char nx_p; | 
                          |  | 125 | char ny_p; | 
                          |  | 126 | cossin(a, 127, 0, &nx_p, &ny_p); | 
                          |  | 127 | fprintf(f, "%4d %4d\n", nx_p, ny_p); | 
                          |  | 128 | } | 
                          |  | 129 | fclose(f); | 
                          |  | 130 |  | 
                          |  | 131 | f = fopen("cordic.dat", "w"); | 
                          |  | 132 | for (short a = 0; a <= 2 * F_PI ; a += 1) { | 
                          |  | 133 | char nx_p; | 
                          |  | 134 | char ny_p; | 
                          |  | 135 | cordic(a, 127, 0, &nx_p, &ny_p); | 
                          |  | 136 | fprintf(f, "%4d %4d\n", nx_p, ny_p); | 
                          |  | 137 | } | 
                          |  | 138 | fclose(f); | 
                          |  | 139 |  | 
                          |  | 140 | return 0; | 
                          |  | 141 | } | 
                          |  | 142 | }}} | 
                          |  | 143 |  | 
                          |  | 144 |  | 
                          |  | 145 |  | 
                          |  | 146 |  |