des00 25 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба 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: арифметический сдвиг влево или вправо Не арифметический, а логический. Обрезать - вроде как нулями добить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба 3 minutes ago, Nick_K said: Не арифметический, а логический. Обрезать - вроде как нулями добить Обрезать - убрать младшие биты из большего при присвоении к меньшему, оставив на месте старший не знаковый бит. Добивают когда нужно масштабировать при присвоении меньшего к большему, оставив в силе старший не знаковый бит, При сдвиге влево, арифметический и логический сдвиги одинаковы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 24 октября, 2019 Опубликовано 24 октября, 2019 · Жалоба 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)]; По сравнению с моим первым вариантом. Хотя тут не учтён вариант произведения меньшего чем результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться