2012-06-18 22 views
3

J'essaie de ralentir une fréquence de 50 MHz jusqu'à 25,175 MHz pour une utilisation avec un contrôleur VGA. J'ai déjà un diviseur d'horloge, mais j'ai du mal à ralentir l'horloge chaque fois que la division résultante de la vitesse d'horloge actuelle et la vitesse d'horloge désirée n'est pas un nombre entier. C'EST À DIRE. 50000000/25175000 ~ 1,98. Le diviseur d'horloge se compile et s'exécute, mais ne génère rien si la division est un nombre décimal. Voici mon code:Diviseur d'horloge VHDL avec décimales

LIBRARY IEEE; 
    USE IEEE.STD_LOGIC_1164.ALL; 

    ENTITY Clockdiv IS PORT (
     Clkin: IN STD_LOGIC; 
     Clk: OUT STD_LOGIC); 
    END Clockdiv; 

    ARCHITECTURE Behavior OF Clockdiv IS 
     CONSTANT max: INTEGER := 50000000/25175000; 
     CONSTANT half: INTEGER := max/2; 
     SIGNAL count: INTEGER RANGE 0 TO max; 
    BEGIN 
     PROCESS 
     BEGIN 
      WAIT UNTIL Clkin'EVENT and Clkin = '1'; 

      IF count < max THEN 
       count <= count + 1; 
      ELSE 
       count <= 0; 
      END IF; 

      IF count < half THEN 
       Clk <= '0'; 
      ELSE 
       Clk <= '1'; 
      END IF; 
     END PROCESS; 
    END Behavior; 

Je recherche google et trouvé en utilisant le type de données REAL vous permettra d'utiliser les décimales, mais quand je l'ai changé les variables que je utilise pour réaux, Quartus me donne l'erreur: Error (10414): VHDL Unsupported Feature error at Clockdiv.vhd(12): cannot synthesize non-constant real objects or values . Puis, si je change "count" en un type CONSTANT, j'obtiens l'erreur: Error (10477): VHDL error at Clockdiv.vhd(18): name "count" must represent signal.

Est-ce que quelqu'un sait comment je peux ralentir une horloge à 25,175 MHz? Aussi, quelqu'un sait-il comment ralentir une horloge afin que le compilateur soit satisfait de la division résultante étant une valeur décimale?

Merci

+0

Sur quelle carte travaillez-vous? Il pourrait venir avec un gestionnaire d'horloge numérique (DCM) qui pourrait offrir un meilleur résultat de division et une implémentation plus simple.Je sais que les cartes Spartan 3a de Xilinx ont les –

+0

J'utilise une carte Altera DE1 pour cela. Le FPGA sur cette carte a 4 PLL, mais pour autant que je sache, il n'y a pas de gestionnaire d'horloge numérique comme Paul Seeb l'a mentionné. Donc, je suppose que ma prochaine question est, comment puis-je profiter d'une PLL dans Quartus à utiliser comme le diviseur d'horloge? –

+0

Si vous avez des PLL, vous pouvez faire des horloges de fréquence supérieure/inférieure aussi longtemps que le matériel peut atteindre la fréquence désirée. Je pense que la plupart des DCM le font de cette façon. Par exemple, doubler la vitesse d'horloge est réalisé par XORing votre horloge avec et 90deg signal d'horloge déphasé –

Répondre

4

Reals sont, en général, pas synthétisable, vous aurez donc besoin de trouver une solution à base entière.

Ce rapport est assez difficile car il est presque 2: 1, mais pas tout à fait. La plupart des circuits diviseurs d'horloge basés sur les bords ne fonctionnent que sur un bord de l'horloge d'origine, donc le ratio le plus bas que vous pouvez diviser est de 2. Dans ce cas, vous devrez travailler sur les deux bords de l'horloge.

Une fois que vous avez obtenu cela, vous devez avoir un compteur qui s'incrémente par le dénominateur de votre ratio et est-il sur le numérateur puis sortie un bord de l'horloge.

PROCESS 
    BEGIN 
     WAIT UNTIL Clkin'EVENT; 

     IF count < max THEN 
      count <= count + DENOMINATOR; 
     ELSE 
      count <= 0; 
     END IF; 

     IF count > NOMINATOR THEN 
      Clk <= ~Clk; 
     END IF; 
    END PROCESS; 

Pour ce ratio, je pense que la plus petite façon de le représenter est 2000/1007. Le problème avec ceci est que vous obtiendrez une horloge qui est fondamentalement 25MHz, mais de temps en temps (chaque itérations 2000/7) vous aurez un avantage supplémentaire. Ce ne sera pas une horloge 25.175MHz. Obtenir 25,175 MHz à partir de 50 MHz est impossible sans PLL.

2

J'ai écrit beaucoup de contrôleurs VGA, et l'utilisation d'une horloge à 25 MHz n'a jamais posé de problème. Si vous voulez absolument vous rapprocher, votre FPGA a probablement un gestionnaire d'horloge quelconque (je ne connais que les appareils Xilinx), qui vous permettra de synthétiser une horloge de sortie en multipliant et en divisant une horloge d'entrée. De même, si vous utilisez des horloges dérivées/synchronisées (les horloges où vous définissez directement la valeur d'un processus) fonctionnera probablement dans ce cas, cela peut entraîner de nombreux problèmes difficiles à déboguer. Une meilleure solution consiste à générer l'horloge, puis à tout exécuter sur la même horloge (rapide). Et une dernière chose, bien qu'il s'agisse probablement d'une question de style préféré, mais j'utilise généralement des instructions de processus cadencées au lieu des instructions WAIT (illustrées ci-dessous avec déclenchement sur front montant, réinitialisation synchrone et activation de l'horloge). Je le trouve plus clair à lire et à comprendre, et moins enclin à écrire des constructions non synthétisables telles que wait for 10ns;, ou des déclarations avec plusieurs WAIT s.

process(clk) 
begin 
    if(rising_edge(clk)) then 
     if(sync_reset = '1') then 
      --Reset logic 
     elsif(clk_enable = '1') then 
      --Actual functionality 
     end if; 
    end if; 
end process; 
+0

Les instructions d'attente sont absolument synthétisables. Il peut y avoir des cas où le synthétiseur ne peut pas implémenter ce que vous avez demandé (par exemple, vous déduisez des registres sensibles aux deux bords, ce qui serait un problème pour le code dans ma réponse), mais l'utilisation du PO est bonne outils (Synopsys Design-Compiler pour un). –

+0

Assez juste, j'ai modifié ma réponse. Je suis probablement influencé par cela dans 90% des cas où je l'ai vu utilisé, il a été par des gens demandant pourquoi leur code «attendre xxx ns;» ne peut pas être synthétisé;) – sonicwave

+0

Ahhh, d'accord. "attendez xxx ns;" n'a pas l'espoir d'être synthétisé. –