Verilog合成需要太长时间

时间:2015-11-02 18:41:01

标签: verilog

我正在尝试编写一个verilog代码来实现640X480像素图像的人口普查变换。我以行为形式编写了完整的代码。但代码合成时间太长。我明白原因可能是长寄存器数组和循环,但我不知道如何处理它 这是我的代码:

module test(in,clk,out
    );
    input clk;
    input [7:0] in;
    output  [119:0]out;
    reg [7:0]matrix[0:639][0:479];
    //reg [119:0]win[0:10][0:10];
    reg [9:0] i = 0;
    reg [8:0] j = 0;
    reg [12:0] count = 0;
    integer p,q = 6;
    integer a,b = -6;
    reg [119:0]censusTransformedImage;
    reg [119:0]census=0;
    always@ (posedge clk)
    begin
        if(count<=6411)
            count = count+1;
    end
    always @ (posedge clk )
    begin
        if(i<=639)
        begin
            matrix[i][j]=in;
            i=i+1;
        end
        else if(i==639 && j<=479)
        begin
            i=0;
            j=j+1;
        end
        //end
    end

    always @ (posedge clk)
    begin
        if(count > 6411)
        begin
            if(p<=634)
            begin
                if(q<=479)
                begin
                    //census = 0;
                    if(a<=6)
                    begin
                        if(b<=6)
                        begin
                            if(~(a==0 && b==0))
                            census=census<<1;
                            if (matrix[p+a][q+b] > matrix[p][q])
                        census=census+1;
                                b = b+1;
                        end
                        else
                        begin
                            b=-6;
                            a=a+1;
                        end 
                    end
                    else
                    begin
                        censusTransformedImage=census;
                        census=0;
                        a=-6;
                        q=q+1;
                    end
                end
                else
                begin
                    q=0;
                    p=p+1;
                end
            end
        end
    end
   assign out = censusTransformedImage;
endmodule

1 个答案:

答案 0 :(得分:0)

合成器可能会尝试将矩阵实现为分布式内存。也就是说,使用取自FPGA片的触发器。必须避免这种情况,因为您只需耗尽FPGA器件的所有资源来实现该存储器。

相反,将矩阵存储器设计为独立模块,具有一个输入地址(坐标i,j),一个8位输出数据和一个8位输入数据。类似的东西:

module matrix (
  input clk,
  input wire [9:0] i,
  input wire [8:0] j,
  input write_enable,
  input wire [7:0] din,
  output reg [7:0] dout
  );

  reg [7:0] M[0:307199]; // your 640x480 matrix
  wire [18:0] addr;

  assign addr = i*640+j; // let's hope the synthesizer is able to
                         // implement this without having to use
                         // an actual multiplication engine
                         // (it shouldn't need to)
  always @(posedge clk) begin
    if (write_enable == 1'b1)
      M[addr] <= din;
    dout <= M[addr];
  end
endmodule

这里的关键点是在每个时钟周期只有一个访问矩阵寄存器(M),并且输入和输出数据都被注册。通过这种方式,合成器将能够利用Block RAM而不是分布式RAM实现这个巨大的寄存器,利用大量切片,加速合成过程。

当然,这也意味着您的控制器必须以这样的方式编写:对于每个时钟周期,只能对您的矩阵执行一次操作,无论是读取还是写入。例如,您不允许在同一时钟周期中读取两个不同的元素。如果在同一时钟周期中需要两个不同的元素(正如您当前的代码所示),请重写此模块,以便提供两组输入坐标以及两个输出数据端口。希望合成器能为它推断出双端口存储器块。

作为测试,指示合成器仅合成矩阵模块并观察有关使用Block RAM实现的M的综合消息,吸收此寄存器等,以确保它不会使用分布式实现RAM再次。