Une fonction Modulo synthètisable

Comme il a été expliqué dans l’article précédent, la fonction VHDL « MOD » correspondant au calcul du modulo n’est pas reconnue comme synthètisable dans les outils courants comme ISE. Il est donc nécessaire de créer une telle fonction à partir d’autres fonctions qui le sont. Nous avons choisi la multiplication qui est parfaitement réalisée par un bloc DSP.

On limite le problème à des nombres non signés. Le diviseur est en principe une constante de N2 bits, le dividende un nombre de N1 bits. On cherche le modulo par la relation:

dividende = quotient * diviseur + modulo

ou modulo = dividende – partie_entiere (dividende /diviseur)

On procède par dichotomie sur le quotient. On propose une succéssion de quotients jusqu’à ce que dividende – quotient * diviseur soit inférieur à diviseur. La différence est alors le modulo cherché.

Avec cette méthode, le temps de calcul en nombre de cycles est en général de N1 – N2 + 1 . Il tombe à 1 cycle si le dividende = 0, et est inférieur si le quotient est apparu plus tôt dans la séquence. Afin de réduire ce temps de cycle, on prendra bien soin d’ajuster N1 au minimum requis, pour N2 (le diviseur) on doit impérativement avoir un ’1′ en MSB afin de n’avoir que des bits « utiles.

Le fichier source et son fichier test apportent toutes les précisions nécessaires.

A titre d’exemple , voici un extrait du rapport de synthèse sur une cible Virtex.

Cell Usage :
# BELS                             : 325
#      GND                         : 1
#      INV                         : 4
#      LUT2                        : 37
#      LUT3                        : 27
#      LUT4                        : 34
#      LUT5                        : 55
#      LUT6                        : 23
#      MUXCY                       : 84
#      VCC                         : 1
#      XORCY                       : 59
# FlipFlops/Latches                : 59
#      FD                          : 23
#      FDR                         : 35
#      FDRS                        : 1
# Clock Buffers                    : 1
#      BUFGP                       : 1
# IO Buffers                       : 42
#      IBUF                        : 33
#      OBUF                        : 9
# DSPs                             : 1
#      DSP48E                      : 1
============================================

Commentaire sur le VHDL

Pour le choix du diviseur rentrant dans le calcul du modulo, nous l’avons voulu constant et avons donc déclaré une constante générique:

GENERIC(  N1  : natural := 24;           — Nombres de bits  dividende

divisor  : unsigned(7 DOWNTO 0) :=x »C8″ );    — 200 et MSB = ’1′

On veut absolument  que le MSB soit 1 ce qui fait dépendre le nombre de bits de la valeur de la constante. On voit très bien que cette écriture n’est pas satisfaisante car la constante ne pourra être modifiée que dans la gamme 128 à 255 puisqu’au delà il faut changer le nombre de bits du diviseur et donc modifier la spécification d’entité.

Une solution alternative serait de définir une constante générique N2 , nombre de bits du diviseur et du modulo et de définir un port d’entree

divisor: unsigned(N2-1 DOWNTO 0), mais alors il faudra de l’extérieur assurer que la valeur d’entrée a bien un MSB = ’1′. On a juste repoussé le problème.

 

 

Leave a Reply

You must be logged in to post a comment.