vhdl operation mathematique
Répondre à la discussion
Affichage des résultats 1 à 22 sur 22

vhdl operation mathematique



  1. #1
    invite938b5933

    vhdl operation mathematique


    ------

    Bonjour a tous,

    j'utilise quartus 2 pour programmer en vhdl un max2 de chez altera.
    J'ai un vecteur sur 24 bits qui arrivent toutes les 1 ms environ et je voudrais faire deux choses avec:
    1- j'aimerais avoir accès à la différence entre entre deux valeurs successives de ces vecteurs 24 bits en continue de sorte que si la différence est nulle je ne garde pas le vecteur.
    input : vect1 ,vect2 , ...... vect n
    sortie : vect2-vect1, vect3-vect2 , ......,vect n-vect n-1

    EN faite je vais envoyer par rs 232 les vecteurs 24 bits sur un pc mais je souhaiterais envoyer les vecteurs seulement quand ils ont changé.(je pense que c'est facile a faire une fois qu'on a la différence entre deux vecteurs successifs avec simplement des boucles condition).
    2- j'aimerais aussi pouvoir avoir la moyenne des vecteurs toutes les secondes seulement je suis limité par le nombre de bits max d'un vecteur (31 bits ???)
    je faisais jusqu'à maintenant la somme de tous ces vecteurs mais j'ai besoin de faire une somme d'environ 1000 vecteurs (soit 10 bits en plus des 24 bits) et je ne sais pas trop comment solutionné ce problème. De plus, je dois ensuite divisé ma somme par 1000 en vhdl.

    Est ce quelqu'un a une idée pour réaliser ces choses en vhdl?
    Merci

    -----

  2. #2
    invite0a7d2e9a

    Re : vhdl operation mathematique

    bonjour,

    1. alors si j'ai bien compris tu ne sais pas comment faire...
    effectivement tu ne peux pas effectuer directement d'opération sur un vecteur. il faut le convertir (et aussi intégrer la bonne librairie). suivant la librairie ça peut etre un peu différent. moi j'utilise : "use ieee.numeric_std.all;"
    ensuite tu peux faire plein de truc : conversion de type et calcul.
    différents type : signed unsigned et integer pour ceux qui t'intéresse.
    donc toi en entré tu doit avoir un STD_LOGIC_VECTOR, il te duffit donc de le convertir en signed ou unsigned (suivant si tu travail en signé ou non signé) en faisant
    out <= STD_LOGIC_VECTOR(unsigned(vect 1) + unsigned(vect2))
    le tout dans un process biensur... (enfin je crois que c'est obligatoire)
    je ne saais pas si tu t'y connais en VHDL mais tu peux aussi créer des signaux interne qui t'aideront à mieux structurer ton code

    2. je ne comprends pas trop ta limitation? ton FPGA ne veux pas faire de vecteur de plus de 24 ou 31 bits? (en es tu sur?)
    si c'est le cas tu peux toujours utiliser 2 vecteur, un pour les poids fort et un pour les poids faible (ça demande un peu de gymnastique mais au moins tu va apprendre des choses)
    et divisé par 1000 c'est pas tres pratique, le mieux serais de faire une moyenne sur 1024 (ça plus que 1 décalage) sinon il te reste l'option avec la librairie numeric_std.all elle permet aussi de faire des division (peut etre que avec les "integer" mais c'est faisable si tu veux un peu de syntaxe n'hesite pas je peux te donner une ou deux ligne en exemple

    bon courage a bientot

  3. #3
    invite938b5933

    Arrow Re : vhdl operation mathematique

    bonjour Hayuki,
    merci de ton aide.

    1-
    En fait j'utilise deja cette librairie, mon problème est plus du coté du stockage et de la récupération des vecteurs successifs.
    Est ce que je peux faire un truc du genre:
    architecture DESCRIPTION of soustraction is
    signal Compt_2 : integer range 0 to 2;
    signal vect1 : std_logic_vector ( 0 to 23);
    signal vect2 : std_logic_vector ( 0 to 23);
    begin
    soustraction:PROCESS(SI_SENSOR )
    begin
    if(RESET='1') then
    if ( SI_SENSOR='1' and SI_SENSOR'event) then
    Compt_2 <= Compt_2 + 1;
    end if;

    if (Compt_2 =1) then
    vect1<=vector;
    else if (Compt_2 =2) then
    vect2<=vector;
    Compt_2<=0;
    end if;
    diff<= STD_LOGIC_VECTOR(unsigned(vect 2) - unsigned(vect1));
    end if;

    END PROCESS soustraction;

    END DESCRIPTION ;
    je connais l'existence du vhdl depuis 2semaines.

  4. #4
    invite0a7d2e9a

    Re : vhdl operation mathematique

    ça me semble correcte
    je pense que c'est bon tu te debrouille pas trop mal
    par contre le mieux serais de tout mettre dans le process et de tout mettre dans le "if ( SI_SENSOR='1' and SI_SENSOR'event)" comme ça tout est sensible à l'horloge et quartus n'aura pas a interpréter certaine chose ça t'évitera des problème de synchro et autres erreurs.
    ensuite une erreur classique : si ton "reset" est synchrone, il faut le mettre apres avoir tester le front montant, si il est asynchrone il faut le mettre dans la liste de sensibilité du process.
    erreur suivante : tu n'indique pas quoi faire en cas de reset, c'est tres mauvais quartus va devoir générer cet état et il mettra ce qu'il veut...

    donc moi j'écrirais :
    architecture DESCRIPTION of soustraction is
    signal Compt_2 : integer range 0 to 2;
    signal vect1 : std_logic_vector ( 0 to 23);
    signal vect2 : std_logic_vector ( 0 to 23);
    begin
    soustraction:PROCESS(SI_SENSOR , RESET)
    begin
    if(RESET='1') then
    if ( SI_SENSOR='1' and SI_SENSOR'event) then
    Compt_2 <= Compt_2 + 1;
    if (Compt_2 =1) then
    vect1<=vector;
    else if (Compt_2 =2) then
    vect2<=vector;
    Compt_2<=0;
    end if;
    diff<= STD_LOGIC_VECTOR(unsigned(vect 2) - unsigned(vect1));
    end if;
    else
    diff <= "00000000000000000000000";
    -- et utiliser les autres sorties au cas ou il y en ait
    end if;

    END PROCESS soustraction;

    END DESCRIPTION ;

    le mieu en VHDL c'est de ne rien laisser au hasard et de traiter tous les cas, ensuite faire en sorte que toutes les opérations soient synchrone sur le meme front (montant ou descendant). ne pas hesiter a faire des signaux ce n'est pas comme en C ça n'utilise pas de ressources inutiles, tout sera optimisé

  5. A voir en vidéo sur Futura
  6. #5
    invite938b5933

    Re : vhdl operation mathematique

    merci de ton aide.
    En faite avec ces technique utilisant un compteur j'aurais la soustraction que une fois sur deux.
    J'ai fais un autre truc qui me semble marcher.
    architecture DESCRIPTION of soustraction is

    signal vect1 : std_logic_vector ( 0 to 23):=(others =>'0');
    signal signal_SOUSTRACTION : std_logic_vector ( 0 to 23);
    begin

    soustraction:PROCESS( SI_SENSOR , RESET)
    begin
    if(RESET='1') then
    if ( SI_SENSOR='1' and SI_SENSOR'event) then
    if ( SOMME_PIXELS >= vect1) then
    signal_SOUSTRACTION <= SOMME_PIXELS - vect1;
    else
    signal_SOUSTRACTION <= vect1 - SOMME_PIXELS;
    end if;
    vect1 <= SOMME_PIXELS;
    end if;

    else
    vect1 <= (others =>'0');
    signal_SOUSTRACTION<=(others =>'0');
    end if;

    END PROCESS soustraction;
    SOUSTRACTION <= signal_SOUSTRACTION;
    vect1_v <= vect1;
    END DESCRIPTION ;
    J'ai pas besoin de vect2, je récupère instantanément la valeur fais la soustraction avec la valeur precedente.
    Par contre, c'est vrai que penser a tous les cas c'est pas facile.
    Bon je reattaque la moyenne.

  7. #6
    invite0a7d2e9a

    Re : vhdl operation mathematique

    je ne sais pas ce que fais ton IP donc je ne peux pas dire grand chose, mais ça parait bien et bien pensé.

  8. #7
    invite938b5933

    Re : vhdl operation mathematique

    pour la moyenne, j'ai un probleme de décalage et je ne sais pas pourquoi.
    architecture DESCRIPTION of moyenne is

    signal Compt_1024: integer range 0 to 1023;
    signal signal_moyenne : std_logic_vector ( 0 to 33):=(others =>'0');
    signal moyenne_initial : std_logic_vector ( 0 to 33):=(others =>'0');
    signal resultat_moyenne: std_logic_vector ( 0 to 33);
    begin

    Pmoyenne:PROCESS( SI_SENSOR , RESET)
    begin
    if(RESET='1') then
    if ( SI_SENSOR='1' and SI_SENSOR'event) then

    if ( Compt_1024 = 0) then
    moyenne_initial<=(others =>'0');
    end if;

    moyenne_initial <= signal_moyenne;
    signal_moyenne <= moyenne_initial + SOMME_PIXELS;--prend la valeur precedente et ajoute la nouvelle valeur

    Compt_1024 <= Compt_1024 + 1;

    if ( Compt_1024 = 1023) then
    resultat_moyenne <= signal_moyenne;
    MOYENNE_DISPO<= '1';
    Compt_1024<= 0;

    else
    MOYENNE_DISPO<= '0';
    end if;

    end if;
    end if;

    else

    MOYENNE_DISPO<= '0';
    signal_moyenne<=(others =>'0');
    end if;

    END PROCESS Pmoyenne;
    MOYENNE_RESULTAT <= resultat_moyenne;
    SIGNAL_MOYENNE_V <= signal_moyenne;
    END DESCRIPTION ;

  9. #8
    invite0a7d2e9a

    Re : vhdl operation mathematique

    problème de décalage?
    je ne comprend pas... où?
    ensuite tu ne divise pas par 1024 donc tu as juste une somme non? donc pas une moyenne?

  10. #9
    invite938b5933

    Re : vhdl operation mathematique

    EN faite la somme je l'envoie dans un bloc diviseur donc mon programme me calcule une somme et je la divise ensuite avec un bloc lpm_divide. C'est la methode la plus simple que j'ai trouvé mais je pense qu'il y en d'autre. Parce qu'on ne peut pas faire de division en vhdl simplement.
    si je change le type de mon signal,
    signal moyenne_initial : std_logic_vector ( 0 to 33):=(others =>'0');
    en
    variable moyenne_initial : std_logic_vector ( 0 to 33):=(others =>'0');
    ca marche mais j'aimerais bien comprendre pourquoi.

  11. #10
    invite938b5933

    Re : vhdl operation mathematique

    quand j'essaie de faire une division, j'ai une erreur :
    Error (10327): VHDL error at moyenne.vhd(47): can't determine definition of operator ""/"" -- found 0 possible definitions
    pourtant j'ai bien mis la librairie Use ieee.numeric_std.all;

    Je ne peux pas simplement faire a la ligne
    resultat_moyenne <= signal_moyenne/1024;
    ??
    et je ne suis pas limité par mon fpga comme je le pensais au début.
    Je peux créer des out std_logic_vector ( 0 to 33); sans problème.

  12. #11
    invite0a7d2e9a

    Re : vhdl operation mathematique

    ça ne marche pas car ton signal moyenne est un std_logic_vector et pas un unsigned...
    ensuite je t'ai fait faire 1024 point pour que tu n'ai qu'un décalage a faire et non une division complete : un division par 1024 c'est un décalage de 10 bits (ou 9) vers la droite donc
    resultat(0 to 23)<= signal_moyenne(23 to 33)
    et la tu realise un décalage en live en faisant juste des connexions sans éléments logiques!
    ensuite je te conseil de faire tres attention a : (0 to 33) et (33 downto 0) ça change l'ordre des bits dans le vecteur, utilise la meme chose dans toutes tes IP
    ce que tu préfère mais dan un cas 1 sur 4 bits s'écrit 1000 dans l'autre 0001 donc quand tu vas passer d'une IP en 0 to 4 à une IP en 4 downto 0 tu va passer de 1 à 8 pour l'interprétation du chiffre...

  13. #12
    invite938b5933

    Re : vhdl operation mathematique

    bonjour,
    j'ai terminé mes calculs de moyenne et de différence et ils marchent un peu près comme je veux. ^^ merci de ton aide
    Par contre, je dois maintenant envoyer les résultats par un bus rs 232. J'ai sur ma carte élec un émetteur rs 232 (http://www.st.com/stonline/products/...4/st3232eb.pdf) ainsi qu'un connecteur sub d9 mais je ne sais pas trop comment programmer en vhdl la transmission des données et aussi comment les recevoir sur un pc.
    Est ce compliqué?

  14. #13
    jiherve

    Re : vhdl operation mathematique

    Bonsoir,
    Tu consultes opencore.org et wasaaa !
    http://opencores.org/projects
    JR
    l'électronique c'est pas du vaudou!

  15. #14
    invite938b5933

    Re : vhdl operation mathematique

    Bonjour,
    j'ai regardé le site opencores mais je ne trouve rien sur la communication rs 232 (code vhdl).
    Il faut s'inscrire ?

  16. #15
    jiherve

    Re : vhdl operation mathematique

    Bonjour,
    il faut chercher à UART ,ou serial asynchronous ,...!
    l'appellation RS232 ne recouvre que l'interface électrique.
    oui il faut s'inscrire, comme ici!
    JR
    l'électronique c'est pas du vaudou!

  17. #16
    invite938b5933

    Re : vhdl operation mathematique

    Merci jiherve, j'ai trouvé ce que je voulais pour la liaison rs 232 par contre j'ai 4 mots binaires 24 bits a envoyer avec une vitesse max pour la lisaison rs 232 230400 bits/s. Je cherche donc un moyen de convertir mes 4 mots 24 bits en bcd afin d'avoir 8 * 4 chiffres bcd a envoyer.
    Ou puis je trouver un code vhdl pour convertir du binaire 24 bits en bcd?
    Merci

  18. #17
    jiherve

    Re : vhdl operation mathematique

    Bonsoir,
    attention la vitesse choisie est hors normes pour de la RS232.
    Pour la conversion Bin BCD un bon tutorial:
    http://edda.csie.dyu.edu.tw/course/fpga/Binary2BCD.pdf
    JR
    l'électronique c'est pas du vaudou!

  19. #18
    invite938b5933

    Re : vhdl operation mathematique

    J'ai repris un code qui marchait bien sur 8 bits et je l'ai adapté pour 24 bits. La conversion des nombres sur 8 bits marche encore mais pas la conversion des nombres sur 24 bits et je ne comprend pas trop pourquoi vu que c'est la même chose.
    Code:
    library ieee;
    use ieee.std_logic_1164.all;
    Use ieee.numeric_std.all;
    use ieee.std_logic_signed.all;
    
    package BINARYTOBCD is 
    
    function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector;
    
    end;
    
    package body BINARYTOBCD is
    	function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector  is
    	
    		variable i : integer:=0;
    		variable bcd : std_logic_vector(32 downto 0) := (others => '0');
    		variable bint : std_logic_vector(23 downto 0) := bin;
    	
    		begin
    		for i in 0 to 23 loop  -- repeating 8 times
    		bcd(32 downto 1) := bcd(31 downto 0);  --shifting the bits.
    		bcd(0) := bint(23);
    		bint(23 downto 1) := bint(22 downto 0);
    		bint(0) :='0';
    
    
    		if(i < 23 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
    		bcd(3 downto 0) := bcd(3 downto 0) + "0011";
    		end if;
    	
    		if(i < 23 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
    		bcd(7 downto 4) := bcd(7 downto 4) + "0011";
    		end if;
    	
    		if(i < 23 and bcd(11 downto 8) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(11 downto 8) := bcd(11 downto 8) + "0011";
    		end if;
    		
    		if(i < 23 and bcd(15 downto 12) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(15 downto 12) := bcd(15 downto 12) + "0011";
    		end if;
    		
    		if(i < 23 and bcd(19 downto 16) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(19 downto 16) := bcd(19 downto 16) + "0011";
    		end if;
    		
    		if(i < 23 and bcd(23 downto 20) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(23 downto 20) := bcd(23 downto 20) + "0011";
    		end if;
    		
    		if(i < 23 and bcd(27 downto 24) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(27 downto 24) := bcd(27 downto 24) + "0011";
    		end if;
    
    		if(i < 23 and bcd(31 downto 28) > "0100") then  --add 3 if BCD digit is greater than 4.
    		bcd(31 downto 28) := bcd(31 downto 28) + "0011";
    		end if;
    		
    		end loop;
    		return bcd;
    	end to_bcd;
    end package body;
    Est ce que quelqu'un a une idée?

  20. #19
    jiherve

    Re : vhdl operation mathematique

    bonsoir,
    plusieurs erreurs:
    l'addition doit se faire en propageant la carry!
    [CODE]
    library ieee;
    use ieee.std_logic_1164.all;
    Use ieee.numeric_std.all;
    --use ieee.std_logic_signed.all; ne jamais utiliser l'implementation n'est pas toujours correcte

    package BINARYTOBCD is

    function to_bcd ( bin : std_logic_vector(23 downto 0) ) return std_logic_vector;

    end;

    package body BINARYTOBCD is
    function to_bcd ( bin : std_logic_vector(23 downto 0) ) return std_logic_vector is

    --variable i : integer:=0; cette variable ne sert à rien
    variable bcd : unsigned(32 downto 0);-- := (others => '0');ne pas initialiser à la déclaration
    variable bint : unsigned(23 downto 0);-- := bin;ne pas initialiser à la déclaration
    constant 3_1 : unsigned(32 downto 0) := to_unsigned(3,32);
    constant 3_2 : unsigned(32 downto 0) := to_unsigned(3*(16**1),32);
    constant 3_3 : unsigned(32 downto 0) := to_unsigned(3*(16**2),32);
    constant 3_4 : unsigned(32 downto 0) := to_unsigned(3*(16**3),32);
    constant 3_5 : unsigned(32 downto 0) := to_unsigned(3*(16**4),32);
    constant 3_6 : unsigned(32 downto 0) := to_unsigned(3*(16**5),32);
    constant 3_7 : unsigned(32 downto 0) := to_unsigned(3*(16**6),32);
    constant 3_8 : unsigned(32 downto 0) := to_unsigned(3*(16**7),32);

    begin
    loop1: for i in 0 to 23 loop -- repeating 24 times
    bcd(32 downto 0) := (bcd(31 downto 0) & bint(23); --shifting the bits.
    bint(23 downto 0) := (bint(22 downto 0) & '0');
    for j = 0 to 7

    if(i < 23 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_1;
    end if;

    if(i < 23 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_2;
    end if;

    if(i < 23 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_3;
    end if;

    if(i < 23 and bcd(15 downto 12) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_3;
    end if;

    if(i < 23 and bcd(19 downto 16) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_4;
    end if;

    if(i < 23 and bcd(23 downto 20) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_5;
    end if;

    if(i < 23 and bcd(27 downto 24) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_6;
    end if;

    if(i < 23 and bcd(31 downto 28) > "0100") then --add 3 if BCD digit is greater than 4.
    bcd(31 downto 0) := bcd(31 downto 0) + 3_7;
    end if;

    end loop;
    return std_logic_vector(bcd);
    end to_bcd;
    end package body;

    [CODE]
    l'électronique c'est pas du vaudou!

  21. #20
    jiherve

    Re : vhdl operation mathematique

    bonsoir,
    plusieurs erreurs:
    l'addition doit se faire en propageant la carry!
    Code:
    library ieee;
    use ieee.std_logic_1164.all;
    Use ieee.numeric_std.all;
    --use ieee.std_logic_signed.all; ne jamais utiliser l'implementation n'est pas toujours correcte
    
    package BINARYTOBCD is 
    
    function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector;
    
    end;
    
    package body BINARYTOBCD is
    	function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector  is
    	
      variable bcd : unsigned(32 downto 0);
      variable bint : unsigned(23 downto 0);
    	
      begin
         loop1: for i in 0 to 23 loop  -- repeating 24 times
           bcd(32 downto 0) := (bcd(31 downto 0) & bint(23);  --shifting  the bits.
          bint(23 downto 0) := (bint(22 downto 0) & '0');
          loop2: for j = 0 to 7 
    	if(i < 23 and bcd(j*4+3 downto j*4) >= to_unsigned(5,4)) then --add 3 if BCD digit is greater than 4.
    	bcd(31 downto 0) := bcd(31 downto 0) + to_unsigned(3*(16**j),32);
    	 end if;
          end loop loop2;
       end loop loop1;
       return std_logic_vector(bcd);
      end to_bcd;
    end package body;
    Sans garantie il est tard!
    JR
    message intempestif avant ne pas en tenir compte!
    Dernière modification par jiherve ; 19/07/2010 à 21h43.
    l'électronique c'est pas du vaudou!

  22. #21
    invite938b5933

    Re : vhdl operation mathematique

    Je viens d'essayer de compiler ce code mais je n'obtiens pas de résultat par contre il n'y a aucune erreur de compilation.
    Code:
    library ieee;
    use ieee.std_logic_1164.all;
    Use ieee.numeric_std.all;
    
    package BINARYTOBCD is 
    
    function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector;
    
    end;
    
    package body BINARYTOBCD is
    	function to_bcd ( bin : std_logic_vector(23 downto  0) )  return std_logic_vector  is
    	
      variable bcd : unsigned(32 downto 0);
      variable bint : unsigned(23 downto 0);
    	
      begin
    		loop1: for i in 0 to 23 loop  -- repeating 24 times
    			bcd(32 downto 0) := (bcd(31 downto 0) & bint(23));  --shifting  the bits.
    			bint(23 downto 0) := (bint(22 downto 0) & '0');
    				loop2: for j in 0 to 7 loop
    					if(i < 23 and bcd(j*4+3 downto j*4) >= to_unsigned(5,4)) then --add 3 if BCD digit is greater than 4.
    					bcd(31 downto 0) := bcd(31 downto 0) + to_unsigned(3*(16**j),32);
    					end if;
    				end loop loop2;
    		end loop loop1;
      
       return std_logic_vector(bcd);
       
      end to_bcd;
    end package body;

  23. #22
    invite938b5933

    Re : vhdl operation mathematique

    bon alors au final, j'ai repris une solution un peu identique et je l'ai arrangé pour qu'elle marche pour un binaire 24 bits.
    Par contre j'ai du bidouiller un ti truc pour que ca marche pour les pairs et impairs autrement ca ne marchait que pour les pairs.
    Content que ce soit finit cette conversion, maintenant plus qu'a envoyer sur le rs 232.
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.numeric_std.ALL;
    
    entity bin2bcd is
    port(
    	clk : in std_logic;
    	reset : in std_logic;
    	start : in std_logic;
    	bin : in std_logic_vector(23 downto 0);
    	ready, done_tick : out std_logic;
    	bcd3, bcd2, bcd1, bcd0, bcd4, bcd5, bcd6, bcd7 : out std_logic_vector(3 downto 0)
    );
    end bin2bcd;
    
    architecture arch of bin2bcd is 
    type state_type is (idle, op, done);
    signal state_reg, state_next: state_type;
    signal p2s_reg, p2s_next : std_logic_vector(23 downto 0);
    signal n_reg, n_next : unsigned (4 downto 0);
    signal bcd3_reg, bcd2_reg, bcd1_reg, bcd0_reg : unsigned (3 downto 0);
    signal bcd3_next, bcd2_next, bcd1_next, bcd0_next : unsigned (3 downto 0);
    signal bcd4_reg, bcd5_reg, bcd6_reg, bcd7_reg : unsigned (3 downto 0);
    signal bcd4_next, bcd5_next, bcd6_next, bcd7_next : unsigned (3 downto 0);
    signal bcd3_tmp, bcd2_tmp, bcd1_tmp, bcd0_tmp : unsigned (3 downto 0);
    signal bcd4_tmp, bcd5_tmp, bcd6_tmp, bcd7_tmp : unsigned (3 downto 0);
    
    begin
    
    	process(clk, reset)
    	begin
    	if (reset='1') then
    		state_reg<=idle;
    		p2s_reg <=(others =>'0');
    		n_reg <=(others =>'0');
    		bcd3_reg <=(others =>'0');
    		bcd2_reg <=(others =>'0');
    		bcd1_reg <=(others =>'0');
    		bcd0_reg <=(others =>'0');
    		bcd4_reg <=(others =>'0');
    		bcd5_reg <=(others =>'0');
    		bcd6_reg <=(others =>'0');
    		bcd7_reg <=(others =>'0');
    	elsif (clk'event and clk='1') then
    		state_reg<=state_next;
    		p2s_reg <=p2s_next;
    		n_reg <= n_next;
    		bcd7_reg <=bcd7_next;
    		bcd6_reg <=bcd6_next;
    		bcd5_reg <=bcd5_next;
    		bcd4_reg <=bcd4_next;
    		bcd3_reg <=bcd3_next;
    		bcd2_reg <=bcd2_next;
    		bcd1_reg <=bcd1_next;
    		bcd0_reg <=bcd0_next;
    	end if;
    	end process;
    	
    	process(state_reg, start, p2s_reg, n_reg, n_next, bin, bcd3_reg, bcd2_reg, bcd1_reg, bcd0_reg, bcd3_tmp, bcd2_tmp, bcd1_tmp, bcd0_tmp, bcd4_reg, bcd5_reg, bcd6_reg, bcd7_reg, bcd4_tmp, bcd5_tmp, bcd6_tmp, bcd7_tmp)
    	begin
    	state_next <= state_reg;
    	ready <= '0';
    	done_tick <= '0';
    	p2s_next <= p2s_reg;
    	bcd0_next <= bcd0_reg;
    	bcd1_next <= bcd1_reg;
    	bcd2_next <= bcd2_reg;
    	bcd3_next <= bcd3_reg;
    	bcd4_next <= bcd4_reg;
    	bcd5_next <= bcd5_reg;
    	bcd6_next <= bcd6_reg;
    	bcd7_next <= bcd7_reg;
    	n_next <= n_reg;
    	case state_reg is 
    		when idle =>
    			ready <= '1';
    			if (start ='1') then
    			state_next <= op;
    			bcd7_next <=(others =>'0');
    			bcd6_next <=(others =>'0');
    			bcd5_next <=(others =>'0');
    			bcd4_next <=(others =>'0');
    			bcd3_next <=(others =>'0');
    			bcd2_next <=(others =>'0');
    			bcd1_next <=(others =>'0');
    			bcd0_next <=(others =>'0');
    			n_next <= "11000";
    			p2s_next <= bin;
    			end if;
    			
    		when op =>
    			p2s_next <= p2s_reg(22 downto 0) & '0';
    			bcd0_next <= bcd0_tmp(2 downto 0) & p2s_reg(23);
    			bcd1_next <= bcd1_tmp(2 downto 0) & bcd0_tmp(3);
    			bcd2_next <= bcd2_tmp(2 downto 0) & bcd1_tmp(3);
    			bcd3_next <= bcd3_tmp(2 downto 0) & bcd2_tmp(3);
    			bcd4_next <= bcd4_tmp(2 downto 0) & bcd3_tmp(3);
    			bcd5_next <= bcd5_tmp(2 downto 0) & bcd4_tmp(3);
    			bcd6_next <= bcd6_tmp(2 downto 0) & bcd5_tmp(3);
    			bcd7_next <= bcd7_tmp(2 downto 0) & bcd6_tmp(3);
    			n_next <= n_reg -1;
    			if (n_next = 0) then
    
    			state_next <= done;
    			end if;
    		
    		when done =>
    				if ( bin(0)='1') then -- fixe le LSB a 1 quand le nombre binaire 24 bits est impaire
    				bcd0_next(0)<= '1';
    				end if;
    			state_next <= idle;
    			done_tick <= '1';
    	end case;
    end process;
    
    bcd0_tmp <= bcd0_reg + 3 when bcd0_reg > 4 else
    			bcd0_reg;
    bcd1_tmp <= bcd1_reg + 3 when bcd1_reg > 4 else
    			bcd1_reg;
    bcd2_tmp <= bcd2_reg + 3 when bcd2_reg > 4 else
    			bcd2_reg;
    bcd3_tmp <= bcd3_reg + 3 when bcd3_reg > 4 else
    			bcd3_reg;
    bcd4_tmp <= bcd4_reg + 3 when bcd4_reg > 4 else
    			bcd4_reg;
    bcd5_tmp <= bcd5_reg + 3 when bcd5_reg > 4 else
    			bcd5_reg;
    bcd6_tmp <= bcd6_reg + 3 when bcd6_reg > 4 else
    			bcd6_reg;
    bcd7_tmp <= bcd7_reg + 3 when bcd7_reg > 4 else
    			bcd7_reg;
    
    bcd0 <= std_logic_vector(bcd0_reg);
    bcd1 <= std_logic_vector(bcd1_reg);
    bcd2 <= std_logic_vector(bcd2_reg);
    bcd3 <= std_logic_vector(bcd3_reg);
    bcd4 <= std_logic_vector(bcd4_reg);
    bcd5 <= std_logic_vector(bcd5_reg);
    bcd6 <= std_logic_vector(bcd6_reg);
    bcd7 <= std_logic_vector(bcd7_reg);
    
    end arch;

Discussions similaires

  1. Question sur une opération mathématique simple
    Par invite8dd4df9d dans le forum Mathématiques du collège et du lycée
    Réponses: 7
    Dernier message: 05/01/2010, 14h16
  2. opération/tabac
    Par invitec7031087 dans le forum Santé et médecine générale
    Réponses: 3
    Dernier message: 29/05/2009, 23h01
  3. Point flottant en VHDL et vhdl-200x
    Par invite6eee6b27 dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 02/09/2008, 20h47
  4. opération chiffrée
    Par invitea451ee22 dans le forum Science ludique : la science en s'amusant
    Réponses: 6
    Dernier message: 12/06/2007, 23h25
  5. Operation en apesanteur
    Par invite92276dd8 dans le forum Actualités
    Réponses: 3
    Dernier message: 22/10/2006, 11h46
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...