我正在设计一个用于SAO过滤的代码,而我的代码合成起来花了太长时间。我正在拍摄一个66x66像素(1CTU),并为整个帧产生64x64输出。我正在考虑在1帧中8 CTus。
module saocalc(input clk,input[7:0]sao_offset1,input[7:0]sao_offset2,
input[7:0]sao_offset3,input[7:0]sao_offset4,
outputreg[7:0]saoval);
reg[7:0]mem[0:34855];
reg[7:0]mem1[0:32767];
reg[7:0]bu[0:65][0:65];
reg[7:0]sao_out[0:63][0:63];
integer i;
reg[7:0]k=8'd0;
integer j;
reg[7:0]sao_type;
initial
begin
$readmemh("0-7ctus.txt",mem);
end
always@(posedge clk)
begin
if(k<8)
begin
for(j=0;j<66;j=j+1)
begin
for(i=0;i<66;i=i+1)
bu[j][i]<=mem[i+(j*66)+4357*k+1];
end
sao_type<=mem[4357*k];
end
else
k<=0;
k<=k+1;
end
always@(posedge clk)
begin
if(sao_type==8'd0)
begin
for(j=0;j<64;j=j+1)
begin
for(i=1;i<64;i=i+1)
begin
if((bu[j][i]>bu[j][i-1])&&(bu[j][i]>bu[j][i+1]))
saoval=bu[j][i]-sao_offset4;
else if((bu[j][i]<bu[j][i-1])&&(bu[j][i]<bu[j][i+1]))
saoval=bu[j][i]+sao_offset1;
else if(((bu[j][i]<bu[j][i-1])&&(bu[j][i]==bu[j][i+1]))||
((bu[j][i]==bu[j][i-1])&&(bu[j][i]<bu[j][i+1])))
saoval=bu[j][i]+sao_offset2;
else if(((bu[j][i]==bu[j][i-1])&&(bu[j][i]>bu[j][i+1]))||
((bu[j][i]>bu[j][i-1])&&(bu[j][i]==bu[j][i+1])))
saoval=bu[j][i]-sao_offset3;
else
saoval=bu[j][i];
sao_out[j][i]=saoval;
end
sao_out[j][0]=bu[j][0];
end
end
else if(sao_type==8'd1)
begin
for(i=0;i<64;i=i+1)
begin
for(j=1;j<64;j=j+1)
begin
if((bu[j][i]>bu[j-1][i])&&(bu[j][i]>bu[j+1][i]))
saoval=bu[j][i]-sao_offset4;
else if((bu[j][i]<bu[j-1][i])&&(bu[j][i]<bu[j+1][i]))
saoval=bu[j][i]+sao_offset1;
else if(((bu[j][i]<bu[j-1][i])&&(bu[j][i]==bu[j+1][i]))||
((bu[j][i]==bu[j-1][i])&&(bu[j][i]<bu[j+1][i])))
saoval=bu[j][i]+sao_offset2;
else if(((bu[j][i]==bu[j-1][i])&&(bu[j][i]>bu[j+1][i]))||
((bu[j][i]>bu[j-1][i])&&(bu[j][i]==bu[j+1][i])))
saoval=bu[j][i]-sao_offset3;
else
saoval=bu[j][i];
sao_out[j][i]=saoval;
end
sao_out[0][i]=bu[0][i];
end
end
else if(sao_type==8'd2)
begin
for(j=1;j<64;j=j+1)
begin
for(i=1;i<64;i=i+1)
begin
if((bu[j][i]>bu[j-1][i-1])&&(bu[j][i]>bu[j+1][i+1]))
saoval=bu[j][i]-sao_offset4;
else if((bu[j][i]<bu[j-1][i-1])&&(bu[j][i]<bu[j+1][i+1]))
saoval=bu[j][i]+sao_offset1;
else if(((bu[j][i]<bu[j-1][i-1])&&(bu[j][i]==bu[j+1][i+1]))||
((bu[j][i]==bu[j-1][i-1])&&(bu[j][i]<bu[j+1][i+1])))
saoval=bu[j][i]+sao_offset2;
else if(((bu[j][i]==bu[j-1][i-1])&&(bu[j][i]>bu[j+1][i+1]))||
((bu[j][i]>bu[j-1][i-1])&&(bu[j][i]==bu[j+1][i+1])))
saoval=bu[j][i]-sao_offset3;
else
saoval=bu[j][i];
sao_out[j][i]=saoval;
sao_out[0][i]=bu[0][i];
end
sao_out[j][0]=bu[j][0];
sao_out[0][0]=bu[0][0];
end
end
else if(sao_type==8'd3)
begin
for(j=1;j<64;j=j+1)
begin
for(i=1;i<64;i=i+1)
begin
if((bu[j][i]>bu[j-1][i+1])&&(bu[j][i]>bu[j+1][i-1]))
saoval=bu[j][i]-sao_offset4;
else if((bu[j][i]<bu[j-1][i+1])&&(bu[j][i]<bu[j+1][i-1]))
saoval=bu[j][i]+sao_offset1;
else if(((bu[j][i]<bu[j-1][i+1])&&(bu[j][i]==bu[j+1][i-1]))||
((bu[j][i]==bu[j-1][i+1])&&(bu[j][i]<bu[j+1][i-1])))
saoval=bu[j][i]+sao_offset2;
else if(((bu[j][i]==bu[j-1][i+1])&&(bu[j][i]>bu[j+1][i-1]))||
((bu[j][i]>bu[j-1][i+1])&&(bu[j][i]==bu[j+1][i-1])))
saoval=bu[j][i]-sao_offset3;
else
saoval=bu[j][i];
sao_out[j][i]=saoval;
sao_out[0][i]=bu[0][i];
end
sao_out[j][0]=bu[j][0];
sao_out[0][0]=bu[0][0];
end
end
else if(sao_type==8'd4)
begin
for(i=0;i<64;i=i+1)
begin
for(j=0;j<64;j=j+1)
begin
if((bu[i][j]>7)&&(bu[i][j]<16))
saoval=bu[i][j]+sao_offset1;
else if((bu[i][j]>15)&&(bu[i][j]<24))
saoval=bu[i][j]+sao_offset2;
else if((bu[i][j]>23)&&(bu[i][j]<32))
saoval=bu[i][j]-sao_offset3;
else if((bu[i][j]>31)&&(bu[i][j]<40))
saoval=bu[i][j]-sao_offset4;
else
saoval=bu[i][j];
sao_out[i][j]=saoval;
end
end
end
else
saoval=3;
end
always@(posedge clk)
begin
for(j=0;j<64;j=j+1)
begin
for(i=0;i<64;i=i+1)
mem1[j+(i*64)+(4096*k)]=sao_out[j][i];
end
end
endmodule发布于 2016-07-10 22:48:46
在可合成代码中,初始块不是首选的。
mem和mem1看起来像是测试平台代码。男性不会从外部获得任何输入,mem1也不会输出任何输出。
如果它们仅用于加载和存储数据,则可以将它们移到saocalc模块之外。
always@(posedge clk)
begin
if(k<8)
begin
for(j=0;j<66;j=j+1)
begin
for(i=0;i<66;i=i+1)
bu[j][i]<=mem[i+(j*66)+4357*k+1];
mem [sao_offset3][sao_offset4] = sao_offset1;
end
sao_type<=mem[4357*k];
end
else
k<=0;
k<=k+1;
end上面的代码用于加载缓冲区。合成器将展开循环。即,它将循环替换为
buj[0][0] = mem[4357*k+1] ;
buj[0][1] = mem[1+4357*k+1] ;
.....
.....
buj[65][65] = mem[65+66*65+4357*k+1] ;创建66*66 = 4356行代码。在代码=> 64*64*6 = 24576多行代码中还有6个这样的循环。并不是所有的都会导致更多的寄存器,因为bu是一个公共元素
它将通过8位8到1多路复用器=> 4356 (实例)*8*8 *X = 278784*X ( 272K *X)数量的门将mem连接到bu。(X是多路复用器的大小)在设计中有更多这样的多路复用器。
flops数34855*8+32767*8+65*65*8+64*64*8 = 607544 (593K)。
到目前为止,这个模块正在与一个完整的芯片(数百万门)本身相抗衡。
让事情变得更加困难的合成器现在,大小和块不在2- 66,34855,4357的幂
合成器现在有它的一小部分试图连接和解决这个设计的细节。
Mem1和can再次显示为仅用于输入和输出存储可以移动到块之外。男人和mem1最终将被优化(在所有的手工工作之后),因为男人没有输入,mem1没有输出。此外,可能需要使用状态机重写该块,以降低互连复杂性。此代码尝试在单个时钟周期内执行所有操作(在8个时钟周期内执行8个操作)。该块需要重置。代码将在功能上工作,但从综合的角度来看是巨大的。
https://stackoverflow.com/questions/38279318
复制相似问题