Je m'enseigne moi-même le Verilog. Le livre que je suis en train de suivre indique dans les chapitres d'introduction que, pour effectuer la division, nous utilisons l'opérateur '/' ou l'opérateur '%'. Dans les chapitres suivants, il est dit que la division est trop complexe pour Verilog et ne peut pas être synthétisée. Pour effectuer la division, elle introduit un algorithme long.
Donc je suis confus, Verilog ne peut-il pas gérer une division simple? l'opérateur/est-il inutile?
Tout dépend du type de code que vous écrivez.
Si vous écrivez du code que vous souhaitez synthétiser, que vous souhaitez intégrer un FPGA ou un ASIC, vous ne souhaitez probablement pas utiliser les opérateurs de division ou modulo. Lorsque vous mettez un opérateur arithmétique dans RTL, le synthétiseur installe un circuit pour effectuer le travail; Un additionneur pour +
& -
; Un multiplicateur pour *
. Lorsque vous écrivez /
, vous demandez un circuit diviseur, mais un circuit diviseur est une chose très complexe. Il faut souvent plusieurs cycles d'horloge et peut utiliser des tables de consultation. C'est beaucoup demander à un outil de synthèse d'inférer ce que vous voulez quand vous écrivez a / b
.
(Évidemment, diviser par une puissance de 2 est simple, mais vous utiliseriez normalement les opérateurs de décalage)
Si vous écrivez un code que vous ne voulez pas synthétiser, cela fait partie d'un banc de test par exemple, alors vous pouvez utiliser la division tout ce que vous voulez.
Donc, pour répondre à votre question, l'opérateur /
n'est pas inutile, mais vous devez savoir où et pourquoi vous l'utilisez. Il en va de même pour *
, mais dans une moindre mesure. Les multiplicateurs sont assez chers, mais la plupart des synthétiseurs sont capables de les déduire.
Vous devez penser au matériel.
Lorsque vous écrivez un <= b/c, vous dites à l’outil de synthèse "Je veux un diviseur qui puisse fournir un résultat à chaque cycle de l’horloge et qui n’a pas de registre de ligne à tirette intermédiaire".
Si vous travaillez sur le circuit logique nécessaire pour créer ce processus, il est très complexe, en particulier pour les nombres de bits plus élevés. En général, les FPGA ne disposent pas de blocs matériels spécialisés pour la division. Ils devraient donc être implémentés à partir de ressources logiques génériques. Il est susceptible d'être à la fois gros (beaucoup de luts) et lent (faible fmax).
Certains synthétiseurs peuvent quand même le mettre en œuvre (après une recherche rapide, il semblerait que ce soit une volonté de notre part), d’autres ne l’ennuieront pas car ils ne pensent pas que cela soit très utile dans la pratique.
Si vous divisez par une constante et pouvez vivre avec un résultat approximatif, vous pouvez faire des tours avec des multiplicateurs. Prenez l'inverse de ce que vous voulez diviser par, multipliez-le par une puissance de deux et arrondissez au nombre entier le plus proche.
Ensuite, dans votre Verilog, vous pouvez mettre en oeuvre votre division approximative par multiplication (ce qui n’est pas trop coûteux sur les systèmes FPGAS modernes) suivie d’un décalage (le décalage d’un nombre fixe de bits est essentiellement libre dans le matériel). Assurez-vous de laisser suffisamment de bits pour le résultat intermédiaire.
Si vous avez besoin d'une réponse exacte ou si vous devez diviser par quelque chose qui n'est pas une constante prédéfinie, vous devrez choisir le type de diviseur que vous souhaitez. SI votre débit est faible, vous pouvez utiliser une approche basée sur une machine à états qui effectue une division tous les n cycles d'horloge. Si votre débit est élevé et que vous avez les moyens financiers de disposer de la zone de périphérique, une approche en pipeline qui effectue une division par cycle d'horloge (mais nécessite plusieurs cycles pour que le résultat circule) peut être plus appropriée.
Les vendeurs d’outils fournissent souvent des blocs pré-fabriqués (altera les appelle des mégafonctions) pour ce genre de choses. L'avantage de ces solutions est que le fournisseur d'outils les aura probablement soigneusement optimisées pour le périphérique. L'inconvénient est qu'ils peuvent amener le verrouillage du fournisseur. Si vous souhaitez passer à un autre fournisseur de périphérique, vous devrez probablement échanger le bloc et le bloc avec lequel vous l'échanger peut présenter des caractéristiques différentes.
Donc je suis confus. verilog ne peut-il pas gérer une division simple? est l'opérateur/ inutile?
La spécification de synthèse Verilog (IEEE 1364.1) indique que tous les opérateurs arithmétiques avec des opérandes entiers doivent être pris en charge, mais que personne ne suit cette spécification. Certains outils de synthèse peuvent effectuer une division entière, mais d’autres le rejetteront (je pense que XST le fait toujours) car la division combinatoire est généralement très inefficace. Les implémentations multi-vélos sont la norme mais elles ne peuvent pas être synthétisées à partir de '/'.
La division et le modulo ne sont jamais "simples". Évitez-les si vous pouvez le faire, par exemple à travers des masques de bits ou des opérations de décalage. En particulier, un diviseur variable est vraiment compliqué à implémenter dans le matériel.
"Verilog the language" gère très bien la division et le modulo - lorsque vous utilisez un ordinateur pour simuler votre code, vous avez un accès complet à toutes ses capacités.
Lorsque vous synthétisez votre code sur une puce particulière, il existe des limites. Les limitations ont tendance à être basées sur ce que le fournisseur d'outils considère comme "raisonnable" plutôt que sur ce qui est réalisable.
Autrefois, la division par autre chose qu'une puissance de deux était jugée peu judicieuse pour le silicium, car il prenait beaucoup de place et fonctionnait très lentement. Pour le moment, certains synthétiseurs créent pour vous des circuits "diviser par une constante".
À l'avenir, je ne vois aucune raison pour que le synthétiseur ne crée pas de séparateur (ou utilise un séparateur figurant dans les blocs DSP d'une future architecture potentielle). Reste à savoir si cela va rester ou non, mais soyez témoin de la progression des multiplicateurs (de "seulement des puissances de deux" à "une entrée constante" à "une mise en œuvre complète" en quelques années à peine)
La division utilisant '/' est possible dans Verilog. Mais ce n'est pas un opérateur synthétisable. Il en va de même pour la multiplication utilisant '*'. Certains algorithmes permettent d'effectuer ces opérations dans Verliog, et ils sont utilisés si le code doit être synthétisable. c'est à dire. si vous avez besoin d’un matériel équivalent.
Je ne connais aucun algorithme pour la division, mais pour la multiplication, j'ai utilisé l'algorithme de Booth.