01signal.com

Arithmétique signée en Verilog : la seule règle à connaître

La règle d’or est la suivante : tous les opérandes doivent être signés.

On dirait bien que Verilog a un fort penchant pour les nombres non signés (unsigned). Chacun des cas suivants produit une valeur non signée :

En bref, il faut soit utiliser la fonction système $signed, soit déclarer des fils (wire) signés et des registres signés.

Par exemple, pour multiplier un registre signé par un registre non signé (unsigned), tout en traitant le résultat comme une valeur signée (évidemment), on peut écrire quelque chose comme ceci :

reg         [15:0] a; // Unsigned
reg signed  [15:0] b;
wire signed [16:0] signed_a;
wire signed [31:0] a_mult_b;

assign signed_a = a; // Convert to signed
assign a_mult_b = signed_a * b

Notez que signed_a fait un bit de plus que « a », ce qui laisse de la place pour le bit de signe, qui vaut toujours zéro. Sans ce bit supplémentaire, le MSB de a aurait été traité comme le bit de signe dans signed_a (MSB = most significant bit, soit bit de poids fort).

On pourrait croire, à tort, qu’il faut définir explicitement le MSB de signed_a avec quelque chose comme {1'b0, a} plutôt qu’avec « a » seul. Or, la norme Verilog est explicite : seule l’expression détermine si le nombre est signé ou non signé. La partie gauche de l’affectation (left-hand side) n’a donc aucune influence sur ce point. « a » est donc traité comme une valeur non signée et est étendu avec des zéros.

Cette page a été traduite de l’anglais par une machine. En cas de doute, veuillez vous reporter au texte original
Copyright © 2021-2026. All rights reserved. (dcc38493)