Как урезать битовую ширину выражения в Verilog?


11

Рассмотрим выражение вроде:

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

где вывод функции имеет ширину 32 бита, а x представляет собой провод из 16 бит. Я хочу назначить только 16 младших битов полученного xor.

Я знаю, что приведенный выше код уже делает это, но он также генерирует предупреждение. «Очевидный» подход не работает:

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

Ответы:


8

Вы можете использовать другую переменную, хотя это не особенно элегантно.

wire[31:0] y;

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

Лучшим подходом было бы использовать функцию.

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));

Я надеялся, что будет что-то приятнее, чем это ... О, хорошо, я просто создам большое количество усекающих функций.
user23106

5

В вашем примере вы неявно усекаете биты.

Явное усечение может часто удалять предупреждения в моделировании / удалении / синтезе.

Один из способов сделать это in-line - использовать оператор приведения, например:

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

Этот подход может иметь смысл, если из контекста очевидно, что все отбрасываемые биты равны 0.

Если некоторые биты могут отличаться от нуля, я бы по-прежнему предлагал использовать промежуточную сеть, такую ​​как @dwikle, предложенную в предыдущем ответе , поскольку это делает более понятным, что вы на самом деле выбрасываете биты. Здесь это снова для справки.

wire[31:0] y;

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

1
Я думаю, что это будет работать только в SystemVerilog. Интересно тем не менее.
Том Карпентер

@TomCarpenter, хотите ли вы ограничиться подмножеством Verilog, доступным в IEEE Std 1364-2005, вместо того, чтобы использовать полный набор синтезируемых verilog, доступный в одной из более новых унифицированных ревизий IEEE Std 1800? Вы можете сказать Verilog-2005 или кое-что прояснить, поскольку стандарт Verilog был включен в унифицированный стандарт SystemVerilog в 2009 году.
Mattgately

3

Я думаю, что это может помочь уменьшить счет.

wire [15:0] not_used ;

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

Не уверен, если это действительно с назначениями, хотя.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.