Altifigence Academy

54 / 63 · Concept

Multiplicateur non signé multicycle par décalage-addition

Répartir l'accumulation sur W cycles et vérifier acceptation, achèvement, dernière somme, largeur et invariant.

Prérequis : logique séquentielle, affectations non bloquantesAffectation non bloquante Affectation <= du RTL séquentiel : le membre droit est évalué puis la mise à jour planifiée, permettant aux registres du même front de calculer à partir de l'ancien état. En savoir plus, compteurs, décalages et additionneurs.

Réutiliser un additionneur sur plusieurs cycles

La multiplication non signéeNon signé Interprétation d'un motif de bits comme entier non négatif. Sur n bits, la plage va de 0 à 2^n−1 et peut différer de l'interprétation signée du même motif. En savoir plus W bits est la somme des produits partiels sélectionnés par chaque bit de B.

AB=∑i=0W−1bi(A2i)A B=\sum_{i=0}^{W-1} b_i(A2^i)

Tout additionner simultanément exige beaucoup de logique. Ici, un seul additionneur est utilisé W fois : un compromis entre aire et débit. Une boucle RTL ne crée pas spontanément plusieurs cycles ; il faut des registresRegistre Circuit stockant plusieurs bits d'état. Les registres synchrones du cours capturent leur entrée définie sur un front d'horloge. En savoir plus d'état intermédiaire et une condition de fin.

P, l'accumulateur, et M, le multiplicande décalé, ont 2W bits ; Q, le multiplicateur décalé à droite, en a W. Initialisez P=0,M=zero-extend(A),Q=B. À chaque cycle de travail, ajoutez M à P si Q[0]=1, décalez M à gauche et Q à droite d'un bit.

Pk+1=Pk+Qk[0]Mk,Mk+1=2Mk,Qk+1=⌊Qk/2⌋P_{k+1}=P_k+Q_k[0]M_k,\quad M_{k+1}=2M_k,\quad Q_{k+1}=\lfloor Q_k/2\rfloor

Après W opérations, Q=0 et P est le produit complet. 2W bits suffisent car (2W−1)2<22W(2^W-1)^2<2^{2W} et les sommes partielles non signées ne dépassent pas le produit final.

Pour A=13,B=11,W=4, les bits bas de Q sont 1,1,0,1. P suit 0→13→39→39→143 ; M utilisé vaut 13,26,52,104. Même à la troisième opération où Q[0]=0, décalages et compteur doivent avancer.

Chaque colonne montre l'état après capture de requête ou opération. La première initialise ; les quatre suivantes calculent. À la troisième opération, l'ancien bit bas de Q est nul : seul P reste constant, M et Q avancent.

Calculer 13×11 en quatre accumulations
Voir les données du chronogramme
Données du chronogramme : chaque caractère représente un intervalle ; un point maintient l'état précédent ; p représente un cycle d'horloge.
SignalForme d'ondeValeurs du bus
edge23452capture → travail1 → travail2 → travail3 → travail4
P après234.50 → 13 → 39 → 143
M après2345213 → 26 → 52 → 104 → 208
Q après2345211 → 5 → 2 → 1 → 0
done après0...1

Définir acceptation et achèvement

Une requête est acceptée au front montantFront montant Instant où l'horloge passe de 0 à 1, distinct du niveau désignant tout l'intervalle CLK=1. En savoir plus avec start=1 pendant idle. À t0, seules les entrées sont stockées. Les W opérations ont lieu de t1 à tW ; product et done deviennent valides après tW. La latence est W périodes, avec W+1 fronts si l'on inclut celui de départ.

start est ignoré lorsque busy=1, y compris au front d'achèvement où l'ancien busy vaut encore 1. La prochaine acceptation est donc au plus tôt tW+1 : intervalle minimal W+1 périodes. Maintenir start à 1 relance au prochain front idle ; l'appelant fournit généralement une impulsion adaptée à l'acceptation.

SystemVerilog
module mul_iter #(parameter int W = 8) (
  input  logic clk, rst, start,
  input  logic [W-1:0] a, b,
  output logic busy, done,
  output logic [2*W-1:0] product
);
  localparam int CW = (W <= 1) ? 1 : $clog2(W);
  localparam logic [CW-1:0] LAST = CW'(W-1);
  logic [CW-1:0] step;
  logic [2*W-1:0] acc, m, next_acc;
  logic [W-1:0] q;

  assign next_acc = acc + (q[0] ? m : {2*W{1'b0}});

  always_ff @(posedge clk) begin
    if (rst) begin
      busy <= 1'b0;
      done <= 1'b0;
      product <= '0;
      acc <= '0;
      m <= '0;
      q <= '0;
      step <= '0;
    end else begin
      done <= 1'b0;
      if (!busy) begin
        if (start) begin
          busy <= 1'b1;
          acc <= '0;
          m <= {{W{1'b0}}, a};
          q <= b;
          step <= '0;
        end
      end else begin
        acc <= next_acc;
        m <= m << 1;
        q <= q >> 1;
        if (step == LAST) begin
          product <= next_acc;
          busy <= 1'b0;
          done <= 1'b1;
        end else begin
          step <= step + 1'b1;
        end
      end
    end
  end
endmodule

Le contrat est W≥1 ; CW reste au moins 1 pour éviter un compteur de largeur nulle à W=1. Le reset synchrone actif haut prime sur une opération en cours. Après capture, changer a,b externes n'affecte pas m,q stockés. product ne change qu'au reset ou à l'achèvement. done est une impulsion d'une période, pas un valid maintenu jusqu'à consommation.

L'affectation finale est product<=next_acc, pas product<=acc. Les membres droits non bloquants lisent l'ancien état : acc seul omettrait le dernier produit partiel. Pour la même raison, écrire le décalage de q plus haut ne change pas le Q[0] actuel utilisé par next_acc.

Invariant de calcul et choix d'implémentation

Après k opérations :

Pk+MkQk=ABP_k+M_kQ_k=A B

Décomposer Q en partie paire et bit bas montre la conservation à l'étape suivante. À k=W, Q=0, donc P=AB. Cet invariantInvariant Condition devant rester vraie dans toute exécution autorisée. Par exemple, l'occupation d'un FIFO de profondeur 4 reste toujours entre 0 et 4. En savoir plus explique l'ordre accumulation/décalage plus clairement qu'un petit chronogramme seul.

Le chemin critique d'une opération comprend un additionneur 2W bits et la sélection d'entrée. Supprimer le symbole de multiplication ne garantit ni gain d'aire ni vitesse : comparez blocs DSP FPGA, synthèse et débitDébit Nombre d'opérations acceptées ou terminées par unité de temps. Un pipeline peut l'augmenter sans réduire la latence d'une opération individuelle. En savoir plus requis. Le module ne réalise ni fin anticipée, ni signé, ni backpressure de résultat ; le consommateur ne doit pas manquer done.

Testez 0,1,maximum et B avec seulement son bit haut à 1, ainsi que start et changements d'entrée pendant busy et annulation par reset. Le B à un seul bit haut révèle particulièrement l'oubli de la dernière accumulation.

Essayez vous-même

W=4,A=9,B=10 sont acceptés à t0. Donnez acc,q,done après t1–t4 et la prochaine acceptation la plus précoce. Que produirait product<=acc à la fin ?

Lire l’explication

Initialement acc=0,m=9,q=1010. t1 : bit bas=0, acc=0,q=0101,done=0. t2 : ajout de m=18, acc=18,q=0010,done=0. t3 : bit bas=0, acc=18,q=0001,done=0. t4 : ajout de m=72, acc=90,q=0000,done=1,busy=0,product=90. Avant t4 busy=1, donc la prochaine requête est acceptée au plus tôt t5. product<=acc lirait l'ancien acc=18 et omettrait 72, donnant 18.

Votre choix s’applique à ce navigateur. Modifiez-le à tout moment en bas de page.