Division de points fixes dans Verilog pour Spartan 6

8A52

Division de points fixes dans Verilog pour Spartan 6


Je développe un noyau sur Spartan 6 qui doit faire des divisions comme 1 / 6,2 / 4 etc … donc les valeurs sont toujours entre 0 et 1. Comme je n’ai pas besoin de la précision de la virgule flottante, je veux utiliser un diviseur à virgule fixe car la division est coûteuse. J’ai trouvé quelques diviseurs sur opencores.org mais tous peuvent résoudre des problèmes de division normaux comme 4 / 2,8 / 4, etc … mais ne peuvent pas faire 1/6 des opérations. Quelqu’un peut-il indiquer un séparateur approprié pour mon application

Merci

Joe Hass

Les diviseurs sont-ils constants ou varient-ils?

Dave Tweed ♦

De quel type de bande passante (résultats par seconde) et de latence votre application a-t-elle besoin? J’ai développé un diviseur en pipeline qui peut fournir un résultat par horloge à 150 MHz, mais c’est parce que je devais calculer 1024 facteurs d’échelle pendant l’intervalle de suppression verticale d’un flux vidéo HD. Si vous n’avez pas besoin de ce type de bande passante, il existe d’autres approches qui nécessitent moins de ressources. Mon diviseur est en VHDL; il pourrait être traduit en Verilog (mais pas gratuitement).

Dave Tweed ♦

@JoeHass: Si les diviseurs sont des constantes, vous n’avez pas du tout besoin d’un diviseur; vous multipliez simplement par 1 / x à la place.

Joe Hass

@DaveTweed: Oui, c’est exactement pourquoi j’ai demandé. J’ai appris à ne jamais rien prendre pour acquis sur stackexchange.

Dave Tweed ♦

En fait, même si les diviseurs varient, le calcul 1 / x est une approche très viable si vous n’avez pas besoin d’un résultat par horloge. La méthode Newton-Rhapson n’a besoin que d’un multiplicateur pour calculer 1 / x en quelques horloges, puis une multiplication supplémentaire vous permet d’obtenir votre quotient. Il existe de nombreux ordinateurs commerciaux à travers l’histoire qui ont utilisé exactement cette méthode.

Réponses


 Joe Hass

Vous dites que vous avez trouvé des séparateurs qui font une division « normale ». La division à virgule fixe est une division normale, sauf que le dividende doit être augmenté (décalé vers la gauche). Déplacez le dividende vers la gauche 8 places (multipliez par 256), puis faites une division normale. Le résultat fractionnaire en virgule fixe est égal au résultat entier de la division, divisé par 256. Donc, si vous voulez calculer 1/6, vous diviserez réellement (1 * 256) / 6, qui est 42. Le résultat réel est donc 42/256 = 0,1640625, ce qui est raisonnablement proche de la vraie valeur de 0,1666 … On dirait normalement que ce résultat est un nombre à virgule fixe avec 8 bits à droite de la virgule décimale. Si vous souhaitez une plus grande précision, utilisez un facteur d’échelle plus grand.

8A52

Mon problème est que si je fais 1/4 avec ce diviseur, je reçois zéro comme réponse. En suivant votre méthode, si je fais 256/4, j’obtiens 64. Encore une fois, si je fais 64/256, j’obtiens zéro car toute division avec un numérateur inférieur au dénominateur entraîne zéro. Que faire ? 🙁

Joe Hass

Vous devez augmenter le dividende. Si vous voulez faire une division entière et que le résultat représente une fraction, vous devez au préalable multiplier le dividende par une puissance de 2.

8A52

Un peu d’exemple de code m’aiderait beaucoup. J’ai essayé et essayé, mais sans succès. Aidez-moi, s’il vous plaît

Joe Hass

Si vous effectuez des divisions entières, il est impossible d’obtenir un résultat qui n’est pas un entier. Le concept clé est la façon dont vous interprétez cet entier. Dans votre exemple ci-dessus, vous n’essaieriez pas de diviser 64/256, vous reconnaîtriez simplement que le résultat est une fraction multipliée par l’entier 256.

 

#de, #pour, 6, dans, division, fixes, points, Spartan, Verilog

 

google

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *