我正在使用 SystemVerilog 在 FPGA 上实现最大池模块。每个字的长度为 64 位,输入数据为 28 x 28 个字的网格(即 28x28 像素的图像)。过滤器大小为 2 x 2 个字,步长为 2。
代码在模拟上运行良好,Vivado 中的合成器没有提及任何不可合成的部分。我还认为这段代码应该很好地综合,因为所有参数都是文字,所以一切都应该在编译步骤中解决。但是当我在 chatGPT 上问这个问题时,它说这个代码不可合成。
这是我的代码:
`timescale 1ns / 1ps
module max_pooling_module
#(
parameter N = 64,
parameter WIDTH = 28,
parameter FILTER_SIZE = 2,
parameter STRIDE = 2
)
(
input logic signed [WIDTH-1:0][WIDTH-1:0][N-1:0] inputImage,
output logic signed [(WIDTH-FILTER_SIZE)/STRIDE:0][(WIDTH-FILTER_SIZE)/STRIDE:0][N-1:0] pooledImage
);
// generate hardwares to do pooling concurrently
generate
genvar row, col;
for(row = WIDTH-1; row + 1 >= STRIDE; row -= STRIDE) begin : stride_down
for(col = WIDTH-1; col + 1 >= STRIDE; col -= STRIDE) begin : stride_right
// create an array contains all the elements that will be passed to max module
logic signed [N-1:0] arr [FILTER_SIZE*FILTER_SIZE];
// add elements to arr
always_comb begin
for(int i = 0; i < FILTER_SIZE; i++) begin
for(int j = 0; j < FILTER_SIZE; j++) begin
arr[i*FILTER_SIZE+j] = inputImage[row-i][col-j];
end
end
end
// max module takes 2 signals, the input is an array of values to compare,
// and an output which receives max value
max pooling(.arr(arr), .maxValue(pooledImage[(row+1)/STRIDE-1][(col+1)/STRIDE-1]));
end
end
endgenerate
endmodule
这是最大模块:
module max #(parameter FILTER_SIZE = 2, parameter N = 64) (
input logic signed [N-1:0] arr[FILTER_SIZE*FILTER_SIZE],
output logic signed [N-1:0] maxValue
);
logic signed [N-1:0] res;
always_comb begin
res = arr[0];
for (int i = 0; i < FILTER_SIZE*FILTER_SIZE; i++) begin
if (res < arr[i]) res = arr[i];
else res = res;
end
end
assign maxValue = res;
endmodule
这段代码可以合成吗?如果不是,正确的做法是什么?
这是我在运行综合和实现后收到的消息:
我认为它是可以合成的,因为合成已经完成并且结果看起来是合理的。想查看利用率摘要。我有兴趣看看利用率摘要是什么样的。 GUI 菜单选项类似于工具/报告/综合后的报告利用率。
我看到的最大问题是 UTLZ-1 错误,这意味着您的设计比目标部件更大。一个 53 磅的盒子里有 56 磅的东西。也许可以将字长从 64 位减少到 32 位。您或许可以使用 << max modules if you figure out a way to use them as an engine and multiplex the data in and out, then store in in registers. If you need to do N operations you don't necessarily need N operating engines, just time share the single operation and store results as needed.
关于除法运算符:
/ 运算符用作在详细阐述时展开的生成循环的一部分,您并不是要求 Verilog RTL 进行除法; / 的使用方式应该没问题。您得到的除法是整数除法。