Функция для вычисления значения внутри цикла генерации Verilog
Я пытаюсь создать параметризованную схему для стадии умножения BCD Wallace Tree Multiplier, которую я реализовал в Orcad. Проблема, с которой я столкнулся, заключается в том, что мне нужно вычислить битовые позиции, которые будут присутствовать каждые две цифры в результате умножения BCD. Вот мой код:
module bcd_mult_1_n #(parameter N = 8)
(input [N * 4 - 1:0] num1, num2, output reg [2 * 4 * N * N - 1:0] partProds);
genvar i, j;
generate
for(i = 0; i < N; i = i + 1) begin : dig1
for(j = 0; j < N; j = j + 1) begin : dig2
localparam lsd = posLSD(i, j);
localparam msd = posMSD(i, j);
bcd_mult_1 bcd_mult(num1[i * 4 + 3:i * 4], num2[j * 4 + 3:j * 4],
partProds[msd * 4 + 3:msd * 4], partProds[lsd * 4 + 3: lsd * 4]);
end
end
endgenerate
В приведенном выше коде numPrev(i + j) должен возвращать значение, вычисленное примерно так
int numPrev(int x) {
int acc = 0;
for(int i = x; i > 0; i++) acc = acc + 2 * i;
return acc;
}
Благодаря помощи @Morgan я создал следующую функцию; логика предназначена для подсчета вверх и вниз своего рода треугольника значений, которые растут от 1 до N и обратно до 1.
function integer posLSD;
input integer x, y;
integer weight;
integer acc;
integer num;
integer i;
weight = x + y;
acc = 0;
if(weight >= N) num = N - 1;
else num = weight;
for(i = num; i > 0; i = i - 1)
acc = acc + 2 * i;
if(weight >= N) begin
for(i = 2 * N - weight; i <= N; i = i + 1) begin
acc = acc + 2 * i;
end
acc = acc + N - weight + y - 1;
end
else
acc = acc + y;
posLSD = acc;
endfunction
function integer posMSD;
input integer x, y;
integer acc;
integer weight;
acc = posLSD(x, y);
weight = x + y;
if(weight < N) acc = acc + weight + 1;
else acc = acc + 2 * N - weight - 1;
posMSD = acc;
endfunction
Как я мог достичь этой функциональности? При необходимости я мог бы использовать конструкции SystemVerilog.
1 ответ
Когда я перехожу на использование функции, я получаю ошибку Packed dimension must specify a range.
Я думаю, вам нужно подумать о ширине вашего partProds и соединениях.
Используя функцию:
module bcd_mult_1_n #(
parameter N = 8
) (
input [N * 4 - 1:0] num1,
input [N * 4 - 1:0] num2,
output reg [2 * 4 * N * N] partProds
);
integer prev = 1;
genvar i, j;
generate
for(i = 0; i < N; i = i + 1) begin : dig1
for(j = 0; j < N; j = j + 1) begin : dig2
bcd_mult_1
bcd_mult(
num1[i * 4 + 3:i * 4],
num2[j * 4 + 3:j * 4],
partProds[numPrev(i+j) + 2*j + i + 1],
partProds[numPrev(i+j) + j]
);
end
end
endgenerate
function numPrev;
input integer x ;
integer acc;
begin
acc = 0;
for(int ij = x; ij > 0; ij++) begin
acc = acc + 2 * ij;
end
numPrev = acc;
end
endfunction
endmodule
module bcd_mult_1(
input [3:0]a,
input [3:0]b,
input c,
input d
);
endmodule
Пример на детской площадке EDA.