Découvrez notre Chaîne YouTube "Devenir Ingénieur"
Le blog contient des publicités, elles permettent de financer l'hébergement et maintenir le blog en fonctionnement. Vous pouvez utiliser adblock pour une lecture sans publicités.

Projet FPGA Calcul de Factorielle n logarithme de factorielle - factorielle de 0

Objectifs du projet :

  • Savoir comment calculer la factorielle de 0 ?
  • Savoir comment maintenir les données en mémoire dans le bus de sortie ?
  • Savoir comment synchroniser les données à l’entrée ?
  • Savoir implémenter la fonction de saturation en VHDL
  • Implémentation sur carte du projet

Analyse de fonctionnement

Comment calculer la factorielle de 0 ?

Dans ce projet on va s’intéresser aux aspects pratiques du code VHDL illustrés dans le projet 7. Comme vous constatez dans le projet 7, la factorielle de 0 n’est pas implémentée ! Je m’en suis rendu compte durant les tests sur carte du composant. Souvent en électronique, on fait des allers-retours entre l’étape de développement et implémentation pour but d’obtenir un fonctionnement optimal. En pratique, c’est rare que notre code marche au premier coup 🙂

Revenant à notre question, une solution possible est de tester la valeur de la donnée à l’entrer : Si elle est nulle on remplace la valeur nulle par 1 et on maintient la valeur dans le cas contraire.

if D_in=b"00000" then
        D_in_tmp <= b"00001";
else
        D_in_tmp<= D_in;
end if;

La donnée dans le bus de sortie D_out dure un coup d’horloge, la sortie passe à 1 dans le prochain coup d’horloge. D’une autre façon, le résultat dans le bus de sortie D_out bascule entre ‘1’ et D_in! (voir image ci-dessous) Ce fonctionnement peut être indésirable si on cherche une donnée stable tant que la donnée à l’entrée reste inchangée. L’avantage du fonctionnement mémoire est d’assurer que la donnée soit lisible et acquise correctement par le composant en amant.

Projet FPGA Calcul de Factorielle n logarithme de factorielle - simulation 6

L’implémentation de la fonction mémoire peut être réalisée à l’instant de la détection du front montant du signal D_outReady, dalleur ce dernier passe à 1 au même temps que la donnée soit présente dans le bus de sortie.  L’approche consiste la mise à jour de la donnée de sortie uniquement durant le front montant du signal D_outReady.

Comme vous l’avez constaté, le bus de sortie est sur 123 bits pour une entrée sur 5 bits. Dans la partie implémentation on va s’intéresser uniquement par les 8 premiers bits du bus de sortie à cause de limitation de notre des LED dans notre kit de développement. Ce choix impose que la sortie D_out ne puisse prendre que des valeurs inférieures ou égales à 255 (1111 1111). D’une autre manière on ne peut calculer que les factorielles des valeurs suivantes : 0, 1, 2, 3 et 4. La factorielle de 6 != 720 >255. La fonction de saturation sera active pour des valeurs en entrée allant de 6 à 31. On a choisi 255 (FF) comme valeur de saturation. La figure ci-dessous illustre la fonction du transfert du composant menu de la fonction de saturation et le code Matlab correspondant:

Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - saturation

Code matlab
clear all; close all; clc

% D_in
N=5;
D_in=0:2^N-1;

% D_out
D_out_tmp=factorial(D_in);
D_out=zeros(1,length(D_in));

for i=1:length(D_in)
    if D_out_tmp(i)>=255
        D_out(i)=255;
    else
        D_out(i)=D_out_tmp(i);
    end;
end

% Affichage
figure(1);
plot(D_in,D_out); grid on; hold on
xlim([D_in(1) D_in(end)]);
ylim([D_out(1) D_out(end)+10]);
xlabel('D_{in}(1..31)');
ylabel('D_{out}(1..255)');

Extrait du code VHDL de la fonction de mémorisation et de saturation :

...
if D_outReady_tmp='1' then
        if D_out_tmp > x"000000000000000000000000008" & b"00000" then  -- 256
                D_out <= x"FF";
        else
                D_out <= D_out_tmp(P-1 downto 0);
        end if;
end if;
...

Code VHDL (FactorielMem.vhd):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FactorielMem is
        Generic ( N : positive := 108;
                  M : positive := 5;
                      P : positive := 8
                        );
    Port ( Rst                         : in  STD_LOGIC;
           Clk                         : in  STD_LOGIC;
           D_in                 : in  STD_LOGIC_VECTOR (M-1 downto 0);
           D_out_Ready                 : out  STD_LOGIC;
           D_out                 : out  STD_LOGIC_VECTOR (P-1 downto 0));
end FactorielMem;
architecture Behavioral of FactorielMem is
signal D_outReady_tmp         :   STD_LOGIC :='0';
signal D_out_tmp         :   STD_LOGIC_VECTOR (N+M-1 downto 0):=x"000000000000000000000000000" & b"00001";
signal D_in_tmp         :   STD_LOGIC_VECTOR (M-1 downto 0):=b"00001";
COMPONENT FactorielN
PORT(
        Rst : IN std_logic;
        Clk : IN std_logic;
        D_in : IN std_logic_vector(M-1 downto 0);
        D_out_Ready : OUT std_logic;
        D_out : OUT std_logic_vector(N+M-1 downto 0)
        );
END COMPONENT;
begin
        FAC5: FactorielN PORT MAP(
                Rst => Rst,
                Clk => Clk,
                D_in => D_in_tmp,
                D_out_Ready => D_outReady_tmp,
                D_out => D_out_tmp
        );
        -- Memorisation de la sortie + Gestion de 0!
        P_data_out : process(Rst, Clk, D_outReady_tmp)
        begin
                if Rst ='1' then
                        D_out(P-1 downto 1) <=(others =>'0');
                        D_out(0) <= '1';
                elsif Clk = '1' and Clk'event then
                        -- 0!=1
                        if D_in=b"00000" then
                                D_in_tmp <= b"00001";
                        else
                                D_in_tmp<= D_in;
                        end if;
                        -- Saturation de la sortie
                        if D_outReady_tmp='1' then
                                if D_out_tmp > x"000000000000000000000000008" & b"00000" then  -- 256
                                        D_out <= x"FF";
                                else
                                        D_out <= D_out_tmp(P-1 downto 0);
                                end if;
                        end if;
                end if;
        end process;
        D_out_Ready <=D_outReady_tmp;
end Behavioral;

Code VHDL du fichier de simulation (tb_FactorielMem.vhd):

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std;
ENTITY tb_FactorielMem IS
END tb_FactorielMem;
ARCHITECTURE behavior OF tb_FactorielMem IS
        -- Component Declaration for the Unit Under Test (UUT)
        COMPONENT FactorielMem
        PORT(
                Rst : IN  std_logic;
                Clk : IN  std_logic;
                D_in : IN  std_logic_vector(4 downto 0);
                D_out_Ready : OUT  std_logic;
                D_out : OUT  std_logic_vector(7 downto 0)
                );
        END COMPONENT;
        --Inputs
        signal Rst : std_logic := '1';
        signal Clk : std_logic := '0';
        signal D_in : std_logic_vector(4 downto 0) := b"00001";
        --Outputs
        signal D_out_Ready : std_logic;
        signal D_out : std_logic_vector(7 downto 0);
        -- Clock period definitions
        constant Clk_period : time := 10 ns;
BEGIN
        -- Instantiate the Unit Under Test (UUT)
        uut: FactorielMem PORT MAP (
                Rst => Rst,
                Clk => Clk,
                D_in => D_in,
                D_out_Ready => D_out_Ready,
                D_out => D_out
                );
        -- Clock process definitions
        Clk_process :process
        begin
                Clk <= '0';
                wait for Clk_period/2;
                Clk <= '1';
                wait for Clk_period/2;
        end process;
        -- Rst process definitions
        Rst_process :process
        begin
                Rst <= '1';
                wait for Clk_period;
                Rst <= '0';
                wait for 200*Clk_period;
        end process;
        -- Input Data process definitions
        D_in_process :process
        begin
                D_in <= D_in+1;
                wait for 50*Clk_period;
        end process;
END;

Résultats de simulation:

Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - simulation 2

Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - simulation 1

Pinout du composant (pinout_FactorielMem.ucf) :

# Alimentation
CONFIG VCCAUX = "3.3" ;
# Horloge 12 MHz
NET "Clk"                     LOC = P129  | IOSTANDARD = LVCMOS33 | PERIOD = 12MHz;
# Entees: Rst + D_in
NET "Rst"                     LOC = P70   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_in[0]"                 LOC = P69   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_in[1]"                 LOC = P68   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_in[2]"                 LOC = P64   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_in[3]"                 LOC = P63   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_in[4]"                 LOC = P60   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
# Sortie D_out_Ready
NET "D_out_Ready"            LOC = P19   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
# Sortie D_out
NET "D_out[0]"                LOC = P46   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[1]"                LOC = P47   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[2]"                LOC = P48   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[3]"                LOC = P49   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[4]"                LOC = P50   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[5]"                LOC = P51   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[6]"                LOC = P54   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "D_out[7]"                LOC = P55   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;

 

Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - factorielle 0 cablage

Photos du projet:

Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 2 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 2
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 4 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 4
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 3 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 3
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 5 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 5
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 6 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 6
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 15 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 15
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 31 Implémentation FPGA Calcul de Factorielle n logarithme de factorielle -factorielle 31
Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - Valeurs Implémentation FPGA Calcul de Factorielle n logarithme de factorielle - Valeurs

Vidéo illustrative:

************

Un petit commentaire de vous, un Grand encouragement pour nous 🙂

************

Téléchargement du projet

************


1 commentaire

  • Projet électronique FPGA #10 : Commande factorielle d’un moteur à CC avec Arduino et FPGA – FPGA | Arduino | Matlab | Cours · 2018-09-29 à 5:18

    […] PROJET #9 : CALCUL DE LA FACTORIELLE DE N: IMPLÉMENTATION SUR CARTE FPGA […]

  • Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Anti-Robot *

    You have successfully subscribed to the newsletter

    There was an error while trying to send your request. Please try again.

    FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.