我正在设计一个SAO过滤代码,我的代码合成时间太长。 我正在拍摄66x66像素(1 CTU)并为整个画面生成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
答案 0 :(得分:2)
初始块不是首选。
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行代码。代码中有6个其他这样的循环=&gt; 64 * 64 * 6 = 24576多行代码。[并非所有代码都会导致更多寄存器,因为bu是一个常见元素]
它将通过8位8到1 mux =>将mem连接到bu。 4356(实例)* 8 * 8 * X = 278784 * X(272K * X)门数。(X是多路复用器的大小) 设计中还有更多这样的多路复用器。
触发数34855 * 8 + 32767 * 8 + 65 * 65 * 8 + 64 * 64 * 8 = 607544(593 K)。
到目前为止,这个模块本身可以与一个完整的芯片(数百万门)相媲美。
为了使合成器现在更加困难,尺寸和块的功率不是2 - 66,34855,4357
合成器现在很少尝试连接和锻炼这种设计的细节。
Mem1和men再次似乎只是用于输入和输出存储可以移动到块外。男人和mem1将最终(毕竟手工)优化出来,因为男人没有输入,mem1没有输出。此外,可能需要使用状态机重新编写块以降低互连复杂性。此代码尝试在单个时钟周期内执行所有操作(以及8个时钟内的8个操作)。该块需要重置。代码将在功能上起作用,但从综合的角度来看是非常重要的。