如何改进我的代码以减少综合时间?
How can I improve my code to reduce the synthesis time?
我已经使用累积直方图方法在 verilog 中为中值滤波器编写了一些代码。当我尝试在 xilinx 中综合我的代码时,它的处理时间长达 1 小时,最后显示错误,"program ran out of memory".
我的代码是:
//***** MEDIAN FILTER BY USING CUMULATIVE HISTOGRAM METHOD******//
module medianfilter(median_out,clk,a1,a2,a3,a4,a5,a6,a7,a8,a9);
output median_out;
input [7:0]a1,a2,a3,a4,a5,a6,a7,a8,a9;
integer i,j;
reg[7:0]b[255:0];
reg [7:0]buff[0:8];
input clk;
reg [7:0]median_out;
always@(negedge clk)
begin
//**************************************************************************//
for(i=0;i<256;i=i+1) // initilize the memory bins with zeros
b[i]=0;
//*************************************************************************//
buff[0]=a1;
buff[1]=a2;
buff[2]=a3;
buff[3]=a4;
buff[4]=a5;
buff[5]=a6;
buff[6]=a7;
buff[7]=a8;
buff[8]=a9;
for(i=0;i<9;i=i+1) // this loop is for cumulative histogram method
begin
b[buff[i]]=b[buff[i]]+1; // incrementing the value in b[i]th memory address
for(j=0;j<256;j=j+1)
if(j>buff[i])
b[j]=b[j]+1; // incrementing the bins below b[i]th bin
end
//**************************************************************************//
for(i=0;i<256;i=i+1) // loop for finding the median
begin
if(b[i]>4) ///////// condition for checking median
begin
b[i]=1;
median_out=i;
i=256; // loop breaks here
end
end
//*************************************************************************//
end
endmodule
如何使代码可综合?
您的代码生成了多少个加法器?我看到至少有 2,100 个 8 位加法器在同一个周期内工作。
您应该重新考虑您的算法:中值滤波器需要像素值的有序列表,因此首先您应该考虑 FPGA 上数字的高效排序。
一个好的方法是像这样对网络进行排序:
- 奇偶合并排序或
- 双调排序。
无法在一个循环中完成对 9 个数字的排序,因此您需要流水线操作。 (你可以做到,但时钟速度非常低。)
我们的PoC-Library contains pipelined sorting networks,但我从来没有用非两个输入大小的幂测试这些网络!
我同意@Paebbels 在这里所说的一切。但是,还有一些额外的注意事项。数据传入的速度有多快。您是否获得了一组新的 10 个值来对每个时钟周期进行排序?如果不是,您可以流水线操作并使用更少的加法器和寄存器阶段,甚至使用单个加法器并将结果存储在块 RAM 中(尽管这会慢得多)。此外,您还没有提到您使用的是哪种 FPGA(尽管我猜这是一个小的)。任何 FPGA 设计都需要考虑目标设备上的可用资源。如果您的设计中的其他地方未使用加法器,您也可以直接为加法器实例化 DSP48 乘法器-累加器,同样取决于您需要的数量和设备上可用的数量。
我已经使用累积直方图方法在 verilog 中为中值滤波器编写了一些代码。当我尝试在 xilinx 中综合我的代码时,它的处理时间长达 1 小时,最后显示错误,"program ran out of memory".
我的代码是:
//***** MEDIAN FILTER BY USING CUMULATIVE HISTOGRAM METHOD******//
module medianfilter(median_out,clk,a1,a2,a3,a4,a5,a6,a7,a8,a9);
output median_out;
input [7:0]a1,a2,a3,a4,a5,a6,a7,a8,a9;
integer i,j;
reg[7:0]b[255:0];
reg [7:0]buff[0:8];
input clk;
reg [7:0]median_out;
always@(negedge clk)
begin
//**************************************************************************//
for(i=0;i<256;i=i+1) // initilize the memory bins with zeros
b[i]=0;
//*************************************************************************//
buff[0]=a1;
buff[1]=a2;
buff[2]=a3;
buff[3]=a4;
buff[4]=a5;
buff[5]=a6;
buff[6]=a7;
buff[7]=a8;
buff[8]=a9;
for(i=0;i<9;i=i+1) // this loop is for cumulative histogram method
begin
b[buff[i]]=b[buff[i]]+1; // incrementing the value in b[i]th memory address
for(j=0;j<256;j=j+1)
if(j>buff[i])
b[j]=b[j]+1; // incrementing the bins below b[i]th bin
end
//**************************************************************************//
for(i=0;i<256;i=i+1) // loop for finding the median
begin
if(b[i]>4) ///////// condition for checking median
begin
b[i]=1;
median_out=i;
i=256; // loop breaks here
end
end
//*************************************************************************//
end
endmodule
如何使代码可综合?
您的代码生成了多少个加法器?我看到至少有 2,100 个 8 位加法器在同一个周期内工作。
您应该重新考虑您的算法:中值滤波器需要像素值的有序列表,因此首先您应该考虑 FPGA 上数字的高效排序。
一个好的方法是像这样对网络进行排序:
- 奇偶合并排序或
- 双调排序。
无法在一个循环中完成对 9 个数字的排序,因此您需要流水线操作。 (你可以做到,但时钟速度非常低。)
我们的PoC-Library contains pipelined sorting networks,但我从来没有用非两个输入大小的幂测试这些网络!
我同意@Paebbels 在这里所说的一切。但是,还有一些额外的注意事项。数据传入的速度有多快。您是否获得了一组新的 10 个值来对每个时钟周期进行排序?如果不是,您可以流水线操作并使用更少的加法器和寄存器阶段,甚至使用单个加法器并将结果存储在块 RAM 中(尽管这会慢得多)。此外,您还没有提到您使用的是哪种 FPGA(尽管我猜这是一个小的)。任何 FPGA 设计都需要考虑目标设备上的可用资源。如果您的设计中的其他地方未使用加法器,您也可以直接为加法器实例化 DSP48 乘法器-累加器,同样取决于您需要的数量和设备上可用的数量。