Мне нужна функция вправо-влево в Verilog для 32-битных входов, поскольку она не определена как оператор (x >>> y).
Легко повернуть такой ввод вручную:
wire [31:0] test = 32'd12345;
wire [31:0] rotated_1 = {test[0:0],test[31:1]};
wire [31:0] rotated_3 = {test[2:0],test[31:3]};
Выход тестового стенда соответствует ожидаемому:
original: 00000000000000000011000000111001
rotate_1: 10000000000000000001100000011100
rotate_3: 00100000000000000000011000000111
Мы видим, что функция rotate (inp, x) должна работать так:
function rotate;
input [31:0] inp;
input [4:0] x;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
Проблема в том, что x не является постоянной , поэтому он не компилируется. Чтобы указать диапазон с помощью [a: b], a и b должны быть константами.
Решение, похоже, использует параметры:
function rotate;
parameter integer x = 1;
input [31:0] inp;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
Хорошо, он компилируется, но в отличие от модулей, для которых вы можете создать экземпляр с измененным параметром, подобным этому
param_module #(3) pm_inst(...);
, что не работает с функциями . Фактически, из чтения грамматики Verilog я не вижу способа вообще для указания параметра:
<function_call>
::= <name_of_function> ( <expression> <,<expression>>* )
Мои эксперименты с defparam работали только с модулями, а не с функциями.
Поскольку параметризованные макросы также не существуют в Verilog, как мне реализовать функцию поворота, не объявляя ее для каждого возможного поворота? - и мне нужно их много: - (
( Не вот так:)
function rotate1...
function rotate2...
function rotate3...
...