J'apprends à utiliser un FPGA (carte de développement Papilio, qui a un xilinx spartan3e, en utilisant vhdl).
J'ai besoin de diviser une impulsion entrante par un nombre (codé en dur).
Je peux voir 3 options - à peu près, comme pseudocode (en utilisant 10 comptes comme exemple):
- Initialiser à 0, lors de l'augmentation du front montant en entrée de 1, par rapport à 10; s'ils sont égaux, remettre à 0 et déclencher l'impulsion de sortie
- Initialiser à 10, sur le front montant en entrée, diminuer de 1, comparer à 0; si elles sont égales, remettre à 10 et déclencher l'impulsion de sortie
- Initialiser à 9, mais assurez-vous qu'il y a au moins 1 bit "0" en tête, qui est mon bit de sortie. Sur front montant en entrée, diminuer de 1. Sur front montant du bit de sortie, réinitialiser.
Le rapport cyclique est sans importance.
L'un d'eux est-il meilleur que les autres? Y a-t-il une méthode encore meilleure à laquelle je n'ai pas pensé?
Existe-t-il une méthode "standard" qui donnera au compilateur les meilleures chances d'optimisation?
Réponses:
L'optimisation à ce niveau vous brisera le cœur. Le résultat pourrait changer en raison de la technologie du FPGA que vous utilisez, d'autres facteurs dans le FPGA, mais également en raison de facteurs hors de votre contrôle, y compris la valeur de nombre aléatoire de l'installateur.
Cela dit, je pense que l'option 3 sera la meilleure. Les options 1 et 2 ont un comparateur / porte OU passant entre les compteurs afin qu'il puisse signaler que le nombre cible a été atteint. L'option 2 peut être légèrement plus rapide que 1, car tout peut être directement OU combiné sans aucun onduleur, mais là encore, vous rencontrez de petites différences technologiques où elle peut être plus rapide vers AND ou XOR.
L'option 3 ignore la comparaison pour le faible coût d'un bit supplémentaire dans le compteur. Cela devrait en valoir la peine, sauf si vous êtes sévèrement limité en tongs.
Un fait amusant sur les compteurs est qu'ils ont tendance à être regroupés dans une taille spécifique au périphérique dans un bloc logique, et vous verrez le timing changer plus que prévu si ce bit supplémentaire vous pousse hors de ce groupe.
la source
Une autre option serait d'initialiser le compteur à 6 (= 2 4 - 10), de compter, puis de le réinitialiser lorsque la sortie de report s'active (c'est-à-dire que les FF sont tous des unités).
L'avantage de cela est qu'il ne nécessite pas de FF supplémentaire, et de nombreux FGPA ont une logique auxiliaire dédiée pour accélérer ce type d'opération de report dans un circuit compteur ou additionneur.
la source
Dépend. Par exemple: le délai de propagation de bascule pour 0 → 1 et 1 → 0 peut être différent, et donc les délais de transition d'un compteur pour 000 → 001 et 001 → 000 peuvent être légèrement différents. Il peut être supérieur ou inférieur, selon la technologie cmos utilisée dans FPGA. Vous devez donc synthétiser et découvrir lequel a les meilleures performances de synchronisation.
la source
Du point de vue de l'auteur d'un compilateur: si vous utilisez
integer
, la représentation interne n'est pas définie et le compilateur est libre de choisir l'implémentation la plus efficace.Si vous forcez une représentation interne particulière, l'optimiseur tentera toujours de l'améliorer, mais il commencera à partir d'un point de vue légèrement pire.
À moins que vous ne connaissiez la structure interne, les ressources allouées à une autre logique (de nombreux FPGA ont une logique multiplate-add à virgule flottante dédiée que vous pouvez également utiliser pour implémenter un compteur si vous avez des unités restantes) et êtes entièrement sûr que vous ne commuterez pas à un modèle différent, la réponse est "n'y pensez pas".
la source