Bonjour,
J'essaye générer un signal carré via un convertisseur numérique analogique (AD7569) connecté à une carte cpld, mais j'arrive pas à voir comment je peux générer ce signal avec du VHDL.
Pouvez-vous me guider?
-----
Bonjour,
J'essaye générer un signal carré via un convertisseur numérique analogique (AD7569) connecté à une carte cpld, mais j'arrive pas à voir comment je peux générer ce signal avec du VHDL.
Pouvez-vous me guider?
Bonjour,
Quelque chose comme ceci :
Le signal enable pourrait être obtenu en divisant le clk système par N.Code:p1 : process(clk,rst) begin if rst = '1' then vdac <= (OTHERS=>'0'); elsif rising_edge(clk) then if enable = '1' then vdac <= "11111111"; else vdac <= "00000000"; end if; end if; end process p1;
Salutations
bonjour,
merci bien pour votre réponse, mais si vous vous rappelez de moi, c'est moi la débutante qui devais faire du filtrage donc votre exemple je ne comprend pas grand chose, c'est quoi vdac? clk c l'horloge de la carte? rst c le reset global de la carte, donc si on active le rst il se passe quoi? et elle fait quoi cette fonction rising_edge?
moi a la base je me suis dis que je vais créer un compteur qui compte jusqu'à 50 par exemple et je dis c compter<25 on envoit un 1 et si compter>25 on envoit 0, puis on réinitialise et rebolote justement je savais pas trop comment me faire comprendre en VHDL, mais apparemment c plus compliquer que ca
Re,
Je me souviens du filtre VHDL mais plus exactement de la config de la carte de dev.
Il doit y avoir un process qui lit la valeur de l'ADC et écrit la valeur du DAC. Cette valeur est codé sur 8 bit car c'est la résolution du convertisseur. Donc pour faire un carré (amplitude max) ont écrit 255 puis 0, puis 255, puis 0....
L'idée du compteur est correcte, et un diviseur de clock utilise un compteur, c'est un composant logique de "base". Je pourrais te donnée la syntaxe mais je ne suis pas sur que ce soit très didactique. Il faudrait trouver un cours ou tuto pour acquérir ces bases.
Salutations
Dernière modification par micka_ch ; 23/08/2017 à 14h43.
Rebonjour,
Merci de votre aide, donc vous voulez dire qu'avec un simple programme d'un compteur de 0 jusqu'à 255, je peux avoir en sortie a l'oscilo un signal carré?
J'ai trouvé celui la sur internet mais c 4 bits, donc si je le modifie en 8 bits sa fera l'affaire?Code:library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Counter2_VHDL is port( Clock_enable: in std_logic; Clock: in std_logic; Reset: in std_logic; Output: out std_logic_vector(3 downto 0)); end Counter2_VHDL; architecture Behavioral of Counter2_VHDL is signal temp: std_logic_vector(3 downto 0); begin process(Clock,Reset) begin if Reset='1' then temp <= "0000"; elsif(Clock'event and Clock='1') then if Clock_enable='0' then if temp="1001" then temp<="0000"; else temp <= temp + 1; end if; else temp <= temp; end if; end if; end process; Output <= temp; end Behavioral;
pour un signal carré, pas besoin de compter, vu qu'il n'y a que 2 états, selon la configuration du AD7569
- en mode unipolaire (Vss=0V): '0000 0000' = 0 = niveau bas (0v) et '1111 1111' = 255 = niveau haut (1.25V ou 2.5V)
- en mode bipolaire (Vss=-5V): '1000 0000' = -128 = niveau bas (-1.25V ou -2.5V) et '0111 1111' = 127 = niveau haut (1.25V ou 2.5V) (dans le cas de ton exercice, c'est ce cas-là pour avoir un signal carré -2.5V/+2.5V)
cf page 15 de la notice du AD7569
Bonjour,
merci pour la réponse donc j'ai pensé à un truc du genre
Ps: je suis encore très très nulle en VHDL, il y'a dans ce code forcement des choses qui ne marche pas :/ je me suis inspiré d'un autre codeCode:library ieee; use ieee.std_logic_unsigned.all; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity SignalCarre is port ( RESET: in std_logic;-- le reset de la carte CLOCK: in std_logic; --horloge de la carte = 40Mhz ADDA_D: inout std_logic_vector(7 downto 0);-- data_bus bidirectionnel ADDA_WR: out std_logic; --Ordre d'ecriture ); end SignalCarre; architecture archi of SignalCarre is signal tmp: std_logic_vector(7 downto 0); signal count:integer:=0; begin CLOCK<=RESET; process(RESET) begin if ADDA_D'event and ADDA_D='1' then tmp<=tmp+1; --incrémentation end if; end process; ADDA_D<=tmp; if count<(128) then ADDA_WR<='1'; if count>(128) then ADDA_WR<='0'; if count>=(128) then count:=0; end if; end if; end if; end archi;
Je viens de comprendre l'idée du compteur, je n'avais pas bien lu ton message qui en parlait ^^.
Le principe est là, mais il faut dissocier:
- le compteur, qui pour moi est une variable qui s'incrémenterai à chaque front montant de l'horloge de la carte (la fonction rising_edge(CLOCK) permet la détection du front montant et ça doit être l'équivalent de ce que tu écris "Clock'event and Clock='1'")
- la valeur à envoyer à l'ADC ("10000000" pour le niveau bas et "01111111" pour le niveau haut dans la configuration de projet vhdl de l'autre sujet).
et ne pas oublier qu'il y a une "procédure" pour envoyer la valeur à l'ADC (on la trouve dans la notice de l'ADC, page 11 >
Pour générer un signal carré par rapport au clk système :
Code:use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity freq_div is port( Clock: in std_logic; Reset: in std_logic; Output: out std_logic); end freq_div; architecture Behavioral of freq_div is signal counter : std_logic_vector(8 downto 0); signal c_out : std_logic; begin process(Clock,Reset) begin if Reset='1' then counter <= "00000000"; c_out <= '0'; elsif(Clock'event and Clock='1') then if counter="*01111101" then -- valeur max = 125 counter<="00000000"; c_out <= NOT(c_out); else counter <= counter + 1; end if; end if; end process; Output <= c_out; end Behavioral;
Remarque personnelle : je préfère ne pas utiliser ieee.std_logic_arith et utiliser un integer pour counter. Ça évite les embrouilles.
Not only is it not right, it's not even wrong!
Ah donc là on en passe pas du tout par le convertisseur ?
et si on veut juste afficher un signal continue, on doit faire comment?
Alors je viens de tester en simulation ce que Micka_Ch, et je vois que c'est un signal continue jusqu'à ce que j'appuie sur le reset, c'étais pas sensé être un programme pour générer un signal carré? si je pige un peu le programme c'est si le reset est à '1' on recoit un zéro directement, sinon si le clock est à '1' et que le counter est a 127 donc il est remit a zéro sinon on incrémente le compteur, donc c'est bel est bien un signal carré que je dois voir non?
Bonjour,
Je n'avais tester mon code, c'était le principe du diviseur que je voulais montrer.
Probleme 1 : le reset est actif haut, c'est a dire qu'il faut commencé à 1 et après quelque ns le mettre a 0
Problème 2 : si tu veux voir output changer d'état, tu doit observer 125 périodes de clock, donc c'est normal que tu vois rien en 7 periode de clk
Salutations
mais en fait dès que je met le reset a 1, output se met a 0 directement, et quand reset et 0, c pareil pour output il est toujours a 0, au fait dès que la première impulsion de reset mets directement output à zero peut importe les nouveaux changement de reset
le reset, dans un circuit logique, sert a mettre le système dans un état déterminer au démarrage. Dans ce cas mettre a 0 counter et c_out.
Dans une simulation, on commence par reset le système et ensuite on applique les stimulus en entrée et on observe les sorties. Dans ce cas il n'y a pas de stimulus particulier si ce n'est le clock.
Voici ce que ca donne chez moi :
Après le reset, je compte 128 périodes de clock et out passe a 1, je compte 128 périodes et out repasse a 0, etc
A+
j'en ai marre de ce vhdl :/ je vais encore voir, merci vraiment pour votre patience :'(
j'aurais cassé mon ordi , une autre question, votre simulation elle est modesim ou juste le test bench de xilinx?
Comme je ne fais que du "système numérique" en loisir, j'utilise la version WEBPACK de Xillinx ISE et le simulateur fournit avec : ISim.
moi je suis entrains de faire avec le test bench et j'ai l'impression que je rentre des valeurs fausse c'est pour ca je n'ai pas du tous ce que vous m'avez montré, déja que mon reset ne veut pas commencer directement par 1 il est tjr à zéro puis 1, et j'arrive pas a avoir bcp de période du clock, finalemnt y'a as que le vhdl ( sa syntaxe) qui m'énerve, même son logiciel il est énervant!!!!!
En fait, l'objectif était de visualiser le signal carré sur l'oscilo, donc au lieu du " output" je met mon ADDA_A [7...0] mon bus de données du convertisseur? c'est tous ce dont j'ai besoin?
Si output = 0, ADDA_A = '1000 0000' = -128 = niveau bas
Si output = 1, ADDA_A = '0111 1111' = 127 = niveau haut
A traduire en VHDL
j'ai ajouté juste une ligne a la fin { ADDA_A<= "10000000" when Output= '0' else "01111111";
c'est ce qui m'a semblé le plus évident mais il y'a une erreur qui dit que output est une sortie et ne peut pas être lu!!!!! :'( :'(
Voici mon convertisseur, vous être sur que je ne touche pas aux autres entrée à part de bus de données?
Dans ton projet tu as 2 (ou plusieurs peut-être) composants, un qui gère les accès l'AD-7569 et l'autre qui génère le signal a sortie, le fameux carré. Une fois que tu testé ton générateur de carré, tu n'a "qu'a" les connectés correctement.
Dans l'idée quelque chose comme ceci, je n'ai pas testé, je n'ai pas la carte de dev correspondante.Code:-- declaration des differentes entites utilisees -- sequenceur gerant les acces au convertisseur component Seq_AdDa port( reset : in std_logic; -- reset global clock : in std_logic; -- 50 ns adda_st : out std_logic; -- ordre d'echantillonnage adda_cs : out std_logic; -- selection du convertisseur read_o : out std_logic; -- ordre de lecture enable_o : out std_logic; -- activer les donnees en sortie write_o : out std_logic; -- ordre d'ecrit. vers le conv. data_in : in std_logic_vector(7 downto 0); -- bus donnee x_data : out std_logic_vector(7 downto 0) -- donnee lue ); end component; -- declaration des signaux intermediaires signal dbus_in : std_logic_vector(7 downto 0); -- bus en entree signal read_n, writ_n, ecrit : std_logic; signal counter : std_logic_vector(7 downto 0); signal square : std_logic; signal v_dac : std_logic_vector(7 downto 0); begin -- interconnexions des 2 entites DO_CONV: Seq_AdDa port map(RESET, CLOCK, ADDA_ST, ADDA_CS, read_n, ecrit, writ_n, dbus_in, x_data); -- Génération d'un carré d'une période de Tclock*2*128 process(CLOCK,RESET) begin if RESET='1' then counter <= "00000000"; square <= '0'; elsif rising_edge(CLOCK) then if counter = "01111111" then counter <= "00000000"; square <= NOT(square); else counter <= counter + "1"; end if; end if; end process; v_dac <= "01111111" when square = '1' else "10000000"; -- lecture du bus de donnees process(B_DATA) begin dbus_in <= B_DATA; end process; -- positionnement du bus en lecture ou en ecriture suivant "ecr" ECRI_DAT: B_DATA <= v_dac when ecrit = '0' else "ZZZZZZZZ"; COM_RD <= read_n; COM_WR <= writ_n;
ca c'est ma tête en voyant le programme
Bonjour,
Encore moi cette fois ci quand je veux assigner mes pins de la carte aux entrées/sorties du programmes sa m'affiche ça, je n'ai pas la moindre idée pourquoi :/, qu'st ce qui à causer ce warning à votre avis??
il ne faut pas d'espaces dans le nom du chemin des fichiers, donc dans ton cas, renommer le dossier de ton bureau "Projet et stage" en "Projet_et_stage" par exemple
(on trouve la solution sur le site de Xilinx > https://www.xilinx.com/support/answers/29760.html
Merci Bcp oui finalement j'ai trouvé sur le forum de xilinx