合成需要太长时间

时间:2016-07-09 07:07:26

标签: verilog

我正在设计一个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

1 个答案:

答案 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个操作)。该块需要重置。代码将在功能上起作用,但从综合的角度来看是非常重要的。