2016-02-20 3 views
0

Je vais fou d'essayer de le faire fonctionner mais rien été sur ce point pour les 6 dernières heures et n'a toujours pas le résoudre:/Pourquoi mon code VHDL pour générer un signal VGA ne fonctionne pas

si ce module supérieur

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

-- Uncomment the following library declaration if using 
-- arithmetic functions with Signed or Unsigned values 
--use IEEE.NUMERIC_STD.ALL; 

-- Uncomment the following library declaration if instantiating 
-- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 

entity Test is 
    Port (CLKI : in STD_LOGIC; 
     HSO : out STD_LOGIC; 
     VSO : out STD_LOGIC; 
     RO,GO,BO : out STD_LOGIC); 
end Test; 

architecture Behavioral of Test is 
    component CLK_25Mhz_Divider 
    Port (CLK : in STD_LOGIC; 
      CLK_OUT : out STD_LOGIC); 
    end component; 

    component VGA_Sync 
    Port (CLK : in STD_LOGIC; 
      HS : out STD_LOGIC; 
      VS : out STD_LOGIC; 
      R,G,B : out STD_LOGIC); 
    end component; 

    signal CLKBE: STD_LOGIC; 

begin 

    CLK_Divider_1: CLK_25Mhz_Divider port map (CLK => CLKI, 
               CLK_OUT => CLKBE); 

    VGA_S1: VGA_Sync port map (CLK => CLKBE, 
      HS => HSO, 
      VS => VSO, 
      R => RO, 
       G => GO, 
       B => BO); 

end Behavioral; 

le diviseur d'horloge

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

-- Uncomment the following library declaration if using 
-- arithmetic functions with Signed or Unsigned values 
--use IEEE.NUMERIC_STD.ALL; 

-- Uncomment the following library declaration if instantiating 
-- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 

entity CLK_25MHz_Divider is 
    Port (CLK : in STD_LOGIC; 
      CLK_OUT : out STD_LOGIC); 
end CLK_25MHz_Divider; 

architecture Behavioral of CLK_25MHz_Divider is 

BEGIN 
    PROCESS(CLK) 
      VARIABLE COUNT : INTEGER:=0; 
      VARIABLE TEMP : STD_LOGIC:='0'; 
      BEGIN 
       IF RISING_EDGE(CLK)THEN 
        COUNT:=COUNT+1; 
        IF COUNT=2 THEN 
          TEMP:=NOT TEMP; 
          COUNT:=0; 
        END IF; 
       END IF; 
       CLK_OUT<=TEMP; 
       END PROCESS; 
end Behavioral; 

le module de génération de signal VGA

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

-- Uncomment the following library declaration if using 
-- arithmetic functions with Signed or Unsigned values 
--use IEEE.NUMERIC_STD.ALL; 

-- Uncomment the following library declaration if instantiating 
-- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 

entity VGA_Sync is 
    Port (CLK : in STD_LOGIC; 
      HS : out STD_LOGIC; 
      VS : out STD_LOGIC; 
      R,G,B : out STD_LOGIC); 
end VGA_Sync; 

architecture Behavioral of VGA_Sync is 

begin 

    process(CLK) 

    Variable countH : Integer := 0; 
    Variable countV : Integer := 0; 

    begin 
    if (CLK'EVENT and CLK = '1') then 

     if countH < 800 then 
      countH := countH + 1; 
     else 
      countH := 0; 
      if countV < 500 then 
       countV := countV + 1; 
     else 
       countV := 0; 
      end if; 
     end if; 

     if countH >= 16 and countH < 112 then 
      HS <= '0'; 
     else 
      HS <= '1'; 
     end if; 

     if countV >= 10 and countV < 12 then 
      VS <= '0'; 
     else 
      VS <= '1'; 
     end if; 

     if (countH < 160) or (countV < 45) then 
      R <= '0'; 
      G <= '0'; 
      B <= '0'; 
     else 
      R <= '1'; 
      G <= '0'; 
      B <= '1'; 
     end if; 
    end if; 
end process;  
end Behavioral; 

alors dites-moi vos réflexions sur ce qui ne va pas avec le code

+0

Btw la résolution que je vise est 640x480 – Mostafa

+0

S'il vous plaît nettoyer votre question. Vous avez posté 'vga_sync' deux fois. Un composant de niveau supérieur ainsi qu'un testbench sont manquants. Et quelle est l'erreur (message)? Et supprimez les lignes de commentaires inutiles. –

+0

désolé de poster deux fois vga_sync je l'ai réparé maintenant. ce n'est pas que j'obtiens une erreur mon code ne me donne pas d'erreurs de syntaxe mais quand je connecte la carte à un écran rien n'apparaît quand la couleur des pixels devrait changer en magenta. J'ai fait un banc d'essai mais ça ne vaut pas la peine d'écrire ici car c'est seulement une horloge et le banc d'essai n'a rien montré de mal, je pourrais l'inclure avec quelques captures d'écran de la forme d'onde si vous voulez. – Mostafa

Répondre

1

Parce que vous ne l'avez pas décrire réellement le problème et parce que j'avais un banc d'essai pour un générateur de vga cadencé 25 MHz qui ne doit changer le type de r, g et b, je courais vous sync_vga contre le banc d'essai:

library ieee; 
use ieee.std_logic_1164.all; 

entity vga_sync_tb is 
end entity; 

architecture foo of vga_sync_tb is 
    signal clk: std_logic := '0'; 
    signal hs:  std_logic; 
    signal vs:  std_logic; 
    signal r,g,b: std_logic; 
begin 
DUT: 
    entity work.vga_sync 
     port map (
      clk => clk, 
      hs => hs, 
      vs => vs, 
      r => r, 
      g => g, 
      b => b 
     ); 
CLOCK: 
    process 
    begin 
     wait for 20 ns; -- clock period 25 MHz = 40 ns; 
     clk <= not clk; 
     if now > 20 ms then -- one frame time plus a bit 
      wait; 
     end if; 
    end process; 
end architecture; 

Il a donné un taux de synchronisation verticale d'environ 60 Hz:

sync_vga_tb_full.png

Zoom et de mesure entre deux bords SH représente une fréquence horizontale d'environ 31,17 KHz.

Vous avez des intervalles de suppression horizontale et verticale et vos R, G et B font ce que dit votre code. Cela sorte de sorte que le séparateur d'horloge ou quelque chose de la plate-forme se rapproche.

Comme un banc d'essai pour l'horloge est simple:

library ieee; 
use ieee.std_logic_1164.all; 

entity clock_tb is 
end entity; 

architecture foo of clock_tb is 
    signal clk:  std_logic := '0'; 
    signal clk25: std_logic; 
begin 
DUT: 
    entity work.clk_25mhz_divider 
     port map (
      clk => clk, 
      clk_out => clk25 
     ); 
CLOCK: 
    process 
    begin 
     wait for 10 ns; -- half the period of 50 MHz 
     clk <= not clk; 
     if now > 130 ns then 
      wait; 
     end if; 
    end process; 
end architecture; 

Il démontre la réponse de Martin Zabel:

clock_tb.png

Que votre division par deux divise en fait par quatre. donnant une période de 80 ns (12,5 MHz). Cela démontre l'utilité de la simulation et, en simulation, il peut être utile d'utiliser des signaux plutôt que des variables sans historique. Les variables n'ont pas de forme d'onde de sortie projetée et le simulateur doit attacher du code supplémentaire pour les afficher dans une forme d'onde.

L'augmentation des performances de simulation en utilisant des variables au lieu de signaux est échangée pour la capacité de les afficher et il n'y a pas de distinction intéressante dans la synthèse.

+0

Merci pour l'explication. c'est quelque chose que je garderais à l'esprit à l'avenir. Je ne suis pas très versé dans le VHDL car je ne l'utilise pas souvent mais je commence à comprendre. – Mostafa

+0

@Mostafa: si vous apprenez une chose à partir de cette excellente réponse, que ce soit ceci: il ne prend pas six heures pour écrire un banc d'essai et simuler votre conception. –

+0

Je dois admettre que cette réponse est meilleure que la mienne car elle démontre le test des sous-modules. Donc, +1. Dommage, j'aurais dû savoir ça. –

1

De commentaires ci-dessous question:

à cette résolution que je devrais utiliser 25Mhz donc je en utilisant l'horloge à bord qui est de 50 Mhz et en divisant en utilisant le module diviseur d'horloge. - Mostafa

Votre diviseur d'horloge divise la fréquence d'entrée de 4 au lieu de 2. Vous pouvez basculer TEMP tous les deux cycles de CLK qui est CLKI du module supérieur. Donc, un cycle complet de CLK_OUT prend 4 cycles de l'horloge d'entrée.

Pour diviser par deux, vous devez activer TEMP chaque cycle d'horloge de l'horloge d'entrée:

architecture Behavioral of CLK_25MHz_Divider is 
BEGIN 
    PROCESS(CLK) 
      VARIABLE TEMP : STD_LOGIC:='0'; 
    BEGIN 
     IF RISING_EDGE(CLK)THEN 
      TEMP:=NOT TEMP; 
     END IF; 
     CLK_OUT<=TEMP; 
    END PROCESS; 

end Behavioral; 

A partir de TEMP = '0', il permet de passer entre « 1 » au premier front montant de CLK. Au deuxième front montant, TEMP bascule à '0' et au troisième front montant revient à '1'. La durée entre le premier et le troisième front montant de l'horloge d'entrée de 50 MHz est de 40 ns, ce qui fait une fréquence de 25 MHz pour l'horloge de sortie.

+0

Ça marche !!!!!! TY monsieur :) Je ne peux pas vous remercier assez. – Mostafa