Changes between Version 4 and Version 5 of MOCCA-TP3-2020


Ignore:
Timestamp:
Oct 22, 2020, 5:52:14 PM (4 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MOCCA-TP3-2020

    v4 v5  
    11= Synthèse logique de CORDIC
    22
    3 La lecture du [htdocs:MOCCA_Cordic_2020.pdf  cours] est nécessaire pour comprendre les principe de l'algorithme CORDIC utilisé pour la rotation.
     3La lecture du [htdocs:MOCCA_Cordic_2020.pdf  cours] est nécessaire pour comprendre les principes de l'algorithme CORDIC utilisé pour la rotation.
    44
    55Dans ce TME, vous devez écrire le modèle VHDL du circuit CORDIC à partir d'une description de l'algorithme en décrit en C.
    66- Le circuit réalise la rotation d'un vecteur (x,y) par un un angle a.
    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.
    917
     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
     33void 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
     39short F_PI = (short)((M_PI) * (1<< 7));
     40short 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
     51void 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
     110int 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