--- title: TD - DSP author: Rémi Maubanc tags: ESIEE, I4 --- TD - Arch. Num. du Trait. Sign. === # TD1 & 2 ## Partie A ### Question 1 **Enoncé**: Donner au sens arithmétique le plus grand nombre positif représentable et le plus négatif représentable sur un nombre en virgule fixe signé ($N=8$ bits) au format Q5. Nombre le plus grand : $011,11111_{2}$ => $3,968758_{10}$ Nombre le plus négatif : $100,00000_{2}$ => $-4_{10}$ ### Question 2 **Enoncé**: Donnez la représentation en complément à 2 format $Q_{5}$ ($N=8$ bits) des nombres suivants : - $x=3,5$ => $011,10000_{2}$ => $70_{16}$ - $x=\sqrt3$ => $001,10111_{2}$ => $37_{16}$ - $x=-1,46875$ => $001,01111_{2}$ Complément à 1 => $110,10000_{2}$ Addition de 1 => $110,10001_{2}$ => $D1_{16}$ :::info Si c'est un nombre positif, il n'y a pas de complément à 2 à réaliser. Pour convertir un nombre négatif, on converti en binaire la **valeur positive**, puis on lui applique un complément à 2 et on lui ajoute 1. ::: ### Question 3 **Enoncé**: Donnez la représentation en complément à 2 en virgule fixe $16Q12$ ($N=16$ bits) signé des nombres suivants : *1 bit de signe + 3 bits entier + 12 bits flottant* - $x=7,65625$ => $0111,101010000000_{2}$ => $7A80_{16}$ - $x=8,5$: Impossible de convertir le nombre dans le format demandé :::success On remarque que $7,65625_{10} * 2^{12} = 31360$ et que $31360_{10} = 7A80_{16}$. Ce qui offre une méthode plus efficace de calcul. ::: ## Partie B ### Question 1 **Enoncé**: Donnez le plus grand nombre représentable en format virgule flottante IEEE 754 avec une mantisse normalisée. Donnez uniquement l'expression littérale. Maximum = $(-1)^{0}*2^{(254-127)}*(1+1-2^{-23}) \simeq 2^{128} \simeq 3,4.10^{38}$ ### Question 2 **Enoncé**: Donnez le plus petit nombre proche de 0 Minimum = $(-1)^{0}*2^{1-127}*(1,0) = 2^{-126} \simeq 1,18.10^{-38}$ Dynamique = $20.log(\frac{|Max|}{|Min|}) \simeq 152$ dB ### Question 3 **Enoncé**: Soit les représentation numériques suivantes de nombres flottants IEEE 754, donnez la valeur décimale correspondante - $X=03~E0~00~00_{16}$ Binaire => $0~0000 0111~1100 0000 0000 0000 0000 000_{2}$ Décimale => $(-1)^{0} * 2^{7-127} * (1,75) \simeq 1,317.10^{-36}$ ![](https://i.imgur.com/3JDswiE.png) - $X=C0~B0~00~00_{16}$ Binaire => $1~100 0000 1~011 0000 0000 0000 0000 0000_{2}$ Décimale => $(-1)^{1} * 2^{129-127}*1,375 = -5,5$ ## Partie C ### Question 1 **Enoncé**: Donnez l'équation de différence générale du filtre $Y_{n} = b_{0}.X_{n} + b_{1}.X_{n-1} - a_{1}.Y_{n-1}$ ## Question 2 **Enoncé**: Quel est le format utilisé pour la représentation des coeficients et des échantillons de mesure ? Ici: $2^{15}-1 = 32767$ représente $1$ Format des coeficients: **16Q15** ## Question 3 **Enoncé**: Ecrire le programme d'un filtre IIR d'ordre 2 Entrées : DAC (Digital Analogic Converter) => **16Q0** On aura donc des opérations de type = $16Q15*16Q0 = 32Q15$. On doit avoir un résultat de type *long* (32 bits). ```c= #define B0 0 #define B1 1 #define B2 2 #define A0 3 #define A1 4 #define A2 5 int IIR_II(int input) { long temps; static signed int x[3] = { 0, 0, 0 }; static signed int y[3] = { 0, 0, 0 }; x[0] = input; temps += (long)coef[B0] * x[0]; temps += (long)coef[B1] * x[1]; temps += (long)coef[B2] * x[2]; temps -= (long)coef[A1] * y[1]; temps -= (long)coef[A2] * y[2]; temps >>= 15; y[0] = (short int)temps; y[2] = y[1]; y[1] = y[0]; x[2] = x[1]; x[1] = x[0]; return y[0]; } ``` ### Question 4 **Enoncé**: On appelle un filtre FIR, un filtre décrit pr la fonction de transfert suivante : $$ H(z) = \frac{Y(z)}{X(z)} = b_{0}+b_{1}.z^{-1}+...+b_{N}.z^{-N} $$ Ecrire le programme d'un filtre FIR d'ordre N quelconque ```c= #define N signed in IIR(void) { int i = 0; long temps = 0; static int init = 0; static signed int x[N+1]; if (init == 0) { for (i = 0; i <= N; ++i) { x[i] = 0; init = 1; } } for (i = 0; i <= N; ++i) { temps += ((long)coef[i] * x[i]); } temps >>= 15; if (temps > 32767) { temps = 32767; } else if (temps < -32767) { temps = -32767; } for (i = N; i > 0; --i) { x[i] = x[i - 1]; } return (short int)temps; } ``` ## Partie D ### Question 1 a. 1,5625 MSPS (`6,25 / 4`) b. Nous avons deux solutions : - Travailler avec deux échantillonneurs et deux séquenceurs. Le séquenceur SEQ1 est prioritaire. - SEQ1: voies 0 et 1 et sera déclenché par l'évènement SOCA - SEQ2: voies 8 et 9 et sera déclenché par SOCB - Travailler avec un seul séquenceur avec un nombre de différence de conversions dans la séquence ### Question 2 a. MAXCONV1 & MAXCONV permettent de contrôler le nombre de conversions effectuées dans une séquence. On fait $n+1$ conversion. b. 1. Séquences: Seq1: 01010101 Seq2: 89898989 MAXCONV1: 7 MAXCONV2: 7 SEQ_CASC: 0 // On travaille avec deux séquenceurs 2. Sequence: 0,1,2,3...15 MAXCONV1: 15 MAXCONV2: 0 (peu importe) SEQ_CASC: 1 // On travaille avec les 4 premiers bits ### Question 3 - *Donner le rôle des registres ADCCHSELSEQ1 & ADCCHSELSEQ2* Ils permettent de sélectionner les voies à convertir. - *Donner le contenu de ces registres lorsqu'on souhaite faire la séquence d'acquisitions suivante: voie1, voie3, voie5, voie7, voie0, voie2, voie4, voie6* Séquence: 13570246 ADCCHSELSEQ1: 0x7531 ADCCHSELSEQ2: 0x6420 ### Question 4 A l'aide des documentations fournies (fichier `DSP280X_Adc.h`), écrire une portion de code C permettant d'initialiser les registres et répondant à la question 3. ```c= AdcRegs.ADCCHSELSEQ1.all = 0x7531; AdcRegs.ADCCHSELSEQ2.bit.CONV4 = 0; AdcRegs.ADCCHSELSEQ2.bit.CONV5 = 2; AdcRegs.ADCCHSELSEQ2.bit.CONV6 = 4; AdcRegs.ADCCHSELSEQ2.bit.CONV7 = 6; ``` # TD 3 & 4 ## Exercice n°1 On désire réaliser un décodeur disposant en entrée d'un vecteur de deux bis et d'un signal de sélection, en sortie d'un vecteur de 4 bits tous de type `std_logic`. Table de vérité: ![](https://i.imgur.com/K3mvKEg.png) X: quelconque - Ecrire l'entité correspondante ```vdhc= entity demux is port( sel: in std_logic; A: in std_logic_vector(1 downto 0); Y: out std_logic_vector(3 downto 0) ); end demux; ``` - Ecrire l'architecture en utilisant les affectations sélectives et conditionnelles ```vdhc= entity demux is port( sel: in std_logic; a: in std_logic_vector(1 downto 0); y: out std_logic_vector(1 downto 0) ); end demux; architecture arch1 of demux is -- Affectation conditionnelle -- begin j <= "1111" when sel = '1' else "1110" when A = '00' else "1101" when A = '01' else "1011" when A = '10' else "0111" when A = '11' else "1111"; end; architecture arch2 of demux is -- Affection sélective -- signal sel_a: std_logic_vector(2 downto 0); begin with sel_a select y <= "1110" when "000", "1101" when "001", "1011" when "010", "0111" when "011", "1111" when others; sel_a <= sel&a end; ``` ## Exercice n°2 On désire réaliser un comparateur dont l'entité est décrite ci-dessous: ```vhdl= entity Comparator is port( A: in std_logic_vector(7 downto 0); B: in std_logic_vector(7 downto 0); less: out std_logic; equal: out std_logic; greater: out std_logic ); end Comparator; ``` - Ecrire l'architecture en considérant que les signaux de sortie sont actifs à l'état '1' ```vdhc= architecture arch f Comparator is -- Affectation conditionnelle -- begin less <= "1" when A < B else '0'; equal <= "1" when A = B else '0'; greater <= "1" when A > B else '0'; end; ``` - Modifier l'entité et l'architecture pour travailler sur une taille de vecteur quelconque ```vdhc= entity genComp is generic (N: natural := 8); port ( A,B: in std_logic_vector(N-1 downto 0); less: out std_logic; equal: out std_logic; greater: out std_logic ); end; ``` ## Exercice n°3 On désire réaliser un registre à décalage à gauche de 8 bits sur front montant d'horloge à entrée et sortie série: ```vdhc= entity Shift_left is port( clk: in std_logic; SI: in std_logic; SO: out std_logic ); end Shift_left; ``` - Ecrire l'architectre en utilisant une boucle pour le décalage ```vdhc= architecture arch of shift_left is signal tmp: std_logic_vector(7 downto 0); begin process(clk) begin if (clk'event and clk='1') for i in 0 to 6 loop tmp(i+1) <= tmp(i); end loop; tmp(0) <= SI; end if; end; end process; SO <= tmp(7); end; ``` - Quel opérateur pourrait-on utiliser pour effectuer le décalage ? ```vdhc= architecture arch of freg is begin process (clock, clear) begin if clear='1' then Q <= (others => '0'); elsif clock'event and clock='1' then if load='1' then Q <= I; endif; endif; end; end process; end; ``` - Modifier l'entité et l'architecture pour travailler sur une taille ```vdhc= entity FIR4_Taps is port( clk: in std_logic; X: in signed(7 downto 0); Y: out signed(15 downto 0) ); end; architecture arch of FIR4_Taps is component DFF is port( Q: out signed(15 downto 0); clk: in std_logic; D: in signed(15 downto 0) ); end component; -- H[-2,-1,3,4] signal H0,H1,H2,H3: signed(7 downto 0); signal MCM0,MCM1,MCM2,MCM3: signed(15 downto 0); signal add1,add2,add3: signed(15 downto 0); signal Q1,Q2,Q3: signed(15 downto 0); begin H0 <= to_signed(-2,8); H1 <= to_signed(1,8); H2 <= to_signed(3,8); H3 <= to_signed(4,8); MCM3 <= H3 * X; MCM2 <= H2 * X; MCM1 <= H1 * X; MCM0 <= H0 * X; add1 <= Q3 + MCM0; add2 <= Q2 + MCM1; add3 <= Q1 + MCM2; dff1: DFF portmap(Q1,clk,MCM3); dff2: DFF portmap(Q2,clk,add3); dff3: DFF portmap(Q3,clk,add2); process(clk) begin if (rising_edge(clk)) Y <= add1; end if; end; end process; end; ``` ## Exercice n°4: Structures séquentielles (registres et horloges) On désire réaliser un registre (structure entrant dans la réalisation des filtres) dont l'entité est fournie ci-après : ```vdhc= entity reg is generic(n: natural :=2); port( I: in std_logic_vector(n-1 downto 0); clock: in std_logic; load: in std_logic; clear: in std_logic; Q: out std_logic_vector(n-1 downto 0) ); end reg; ``` Le raz est asynchrone et le chargement s'effectue sur un front montant du signal d'horloge clock. - Ecrire l'architecture correspondante ## Exercice n°5: Structures séquentielles (variables, boucles...) On désire réaliser un mulplieur 2x2 bits produisant un résultat sur 4 bits à partir d'une suite d'additions et de décalages (méthode identique à la méthode manuelle) en utilisant un process et des variables. - Ecrire l'entité correspondante - Ecrire l'architecture - Pour la taille fixe décrite dans l'énoncé - Modifier l'entité et l'architecture pour obtenir un multiplieur générique ## Exercice n°6: Structure de filtres Cet exercice vise à réaliser un filtre FIR à 4 cellules réalisé à partir de multiplieur cablés disponibles sur le circuit FPGA. $$ Y[n] = \sum_{i=0}^{N-1}H[i]X[n-i] $$ La description nécessite l'utilisation des bibliothèques suivantes: ```vdhc library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; ``` Avec le type: ```vdhc type SIGNED is array (NATURAL range <>) of STD_LOGIC; ``` L'implémentation recherchée est donnée ci-contre avec X un vecteur de 8 bits et Y la sortie sur 16 bits. **Note:** pour une synchronisation de la sortie avec l'horloge nous utiliserons une vascule supplémentaire (non représentée). Pour réaliser ce filtre, on dispose d'un composant `DFF bascule D-edge` travaillant sur des vecteurs de 16 bits et de la fonction `TO_SIGNED` de la bibliothèque `IEEE.NUMERIC_STD` ci-dessous: ```vdhl= -- null range array constants constant NAU: UNSIGNED(0 downto 1) := (others => '0') constant NAS: SIGNED(0 downto 1) := (others => '1') -- implementation controls -- default to emit warnings constant NO_WARNING: BOOLEAN := FALSE; ```