Перейти к содержанию
    

1 hour ago, Timmy said:

А вот с Верилогом, кажется, придётся мудрить.

как уже писал,разрдяность типа статическая, поэтому либо функция уровня модуля, либо шаблон. а внутри там все тривиально, арифметический сдвиг влево или вправо, на нужное количество бит.

Ну а если призвать на помощь макросы (хотя многие их не любят) то будет так

  bit [7 : 0] a, a1;
  bit [3 : 0] b, b1;

  bit [15 : 0] c, c1;

  assign c = ($size(c) > ($size(a) + $size(b))) ? (a*b) <<< ($size(c) - ($size(a) + $size(b))) :
                                                  (a*b) >>> ($size(a) + $size(b) - $size(c)) ;

  `define align_left(a, b, c)                                                                             \
    ($size(c) > ($size(a) + $size(b))) ? (a * b) <<< ($size(c) - ($size(a) + $size(b))) : \
                                         (a * b) >>> ($size(a) + $size(b) - $size(c))     \

  assign c1 = `align_left(a1, b1, c1);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Timmy said:

другую переменную произвольной разрядности, с выравниванием по старшим битам

Ну во-первых я изначально сказал, что в Верилоге операции с векторами (сдвиги, перекручивания и т.п.) ИМХО сложнее VHDL'ных.

Во-вторых можно расписать вот так:

localparam int p_mul_len = ($bits(a_inp) + $bits(b_inp));
logic [p_mul_len - 1 : 0] r_temp;

assign r_temp = a_inp * b_inp;

assign c_out = {<<p_mul_len{r_temp}};

Операции стриминга работают на ура. Проблемы опять в разрядностях. Плюс стриминг часто глючит и достаточно редко поддерживается в синтезаторах.

В-третьих, у меня Ваш код VHDL не захотел синтезироваться. Видно я не нашёл библиотеки с align_left функцией. На Верилоге всё в стандарте съедается.

18 minutes ago, des00 said:

арифметический сдвиг влево или вправо

Не арифметический, а логический. Обрезать - вроде как нулями добить :smile:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Nick_K said:

Не арифметический, а логический. Обрезать - вроде как нулями добить :smile:

Обрезать - убрать младшие биты из большего при присвоении к меньшему, оставив на месте старший не знаковый бит. Добивают когда нужно масштабировать при присвоении меньшего к большему, оставив в силе старший не знаковый бит, При сдвиге влево, арифметический и логический сдвиги одинаковы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 minutes ago, des00 said:

Обрезать - убрать младшие биты из большего при присвоении к меньшему, оставив на месте старший не знаковый бит.

А да, пардоньте запутался. Тогда получается немного красивее у меня:

localparam int p_mul_len = ($bits(a_inp) + $bits(b_inp));
logic [p_mul_len - 1 : 0] r_temp;

assign r_temp = a_inp * b_inp;

assign c_out = r_temp[(p_mul_len - 1) -: $bits(c_out)];

По сравнению с моим первым вариантом. Хотя тут не учтён вариант произведения меньшего чем результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...