Como truncar uma largura de bit de expressão no Verilog?

11

Considere uma expressão como:

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

onde a saída da função tem 32 bits de largura ex é um fio de 16 bits. Quero atribuir apenas os 16 bits mais baixos do xor resultante.

Eu sei que o código acima já faz isso, mas também gera um aviso. A abordagem "óbvia" não funciona:

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

Respostas:

8

Você pode usar outra variável, embora isso não seja particularmente elegante.

wire[31:0] y;

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

Uma abordagem melhor seria usar uma função.

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
fonte
Eu esperava que houvesse algo melhor do que isso ... Oh, bem, vou criar um grande número de funções truncantes.
user23106
5

No seu exemplo, você está truncando bits implicitamente.

Tornar o truncamento explícito geralmente pode remover os avisos em simulação / fiapos / síntese.

Uma maneira de fazer isso em linha é usar um operador de conversão, por exemplo:

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

Essa abordagem pode fazer sentido se for óbvio, no contexto, que todos os bits que estão sendo descartados são zeros.

Se alguns bits podem ser diferentes de zero, sugiro ainda usar uma rede intermediária como @dwikle sugerida em uma resposta anterior , pois fica mais claro que você está realmente jogando bits fora. Aqui está novamente para referência.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];
mattgately
fonte
11
Eu acho que isso só funcionaria no SystemVerilog. Interessante não menos.
21416 Tom Carpenter
@ TomCarpenter, você deseja limitar-se ao subconjunto do Verilog disponível no IEEE Std 1364-2005, em vez de usar o conjunto completo de verilog sintetizável disponível em uma das mais recentes revisões unificadas do IEEE Std 1800? Você pode dizer Verilog-2005 ou algo a esclarecer, uma vez que o padrão Verilog foi incluído no padrão SystemVerilog unificado em 2009.
mattgately
3

Eu acho que isso pode ajudar a manter a contagem decrescente.

wire [15:0] not_used ;

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

Não tenho certeza se isso é válido com atribuições.

pre_randomize
fonte