Comment tronquer une largeur de bit d'expression dans Verilog?


11

Considérez une expression comme:

assign x = func(A) ^ func(B);

où la sortie de la fonction a une largeur de 32 bits et x est un fil de 16 bits. Je veux affecter uniquement les 16 bits les plus bas du xor résultant.

Je sais que le code ci-dessus le fait déjà, mais il génère également un avertissement. L'approche "évidente" ne fonctionne pas:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected

Réponses:


8

Vous pouvez utiliser une autre variable, bien que ce ne soit pas particulièrement élégant.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

Une meilleure approche serait d'utiliser une fonction.

function [15:0] trunc_32_to_16(input [31:0] val32);
  trunc_32_to_16 = val32[15:0];
endfunction

assign x = trunc_32_to_16(func(A) ^ func(B));

J'espérais qu'il y aurait quelque chose de plus agréable que ça ... Eh bien, je vais juste créer un grand nombre de fonctions de troncature.
user23106

5

Dans votre exemple, vous tronquez implicitement des bits.

Rendre la troncature explicite peut souvent supprimer les avertissements de simulation / peluches / synthèse.

Une façon de le faire en ligne consiste à utiliser un opérateur de transtypage, par exemple:

typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));

Cette approche peut avoir du sens s'il est évident d'après le contexte que tous les bits supprimés sont des 0.

Si certains bits peuvent être différents de zéro, je suggérerais toujours d'utiliser un réseau intermédiaire comme @dwikle suggéré dans une réponse précédente , car il est plus clair que vous jetez des bits. Le voici à nouveau pour référence.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

1
Je pense que cela ne fonctionnerait que dans SystemVerilog. Intéressant non-moins.
Tom Carpenter

@TomCarpenter, voulez-vous vous limiter au sous-ensemble de Verilog disponible dans IEEE Std 1364-2005, plutôt que d'utiliser l'ensemble complet de verilog synthétisable disponible dans l'une des plus récentes révisions unifiées IEEE Std 1800? Vous voudrez peut-être dire Verilog-2005 ou quelque chose à clarifier, puisque la norme Verilog a été incluse dans la norme SystemVerilog unifiée en 2009.
matinalement le

3

Je pense que cela pourrait aider à réduire le nombre de lignes.

wire [15:0] not_used ;

assign {not_used, x} = (func(A) ^ func(B));

Je ne sais pas si cela est valable avec les assignés.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.