Як обрізати ширину бітів виразів у 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));

Я сподівався, що буде щось приємніше за це ... Ну добре, я просто створять велику кількість функцій обрізки.
користувач23106

5

У вашому прикладі ви неявно обрізаєте біти.

Зростання явного усічення часто може видаляти попередження в моделюванні / ворсі / синтезі.

Один із способів зробити це в режимі рядка - це використовувати оператор лиття, наприклад:

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 році.
1616

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.