¿Cómo truncar un ancho de bits de expresión en Verilog?

11

Considere una expresión como:

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

donde la salida del func es de 32 bits de ancho y x es un cable de 16 bits. Quiero asignar solo los 16 bits más bajos del xor resultante.

Sé que el código anterior ya lo hace, pero también genera una advertencia. El enfoque "obvio" no funciona:

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

Respuestas:

8

Puede usar otra variable, aunque esto no es particularmente elegante.

wire[31:0] y;

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

Un mejor enfoque sería usar una función.

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));
dwikle
fuente
Esperaba que hubiera algo mejor que eso ... Oh, bueno, crearé una gran cantidad de funciones truncadas.
user23106
5

En su ejemplo, está truncando implícitamente los bits.

Hacer explícito el truncamiento a menudo puede eliminar las advertencias en simulación / pelusa / síntesis.

Una forma de hacer esto en línea es usar un operador de conversión, por ejemplo:

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

Este enfoque puede tener sentido si es obvio por el contexto que todos los bits que se descartan son ceros.

Si algunos de los bits pueden ser distintos de cero, entonces sugeriría seguir usando una red intermedia como @dwikle sugerido en una respuesta anterior , ya que deja más claro que en realidad está tirando bits. Aquí está nuevamente como referencia.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];
mate
fuente
1
Creo que eso solo funcionaría en SystemVerilog. Interesante no obstante.
Tom Carpenter
@TomCarpenter, ¿desea limitarse al subconjunto de Verilog disponible en IEEE Std 1364-2005, en lugar de usar el conjunto completo de verilog sintetizable disponible en una de las revisiones unificadas más nuevas de IEEE Std 1800? Es posible que desee decir Verilog-2005 o algo para aclarar, ya que el estándar Verilog se incluyó en el estándar unificado SystemVerilog en 2009.
2016
3

Creo que esto podría ayudar a mantener la cuenta regresiva de la línea.

wire [15:0] not_used ;

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

Sin embargo, no estoy seguro de si eso es válido con las asignaciones.

pre_randomize
fuente