IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VHDL Discussion :

[Débutante] VGA sur la carte Spartan-3


Sujet :

VHDL

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 39
    Points : 22
    Points
    22
    Par défaut [Débutante] VGA sur la carte Spartan-3
    Bonjour à tous

    Je suis débutante en programmation en VHDL. Actuellement, je travaille sur la carte Spartan-3. J'ai trouvé cet exemple de code sur le net :

    http://www.derepas.com/fabrice/hard/

    Pour l'exemple de "squares", je n'ai pas compris cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    process (clk25)
    begin
    if clk25'event and clk25 = '1' then
    if (horizontal_counter >= "0010010000" ) -- 144
    and (horizontal_counter < "1100010000" ) -- 784
    and (vertical_counter >= "0000100111" ) -- 39
    and (vertical_counter < "1000000111" ) -- 519
    then
    red_out <= horizontal_counter(3)
    and vertical_counter(3);
    green_out <= horizontal_counter(4)
    and vertical_counter(4);
    blue_out <= horizontal_counter(5)
    and vertical_counter(5);
    else
    red_out <= '0';
    green_out <= '0';
    blue_out <= '0';
    end if;
    if (horizontal_counter > "0000000000" )
    and (horizontal_counter < "0001100001" ) -- 96+1
    then
    hs_out <= '0';
    else
    hs_out <= '1';
    end if;
    if (vertical_counter > "0000000000" )
    and (vertical_counter < "0000000011" ) -- 2+1
    then
    vs_out <= '0';
    else
    vs_out <= '1';
    end if;
    horizontal_counter <= horizontal_counter+"0000000001 ";
    if (horizontal_counter="110010000 0") then
    vertical_counter <= vertical_counter+"0000000001";
    horizontal_counter <= "0000000000";
    end if;
    if (vertical_counter="1000001001" ) then
    vertical_counter <= "0000000000";
    end if;
    end if;
    end process;
    ou, plus précisément, je n'ai pas compris l'utilité de " horizontal-counter" et "vertical_counter".

    Je me demande si quelqu'un peut m'expliquer ce code.

    Merci d'avance

  2. #2
    Membre régulier
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 108
    Points : 97
    Points
    97
    Par défaut
    C'est peut-être un peu tard comme début de réponse mais vu que je viens tout juste de commencer la dev FPGA, de plus avec un SPARTAN 3 moi aussi (un carte de dev Spartan-3E XC3S500E-PQG208 avec un écran LCD de 4.3 pouces intégré) et qu'il faut bien que je commence par quelque chose, la gestion d'un buffer graphique est typiquement le genre de truc que je voudrais y gérer => donc ça tombe bien

    Au tout début, il y a ce test qui doit gérer l'affichage en 25/50 Hz et/ou la prise en compte si c'est une ligne paire ou impaire pour le tramage ou qqchose du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if clk25'event and clk25 = '1' then

    Dans la seconde partie, celà consiste à ne prendre en compte que la partie qui sera réellement affichée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (horizontal_counter >= "0010010000" ) -- 144
    and (horizontal_counter < "1100010000" ) -- 784
    and (vertical_counter >= "0000100111" ) -- 39
    and (vertical_counter < "1000000111" ) -- 519
    784 - 144 = 640
    519 - 39 = 480

    Ca permet donc n'envoyer un signal video que lorsque le spot video est bien dans la "fenêtre" affichable de l'écran (soit ici 640x480)

    En passant, on voit qu'il y 144 cycles en début de ligne où il ne faut pas envoyer de signal video
    (ça doit être le temps que met le spot lumineux pour passer de la fin d'une ligne au début d'une autre ou qqchose comme ça)

    On y voit de la même façon qu'il doit y avoir 39 cycles de plus quand le spot lumineux repasse de la dernière ligne à la première ligne pour commencer la génération d'une nouvelle trame
    (ça me parait court mais vu qu'il y a les 144 cycles en plus pour revenir du dernier pixel d'une ligne au premier de la ligne suivante et que le spot remonte en diagonale du dernier pixel de la dernière ligne au premier pixel de la première ligne, ça doit sûrement faire ces 144+35 cycles)


    Quand on est bien dans le zone affichable, on envoie au spot lumineux les valeurs des composantes primaires Rouge, Vert et Bleu du pixel à afficher
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    red_out <= horizontal_counter(3)
    and vertical_counter(3);
    green_out <= horizontal_counter(4)
    and vertical_counter(4);
    blue_out <= horizontal_counter(5)
    and vertical_counter(5);
    Sinon on n'envoie aucune couleur (cf. composantes primaires Rouge, vert et Bleu à zéro) au spot lumineux qui affiche le pixel sur l'écran
    (cf. c'est du noir donc on ne risque pas de voir le faiseau lumineux passer du dernier pixel au premier pixel d'une ligne ou de l'image)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    red_out <= '0';
    green_out <= '0';
    blue_out <= '0';
    Cette partie doit assez sûrement gérer la synchronisation horizontale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    f (horizontal_counter > "0000000000" )
    and (horizontal_counter < "0001100001" ) -- 96+1
    then
    hs_out <= '0';
    else
    hs_out <= '1';
    end if;
    (cf. ça envoie un 0 sur la patte hs_out quand on est sur la synchro horizontale [qui dure 97 cycles à première vue], et sinon un 1 le reste du temps)

    Et celle-ci la synchro verticale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (vertical_counter > "0000000000" )
    and (vertical_counter < "0000000011" ) -- 2+1
    then
    vs_out <= '0';
    else
    vs_out <= '1';
    end if;
    (cf. ça envoie un 0 sur la patte vs_out, quand on est sur la synchro horizontale [qui dure sur 3 lignes à première vue], et sinon un 1 le reste du temps)

    Cette partie gère l'incrémentation d'un pixel à droite pour l'affichage de chaque pixel successif d'une même ligne, de la remise à 0 de l'indice du pixel quand on est arrivé à la fin de la ligne afin que la prochaine occurence pointe bien sur le premier de la ligne suivante + incrémentation du compteur de ligne pour que la prochaine occurence pointe bien sur la ligne suivante (qui commencera 144 cycle après car il faut que le faisceau lumineux ai le temps de repasser de la fin au début de ligne, mais ça c'est déjà géré dans la seconde partie expliquée plus haut) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    horizontal_counter <= horizontal_counter+"0000000001 ";
    if (horizontal_counter="110010000 0") then
    vertical_counter <= vertical_counter+"0000000001";
    horizontal_counter <= "0000000000";
    end if;
    Et enfin, celle ci permet de réinitialiser le compteur de ligne quand on est arrivé à la dernière, afin de pouvoir commencer l'affichage d'une nouvelle trame
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (vertical_counter="1000001001" ) then
    vertical_counter <= "0000000000";
    J'y ai peut-être fait quelques petites erreurs d'interprétations, mais ne pense pas être très loin de la réalité

Discussions similaires

  1. Réponses: 9
    Dernier message: 22/02/2011, 15h30
  2. Réponses: 0
    Dernier message: 29/06/2009, 20h52
  3. [Débutante] Extrapolation de point sur une carte
    Par chlorure007 dans le forum MATLAB
    Réponses: 5
    Dernier message: 16/12/2008, 15h48
  4. Réponses: 9
    Dernier message: 02/04/2008, 20h44
  5. [Débutant] Connexion sur une machine distante protégée
    Par arthix dans le forum Développement
    Réponses: 3
    Dernier message: 28/08/2003, 09h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo