Types, tailles et signe
Comprendre logic, bit, les types SystemVerilog à 2 ou 4 états, les largeurs, le signe et les conversions sans surprise.
Quatre états ou deux états
logic est un type à 4 états. En plus de 0 et 1, il peut contenir X, valeur inconnue, et Z, haute impédance. Ces états sont utiles en simulation pour repérer une initialisation manquante, plusieurs pilotes en conflit ou un bus non piloté.
bit est limité à 0 et 1. Les types entiers atomiques byte, shortint, int et longint sont eux aussi à 2 états ; ils ont respectivement 8, 16, 32 et 64 bits et sont signés par défaut. Les anciens types integer et time sont à 4 états. Pour un vecteur de largeur choisie, bit [N-1:0] est à 2 états alors que logic [N-1:0] est à 4 états.
Dans le RTL, logic reste souvent le choix le plus lisible pour les ports et les signaux internes, car une valeur X peut révéler un reset ou un pilotage incomplet.
logic valid;
logic [15:0] data;
bit enable_model;
int unsigned transaction_count;Un type à 2 états peut accélérer certains modèles de test, mais il transforme une valeur inconnue en 0. Il ne faut donc pas l'utiliser si cette conversion risque de cacher une erreur d'initialisation.
Lorsqu'une entrée ou une sortie du DUT doit rester à 4 états, contrôler explicitement les inconnues évite qu'une conversion les masque :
known_bus_a: assert (!$isunknown({valid, data}))
else $error("valid ou data contient X/Z");La taille fait partie du calcul
La largeur d'une expression dépend de ses opérandes, mais aussi du contexte dans lequel elle est évaluée. Dans une affectation, une destination plus large peut imposer une précision plus grande à l'addition. Dans une expression imbriquée, un argument de fonction ou un résultat stocké d'abord dans une variable étroite, ce contexte peut être différent.
Lorsqu'un bit de retenue fait partie du contrat, une extension explicite reste la forme la plus robuste : elle rend la précision voulue indépendante du reste de l'expression.
module add_with_carry (
input logic [7:0] i_a,
input logic [7:0] i_b,
output logic [8:0] o_sum
);
always_comb begin
o_sum = {1'b0, i_a} + {1'b0, i_b};
end
endmoduleL'extension explicite rend le bit de retenue visible et documente le choix. Les littéraux comme 8'hA5, 5'd17 ou -16'sd3 indiquent clairement taille, base et signe.
'0 remplit toute la destination de zéros et '1 la remplit de uns. Cette écriture suit la taille du signal et convient bien aux resets génériques.
Signé et non signé
Un vecteur logic [7:0] est non signé par défaut. Le mot-clé signed change l'interprétation des comparaisons, extensions et décalages arithmétiques.
logic signed [11:0] sample;
logic signed [12:0] extended;
assign extended = $signed({sample[11], sample});Mélanger signé et non signé dans la même expression peut donner un résultat différent de celui attendu. Il vaut mieux typer les signaux selon leur sens physique et employer $signed, $unsigned ou un cast de type à l'endroit précis où la conversion est voulue.
Casts et contrôles
Un cast statique s'écrit type'(expression). Il rend une conversion visible dans la revue de code.
typedef logic signed [15:0] sample_t;
sample_t filtered;
assign filtered = sample_t'(raw_value);Le cast ne protège pas d'une troncature. Si la destination est plus petite, les bits de poids fort sont perdus. Il faut donc contrôler les bornes, les avertissements de compilation et les valeurs limites dans le testbench.
À retenir
logicconserveXetZ, ce qui aide au débogage.bit,byte,shortint,intetlongintsont à 2 états et peuvent masquer une inconnue.- La largeur des opérandes doit être choisie avant l'opération.
- Le signe influe sur les comparaisons, extensions et décalages.
- Un cast explicite clarifie une conversion mais n'empêche pas la troncature.
📝 Tester mes connaissances - Quiz du chapitre