zoukankan      html  css  js  c++  java
  • 维纳滤波器

    最近刚好要处理项目中噪声大的问题,在网上看到这篇博客,就用FPGA实现了一下,效果还可以,原文https://blog.csdn.net/baimafujinji/article/details/73302911

    下面是基于HSV数据格式的维纳滤波器

    module winnerfilter(
      input wire          clk,
      input wire          reset,
      input wire          vdin,
      input wire          hdin,
      input wire[8:0]     din_h,
      input wire[7:0]     din_s,
      input wire[7:0]     din_v,
      
      output reg          vdout,
      output reg          hdout,
      output reg[8:0]     dout_h,
      output reg[7:0]     dout_s,
      output reg[7:0]     dout_v
    );
    
      reg                 vdin_d0; 
      reg[37:0]           hdin_dly; 
      reg[7:0]            din_dly[5:0];
      
      
      reg[11:0]           hd_data;
      reg[11:0]           vd_data;
      
    //==================================================//  
      reg                 wr_en_h;
      (*KEEP = "TRUE"*)reg                 wr_en_s;
      
      reg                 rd_en_h;
      (*KEEP = "TRUE"*)reg                 rd_en_s;
      
      reg[8:0]            din4;
      reg[7:0]            din5;
      
      wire[8:0]           dout4;
      wire[7:0]           dout5;
      
      reg[8:0]            dout4_dly[34:0];
      reg[7:0]            dout5_dly[34:0];
    //=================================================// 
      
      reg                 wr_en1;
      reg                 wr_en2;
      reg                 wr_en3;
      
      reg                 rd_en1;
      reg                 rd_en2;
      reg                 rd_en3;
      
      reg [7:0]           din1;
      reg [7:0]           din2;
      reg [7:0]           din3;
      
      wire[7:0]           dout1;
      wire[7:0]           dout2;
      wire[7:0]           dout3;
      
      reg[7:0]            dout1_d0;
      reg[7:0]            dout1_d1;
      reg[7:0]            dout1_d2;
      reg[7:0]            dout1_d3;
      
      reg[7:0]            dout2_d0;
      reg[7:0]            dout2_d1;
      reg[7:0]            dout2_d2;
      reg[7:0]            dout2_d3;
      
      (*KEEP = "TRUE"*)reg[7:0]            dout3_dly[34:0];
      
      reg[9:0]            line_1;
      reg[9:0]            line_2;
      reg[9:0]            line_3;
      reg[9:0]            line_4;
      
      wire[11:0]          temp;
      reg [7:0]           avg_window;
      
      reg [7:0]           a2;
      reg [7:0]           b2;
      wire[15:0]          p2;
      
      reg [7:0]           a4;
      reg [7:0]           b4;
      wire[15:0]          p4;
      
      reg [7:0]           a5;
      reg [7:0]           b5;
      wire[15:0]          p5;
      
      reg [7:0]           a6;
      reg [7:0]           b6;
      wire[15:0]          p6;
      
      reg [7:0]           a7;
      reg [7:0]           b7;
      wire[15:0]          p7;
      
      reg [15:0]          p4_d0;
      reg [15:0]          p4_d1;
      reg [15:0]          p4_d2;
      reg [15:0]          p4_d3;
      
      reg [15:0]          p5_d0;
      reg [15:0]          p5_d1;
      reg [15:0]          p5_d2;
      reg [15:0]          p5_d3;
      
      reg [15:0]          p6_d0;
      reg [15:0]          p6_d1;
      reg [15:0]          p6_d2;
      reg [15:0]          p6_d3;
      
      reg [15:0]          p7_d0;
      reg [15:0]          p7_d1;
      reg [15:0]          p7_d2;
      reg [15:0]          p7_d3;
      
      reg [17:0]          sum_1;
      reg [17:0]          sum_2;
      reg [17:0]          sum_3;
      reg [17:0]          sum_4;
      
      reg [19:0]          temp3;
      
      reg [15:0]          variance_window;
      reg [37:0]          temp2;
      reg [21:0]          numbel;
      
      reg                 srst;
      
      reg[23:0]           dividend1;
      reg[15:0]           divisor1;
      wire[23:0]          quotient1;
      
      reg[7:0]            diff_value;
      
      reg[15:0]           a3;
      reg[7:0]            b3;
      wire[23:0]          p3;
      
      reg[23:0]           dividend2;
      reg[15:0]           divisor2;
      wire[23:0]          quotient2;
      
      reg                 flag;
      reg                 flag_diff_value;
      reg[33:0]           flag_diff_value_dly;
      
      always@(posedge clk)
        hdin_dly <= {hdin_dly[36:0],hdin};
      
      always@(posedge clk)
        begin
          vdin_d0 <= vdin;    
        end
                                           
      always@(posedge clk)
        begin
          din_dly[0] <= din_v;
          dout3_dly[0] <= dout3;
        end
        
      always@(posedge clk)
        begin:u1
          integer i;
            for(i=0;i<5;i=i+1)
              begin
                din_dly[i+1] <= din_dly[i];          
              end
        end     
    
      always@(posedge clk)
        begin:u2
          integer i;
            for(i=0;i<34;i=i+1)
              begin
                dout3_dly[i+1] <= dout3_dly[i];
              end
        end            
    
    //列计数  
      always@(posedge clk or posedge reset)
        if(reset)
          hd_data <= 12'd0;
        else if(vdin==1 && vdin_d0==0)
          hd_data <= 12'd0;
        else if(hd_data==12'd2093)
          hd_data <= 12'd0;
        else 
          hd_data <= hd_data + 1'd1;
    
    //行计数  
      always@(posedge clk or posedge reset)
        if(reset)
          vd_data <= 12'd0;
        else if(vdin==1 && vdin_d0==0)
          vd_data <= 12'd0;
        else if(hd_data==12'd2093)
          vd_data <= vd_data + 1'd1;
          
    //===============================================================//
      always@(posedge clk)
        begin
          dout4_dly[0] <= dout4;
          dout5_dly[0] <= dout5;
        end
         
      always@(posedge clk)
        begin:u3
          integer i;
          for(i=0;i<34;i=i+1)
            begin
              dout4_dly[i+1] <= dout4_dly[i];
              dout5_dly[i+1] <= dout5_dly[i];
            end
        end 
        
    //=======================================================================//
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en_h <= 1'd0;
        else 
          wr_en_h <= hdin;
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en_h <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1440)
          rd_en_h <= hdin;
        else
           rd_en_h <= 1'd0;
            
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en_s <= 1'd0;
        else 
          wr_en_s <= hdin;
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en_s <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1440)
          rd_en_s <= hdin;
        else
           rd_en_s <= 1'd0;
            
      always@(posedge clk or posedge reset)
        if(reset)
          din4 <= 9'd0;
        else if(vdin && hdin)
          din4 <= din_h;
        else 
          din4 <= 9'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din5 <= 8'd0;
        else if(vdin && hdin)
          din5 <= din_s;
        else 
          din5 <= 8'd0;        
    //===============================================================//    
    
    //4x4窗口
    //缓存第一行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en3 <= 1'd0;
        else 
          wr_en3 <= hdin;
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en3 <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1440)
          rd_en3 <= hdin;
        else
           rd_en3 <= 1'd0;
    
    //缓存第二行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en2 <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1439)
          wr_en2 <= hdin_dly[1];
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en2 <= 1'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          rd_en2 <= hdin;
    
    //缓存第三行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en1 <= 1'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          wr_en1 <= hdin_dly[1];
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en1 <= 1'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          rd_en1 <= hdin;
    
          
      always@(posedge clk or posedge reset)
        if(reset)
          din3 <= 8'd0;
        else if(vdin && hdin)
          din3 <= din_v;
        else 
          din3 <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din2 <= 8'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1439)
          din2 <= dout3;
        else 
          din2 <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din1 <= 8'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          din1 <= dout2;
        else
          din1 <= 8'd0;
       
      always@(posedge clk)
          begin
            dout1_d0 <= dout1;
            dout1_d1 <= dout1_d0;
            dout1_d2 <= dout1_d1;
            dout1_d3 <= dout1_d2;
            
            dout2_d0 <= dout2;
            dout2_d1 <= dout2_d0;
            dout2_d2 <= dout2_d1;
            dout2_d3 <= dout2_d2;        
          end 
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_1 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_1 <= dout1_d3 + dout1_d2 + dout1_d1 + dout1_d0;
        else 
          line_1 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_2 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_2 <= dout2_d3 + dout2_d2 + dout2_d1 + dout2_d0;
        else 
          line_2 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_3 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_3 <= dout3_dly[3] + dout3_dly[2] + dout3_dly[1] + dout3_dly[0];
        else 
          line_3 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_4 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_4 <= din_dly[5] + din_dly[4] + din_dly[3] + din_dly[2];
        else 
          line_4 <= 10'd0;    
      
      assign temp = line_1 + line_2 + line_3 + line_4;
    
    //4x4窗口均值  
      always@(posedge clk or posedge reset)
        if(reset)
          avg_window <= 8'd0;
        else if(vd_data>=12'd3 && hdin_dly[6]==1)
          avg_window <= temp[11:4];
        else
          avg_window <= 8'd0;
    
    //计算4x4窗口平方的均值        
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            a4 <= 8'd0;
            b4 <= 8'd0;
              
            a5 <= 8'd0;
            b5 <= 8'd0;
              
            a6 <= 8'd0;
            b6 <= 8'd0;
              
            a7 <= 8'd0;
            b7 <= 8'd0;
          end
        else if(vd_data>=12'd3 && hdin_dly[1]==1)
          begin
            a4 <= dout1;
            b4 <= dout1;
              
            a5 <= dout2;
            b5 <= dout2;
              
            a6 <= dout3;
            b6 <= dout3;
              
            a7 <= din_dly[1];
            b7 <= din_dly[1];
          end
            
      always@(posedge clk)
          begin
            p4_d0 <= p4;  
            p4_d1 <= p4_d0;
            p4_d2 <= p4_d1;
            p4_d3 <= p4_d2;
              
            p5_d0 <= p5;  
            p5_d1 <= p5_d0;
            p5_d2 <= p5_d1;
            p5_d3 <= p5_d2;
              
            p6_d0 <= p6;  
            p6_d1 <= p6_d0;
            p6_d2 <= p6_d1;
            p6_d3 <= p6_d2;
              
            p7_d0 <= p7;  
            p7_d1 <= p7_d0;
            p7_d2 <= p7_d1;
            p7_d3 <= p7_d2;       
          end
          
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            sum_1 <= 18'd0;
            sum_2 <= 18'd0;
            sum_3 <= 18'd0;
            sum_4 <= 18'd0;
          end  
        else if(vd_data>=12'd3 && hdin_dly[7]==1)
          begin
            sum_1 <= p4_d0 + p4_d1 + p4_d2 + p4_d3;
            sum_2 <= p5_d0 + p5_d1 + p5_d2 + p5_d3;
            sum_3 <= p6_d0 + p6_d1 + p6_d2 + p6_d3;
            sum_4 <= p7_d0 + p7_d1 + p7_d2 + p7_d3;
          end
        else 
          begin
            sum_1 <= 18'd0;
            sum_2 <= 18'd0;
            sum_3 <= 18'd0;
            sum_4 <= 18'd0;
          end
            
      always@(posedge clk or posedge reset)
        if(reset)
          temp3 <= 20'd0; 
        else if(vd_data>=12'd3 && hdin_dly[8]==1)
          temp3 <= sum_1 + sum_2 + sum_3 + sum_4;
        else 
          temp3 <= 20'd0;
                
      always@(posedge clk or posedge reset)
        if(reset)
          begin      
            a2 <= 8'd0;
            a2 <= 8'd0;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin      
            a2 <= avg_window;
            b2 <= avg_window;
          end
        else 
          begin       
            a2 <= 8'd0;
            b2 <= 8'd0;
          end
            
      always@(posedge clk or posedge reset)
        if(reset)
           flag <= 1'd0;
        else if(temp3[19:4]>p2)
           flag <= 1'd1;
        else 
           flag <= 1'd0;
      
    //4x4窗口里的平方差
      always@(posedge clk or posedge reset)
        if(reset)
          variance_window <= 16'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(temp3[19:4]>p2)
              variance_window <= temp3[19:4] - p2;
            else
              variance_window <= p2 - temp3[19:4];
          end
        else
          variance_window <= 16'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          temp2 <= 38'd0;
        else if(vdin==1'd1 && vdin_d0==1'd0)
          temp2 <= 38'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10] && hdin_dly[7])
                  begin
                      if(flag==1)
                  temp2 <= temp2 + variance_window;
                        else
                          temp2 <= temp2 - variance_window;
                    end
          end 
          
      always@(posedge clk or posedge reset)
        if(reset)
          numbel <= 22'd0;
        else if(vdin==1'd1 && vdin_d0==1'd0)
          numbel <= 22'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10] && hdin_dly[7])
              numbel <= numbel + 1'd1;
          end
         
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            dividend1 <= 24'd0;
            divisor1  <= 16'd1;
          end   
        else if(vdin==1'd0 && vdin_d0==1'd1)
          begin
            dividend1 <= temp2[37:14];
            divisor1  <= {8'd0,numbel[21:14]};
          end
    
    //4x4窗口差值  像素值 - 窗口均值  (有正负值)
      always@(posedge clk or posedge reset)
        if(reset)
          diff_value <= 8'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[7])
              begin
                if(dout3_dly[4]>avg_window)
                  diff_value <= dout3_dly[4] - avg_window;
                else
                  diff_value <= avg_window - dout3_dly[4];
              end
            else
              diff_value <= 8'd0;
          end
        else
          diff_value <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          flag_diff_value <= 1'd0;
        else if(dout3_dly[4]>=avg_window)
          flag_diff_value <= 1'd1;
        else
          flag_diff_value <= 1'd0;
          
      always@(posedge clk)
        flag_diff_value_dly <= {flag_diff_value_dly[32:0],flag_diff_value}; 
      
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            a3 <= 16'd0;
            b3 <= 8'd0;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[8])
              begin
                a3 <= quotient1[15:0];
                b3 <= diff_value;
              end
            else
              begin
                a3 <= 16'd0;
                b3 <= 8'd0;
              end
          end
        else
          begin
            a3 <= 16'd0;
            b3 <= 8'd0;
          end
          
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            dividend2 <= 24'd0;
            divisor2  <= 16'd1;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10])
              begin
                if(variance_window>quotient1)
                  begin
                    dividend2 <= p3;
                    divisor2  <= variance_window;
                  end
                else
                  begin
                    dividend2 <= p3;
                    divisor2  <= quotient1[15:0];
                  end
              end
            else
              begin
                dividend2 <= 24'd0;
                divisor2  <= 16'd1;
              end
          end
        else
          begin
            dividend2 <= 24'd0;
            divisor2  <= 16'd1;
          end
      
            
      always@(posedge clk or posedge reset)
        if(reset)
          dout_v <= 8'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[35] && hdin_dly[37])
              begin
                if(flag_diff_value_dly[28]==1)
                  begin
                    if(dout3_dly[34]>quotient2)
                      dout_v <= dout3_dly[34] - quotient2;
                    else
                      dout_v <= 8'd0;
                  end
                else
                  begin
                    if(dout3_dly[34]+quotient2>=8'd255)
                      dout_v <= 8'd255;
                    else
                      dout_v <= dout3_dly[34] + quotient2;
                  end
              end
            else
              dout_v <= dout3_dly[34];
          end
        else
          dout_v <= dout3_dly[34];
          
    //=====================================================//
      always@(posedge clk or posedge reset)
        if(reset)
            dout_h <= 9'd0;
        else
          dout_h <= dout4_dly[34];
            
      always@(posedge clk or posedge reset)
        if(reset)
            dout_s <= 8'd0;
        else 
          dout_s <= dout5_dly[34];
    //=====================================================//
          
      always@(posedge clk or posedge reset)
        if(reset)
          vdout <= 1'd0;
        else if(vd_data==12'd1 && hd_data==12'd36)
          vdout <= 1'd1;
        else if(vd_data==12'd1441 && hd_data==12'd2093)
          vdout <= 1'd0;
    
      always@(posedge clk or posedge reset)
        if(reset)
          hdout <= 1'd0;
        else if(vdout==1)
          begin
            if(hd_data>=12'd62 && hd_data<=12'd1981)
              hdout <= 1'd1;
            else
              hdout <= 1'd0;
          end
        else
          hdout <= 1'd0;
          
      
      always@(posedge clk or posedge reset)
        if(reset)
          srst <= 1'd0;
        else if(vd_data==12'd1450)
          srst <= 1'd1;
        else 
          srst <= 1'd0;  
          
    //========================================================================//
    fifo_1920x9 fifo_h (
      .clk           (clk    ), // input clk
      .srst          (srst   ), // input srst
      .din           (din4   ), // input [8 : 0] din
      .wr_en         (wr_en_h), // input wr_en
      .rd_en         (rd_en_h), // input rd_en
      .dout          (dout4  ), // output [8 : 0] dout
      .full          (       ), // output full
      .empty         (       )  // output empty
    );
    
    fifo_1920x8 fifo_s (
      .clk           (clk    ), // input clk
      .srst          (srst   ), // input srst
      .din           (din5   ), // input [7 : 0] din
      .wr_en         (wr_en_s), // input wr_en
      .rd_en         (rd_en_s), // input rd_en
      .dout          (dout5  ), // output [7 : 0] dout
      .full          (       ), // output full
      .empty         (       )  // output empty
    );
    //========================================================================//      
    
      
    fifo_1920x8 fifo1 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din1  ), // input [7 : 0] din
      .wr_en         (wr_en1), // input wr_en
      .rd_en         (rd_en1), // input rd_en
      .dout          (dout1 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    fifo_1920x8 fifo2 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din2  ), // input [7 : 0] din
      .wr_en         (wr_en2), // input wr_en
      .rd_en         (rd_en2), // input rd_en
      .dout          (dout2 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    fifo_1920x8 fifo3 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din3  ), // input [7 : 0] din
      .wr_en         (wr_en3), // input wr_en
      .rd_en         (rd_en3), // input rd_en
      .dout          (dout3 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    //u8xu8   avg_window*avg_window;
    mult_u8_u8  u_mult_u8_u8_2(
      .clk           (clk   ),
      .a             (a2    ),
      .b             (b2    ),
      .p             (p2    )
    );
    
    //u8xu8   dout1*dout1;
    mult_u8_u8  u_mult_u8_u8_4(
      .clk           (clk   ),
      .a             (a4    ),
      .b             (b4    ),
      .p             (p4    )
    );
    
    //u8xu8   dout2*dout2;
    mult_u8_u8  u_mult_u8_u8_5(
      .clk           (clk   ),
      .a             (a5    ),
      .b             (b5    ),
      .p             (p5    )
    );
    
    //u8xu8   dout3*dout3;
    mult_u8_u8  u_mult_u8_u8_6(
      .clk           (clk   ),
      .a             (a6    ),
      .b             (b6    ),
      .p             (p6    )
    );
    
    //u8xu8   din*din;
    mult_u8_u8  u_mult_u8_u8_7(
      .clk           (clk   ),
      .a             (a7    ),
      .b             (b7    ),
      .p             (p7    )
    );
    
    //计算噪声的方差
    div_u21_u13 u_div_u24_u16_1 (
        .clk           (clk       ), // input clk
        .rfd           (          ), // output rfd
        .dividend      (dividend1 ), // input [30 : 0] dividend
        .divisor       (divisor1  ), // input [15 : 0] divisor
        .quotient      (quotient1 ), // output [20 : 0] quotient
        .fractional    (          )  // output [6 : 0] fractional
        );
        
    //u16*u8    diff_value*quotient1;
    mult_u13_u8  u_mult_u13_u8(
      .clk           (clk   ),
      .a             (a3    ),
      .b             (b3    ),
      .p             (p3    )
    );
    
    div_u21_u13 u_div_u24_u16_2 (
        .clk           (clk       ), // input clk
        .rfd           (          ), // output rfd
        .dividend      (dividend2 ), // input [30 : 0] dividend
        .divisor       (divisor2  ), // input [15 : 0] divisor
        .quotient      (quotient2 ), // output [20 : 0] quotient
        .fractional    (          )  // output [6 : 0] fractional
        );
        
    endmodule
    View Code

    这是基于RGB数据格式的维纳滤波器

    module winnerfilter(
      input wire          clk,
      input wire          reset,
      input wire          vdin,
      input wire          hdin,
      input wire[7:0]     din,
      
      output reg          vdout,
      output reg          hdout,
      output reg[7:0]     dout
    );
    
      reg                 vdin_d0; 
      reg[37:0]           hdin_dly; 
      reg[7:0]            din_dly[5:0];
      
      
      reg[11:0]           hd_data;
      reg[11:0]           vd_data;
      
      reg                 wr_en1;
      reg                 wr_en2;
      reg                 wr_en3;
      
      reg                 rd_en1;
      reg                 rd_en2;
      reg                 rd_en3;
      
      reg [7:0]           din1;
      reg [7:0]           din2;
      reg [7:0]           din3;
      
      wire[7:0]           dout1;
      wire[7:0]           dout2;
      wire[7:0]           dout3;
      
      reg[7:0]            dout1_d0;
      reg[7:0]            dout1_d1;
      reg[7:0]            dout1_d2;
      reg[7:0]            dout1_d3;
      
      reg[7:0]            dout2_d0;
      reg[7:0]            dout2_d1;
      reg[7:0]            dout2_d2;
      reg[7:0]            dout2_d3;
      
      (*KEEP = "TRUE"*)reg[7:0]            dout3_dly[34:0];
      reg[9:0]            line_1;
      reg[9:0]            line_2;
      reg[9:0]            line_3;
      reg[9:0]            line_4;
      
      wire[11:0]          temp;
      reg [7:0]           avg_window;
      
      reg [7:0]           a2;
      reg [7:0]           b2;
      wire[15:0]          p2;
      
      reg [7:0]           a4;
      reg [7:0]           b4;
      wire[15:0]          p4;
      
      reg [7:0]           a5;
      reg [7:0]           b5;
      wire[15:0]          p5;
      
      reg [7:0]           a6;
      reg [7:0]           b6;
      wire[15:0]          p6;
      
      reg [7:0]           a7;
      reg [7:0]           b7;
      wire[15:0]          p7;
      
      reg [15:0]          p4_d0;
      reg [15:0]          p4_d1;
      reg [15:0]          p4_d2;
      reg [15:0]          p4_d3;
      
      reg [15:0]          p5_d0;
      reg [15:0]          p5_d1;
      reg [15:0]          p5_d2;
      reg [15:0]          p5_d3;
      
      reg [15:0]          p6_d0;
      reg [15:0]          p6_d1;
      reg [15:0]          p6_d2;
      reg [15:0]          p6_d3;
      
      reg [15:0]          p7_d0;
      reg [15:0]          p7_d1;
      reg [15:0]          p7_d2;
      reg [15:0]          p7_d3;
      
      reg [17:0]          sum_1;
      reg [17:0]          sum_2;
      reg [17:0]          sum_3;
      reg [17:0]          sum_4;
      
      reg [19:0]          temp3;
      
      reg [15:0]          variance_window;
      reg [37:0]          temp2;
      reg [21:0]          numbel;
      
      reg                 srst;
      
      reg[23:0]           dividend1;
      reg[15:0]           divisor1;
      wire[23:0]          quotient1;
      
      reg[7:0]            diff_value;
      
      reg[15:0]           a3;
      reg[7:0]            b3;
      wire[23:0]          p3;
      
      reg[23:0]           dividend2;
      reg[15:0]           divisor2;
      wire[23:0]          quotient2;
      
      reg                 flag;
      reg                 flag_diff_value;
      reg[33:0]           flag_diff_value_dly;
      
      always@(posedge clk)
        hdin_dly <= {hdin_dly[36:0],hdin};
      
      always@(posedge clk)
        begin
          vdin_d0 <= vdin;    
        end
                                           
      always@(posedge clk)
        begin
          din_dly[0] <= din;
          dout3_dly[0] <= dout3;
        end
        
      always@(posedge clk)
        begin:u1
          integer i;
            for(i=0;i<5;i=i+1)
              begin
                din_dly[i+1] <= din_dly[i];          
              end
        end     
    
      always@(posedge clk)
        begin:u2
          integer i;
            for(i=0;i<34;i=i+1)
              begin
                dout3_dly[i+1] <= dout3_dly[i];
              end
        end       
    
    //列计数  
      always@(posedge clk or posedge reset)
        if(reset)
          hd_data <= 12'd0;
        else if(vdin==1 && vdin_d0==0)
          hd_data <= 12'd0;
        else if(hd_data==12'd2093)
          hd_data <= 12'd0;
        else 
          hd_data <= hd_data + 1'd1;
    
    //行计数  
      always@(posedge clk or posedge reset)
        if(reset)
          vd_data <= 12'd0;
        else if(vdin==1 && vdin_d0==0)
          vd_data <= 12'd0;
        else if(hd_data==12'd2093)
          vd_data <= vd_data + 1'd1;
    
    //4x4窗口
    //缓存第一行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en3 <= 1'd0;
        else 
          wr_en3 <= hdin;
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en3 <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1440)
          rd_en3 <= hdin;
        else
           rd_en3 <= 1'd0;
    
    //缓存第二行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en2 <= 1'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1439)
          wr_en2 <= hdin_dly[1];
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en2 <= 1'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          rd_en2 <= hdin;
    
    //缓存第三行数据      
      always@(posedge clk or posedge reset)
        if(reset)
          wr_en1 <= 1'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          wr_en1 <= hdin_dly[1];
          
      always@(posedge clk or posedge reset)
        if(reset)
          rd_en1 <= 1'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          rd_en1 <= hdin;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din3 <= 8'd0;
        else if(vdin && hdin)
          din3 <= din;
        else 
          din3 <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din2 <= 8'd0;
        else if(vd_data>=12'd1 && vd_data<=12'd1439)
          din2 <= dout3;
        else 
          din2 <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          din1 <= 8'd0;
        else if(vd_data>=12'd2 && vd_data<=12'd1439)
          din1 <= dout2;
        else
          din1 <= 8'd0;
       
      always@(posedge clk)
          begin
            dout1_d0 <= dout1;
            dout1_d1 <= dout1_d0;
            dout1_d2 <= dout1_d1;
            dout1_d3 <= dout1_d2;
            
            dout2_d0 <= dout2;
            dout2_d1 <= dout2_d0;
            dout2_d2 <= dout2_d1;
            dout2_d3 <= dout2_d2;        
          end 
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_1 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_1 <= dout1_d3 + dout1_d2 + dout1_d1 + dout1_d0;
        else 
          line_1 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_2 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_2 <= dout2_d3 + dout2_d2 + dout2_d1 + dout2_d0;
        else 
          line_2 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_3 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_3 <= dout3_dly[3] + dout3_dly[2] + dout3_dly[1] + dout3_dly[0];
        else 
          line_3 <= 10'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          line_4 <= 10'd0;
        else if(vd_data>=12'd3 && hdin_dly[5]==1)
          line_4 <= din_dly[5] + din_dly[4] + din_dly[3] + din_dly[2];
        else 
          line_4 <= 10'd0;    
      
      assign temp = line_1 + line_2 + line_3 + line_4;
    
    //4x4窗口均值  
      always@(posedge clk or posedge reset)
        if(reset)
          avg_window <= 8'd0;
        else if(vd_data>=12'd3 && hdin_dly[6]==1)
          avg_window <= temp[11:4];
        else
          avg_window <= 8'd0;
    
    //计算4x4窗口平方的均值        
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            a4 <= 8'd0;
            b4 <= 8'd0;
              
            a5 <= 8'd0;
            b5 <= 8'd0;
              
            a6 <= 8'd0;
            b6 <= 8'd0;
              
            a7 <= 8'd0;
            b7 <= 8'd0;
          end
        else if(vd_data>=12'd3 && hdin_dly[1]==1)
          begin
            a4 <= dout1;
            b4 <= dout1;
              
            a5 <= dout2;
            b5 <= dout2;
              
            a6 <= dout3;
            b6 <= dout3;
              
            a7 <= din_dly[1];
            b7 <= din_dly[1];
          end
            
      always@(posedge clk)
          begin
            p4_d0 <= p4;  
            p4_d1 <= p4_d0;
            p4_d2 <= p4_d1;
            p4_d3 <= p4_d2;
              
            p5_d0 <= p5;  
            p5_d1 <= p5_d0;
            p5_d2 <= p5_d1;
            p5_d3 <= p5_d2;
              
            p6_d0 <= p6;  
            p6_d1 <= p6_d0;
            p6_d2 <= p6_d1;
            p6_d3 <= p6_d2;
              
            p7_d0 <= p7;  
            p7_d1 <= p7_d0;
            p7_d2 <= p7_d1;
            p7_d3 <= p7_d2;       
          end
          
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            sum_1 <= 18'd0;
            sum_2 <= 18'd0;
            sum_3 <= 18'd0;
            sum_4 <= 18'd0;
          end  
        else if(vd_data>=12'd3 && hdin_dly[7]==1)
          begin
            sum_1 <= p4_d0 + p4_d1 + p4_d2 + p4_d3;
            sum_2 <= p5_d0 + p5_d1 + p5_d2 + p5_d3;
            sum_3 <= p6_d0 + p6_d1 + p6_d2 + p6_d3;
            sum_4 <= p7_d0 + p7_d1 + p7_d2 + p7_d3;
          end
        else 
          begin
            sum_1 <= 18'd0;
            sum_2 <= 18'd0;
            sum_3 <= 18'd0;
            sum_4 <= 18'd0;
          end
            
      always@(posedge clk or posedge reset)
        if(reset)
          temp3 <= 20'd0; 
        else if(vd_data>=12'd3 && hdin_dly[8]==1)
          temp3 <= sum_1 + sum_2 + sum_3 + sum_4;
        else 
          temp3 <= 20'd0;
                
      always@(posedge clk or posedge reset)
        if(reset)
          begin      
            a2 <= 8'd0;
            a2 <= 8'd0;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin      
            a2 <= avg_window;
            b2 <= avg_window;
          end
        else 
          begin       
            a2 <= 8'd0;
            b2 <= 8'd0;
          end
            
      always@(posedge clk or posedge reset)
        if(reset)
           flag <= 1'd0;
        else if(temp3[19:4]>p2)
           flag <= 1'd1;
        else 
           flag <= 1'd0;
      
    //4x4窗口里的平方差
      always@(posedge clk or posedge reset)
        if(reset)
          variance_window <= 16'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(temp3[19:4]>p2)
              variance_window <= temp3[19:4] - p2;
            else
              variance_window <= p2 - temp3[19:4];
          end
        else
          variance_window <= 16'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          temp2 <= 38'd0;
        else if(vdin==1'd1 && vdin_d0==1'd0)
          temp2 <= 38'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10] && hdin_dly[7])
                  begin
                      if(flag==1)
                  temp2 <= temp2 + variance_window;
                        else
                          temp2 <= temp2 - variance_window;
                    end
          end 
          
      always@(posedge clk or posedge reset)
        if(reset)
          numbel <= 22'd0;
        else if(vdin==1'd1 && vdin_d0==1'd0)
          numbel <= 22'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10] && hdin_dly[7])
              numbel <= numbel + 1'd1;
          end
         
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            dividend1 <= 24'd0;
            divisor1  <= 16'd1;
          end   
        else if(vdin==1'd0 && vdin_d0==1'd1)
          begin
            dividend1 <= temp2[37:14];
            divisor1  <= {8'd0,numbel[21:14]};
          end
    
    //4x4窗口差值  像素值 - 窗口均值  (有正负值)
      always@(posedge clk or posedge reset)
        if(reset)
          diff_value <= 8'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[7])
              begin
                if(dout3_dly[4]>avg_window)
                  diff_value <= dout3_dly[4] - avg_window;
                else
                  diff_value <= avg_window - dout3_dly[4];
              end
            else
              diff_value <= 8'd0;
          end
        else
          diff_value <= 8'd0;
          
      always@(posedge clk or posedge reset)
        if(reset)
          flag_diff_value <= 1'd0;
        else if(dout3_dly[4]>=avg_window)
          flag_diff_value <= 1'd1;
        else
          flag_diff_value <= 1'd0;
          
      always@(posedge clk)
        flag_diff_value_dly <= {flag_diff_value_dly[32:0],flag_diff_value}; 
      
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            a3 <= 16'd0;
            b3 <= 8'd0;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[8])
              begin
                a3 <= quotient1[15:0];
                b3 <= diff_value;
              end
            else
              begin
                a3 <= 16'd0;
                b3 <= 8'd0;
              end
          end
        else
          begin
            a3 <= 16'd0;
            b3 <= 8'd0;
          end
          
      always@(posedge clk or posedge reset)
        if(reset)
          begin
            dividend2 <= 24'd0;
            divisor2  <= 16'd1;
          end
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[10])
              begin
                if(variance_window>quotient1)
                  begin
                    dividend2 <= p3;
                    divisor2  <= variance_window;
                  end
                else
                  begin
                    dividend2 <= p3;
                    divisor2  <= quotient1[15:0];
                  end
              end
            else
              begin
                dividend2 <= 24'd0;
                divisor2  <= 16'd1;
              end
          end
        else
          begin
            dividend2 <= 24'd0;
            divisor2  <= 16'd1;
          end
      
            
      always@(posedge clk or posedge reset)
        if(reset)
          dout <= 8'd0;
        else if(vd_data>=12'd3 && vd_data<=12'd1439)
          begin
            if(hdin_dly[35] && hdin_dly[37])
              begin
                if(flag_diff_value_dly[28]==1)
                  begin
                    if(dout3_dly[34]>quotient2)
                      dout <= dout3_dly[34] - quotient2;
                    else
                      dout <= 8'd0;
                  end
                else
                  begin
                    if(dout3_dly[34]+quotient2>=8'd255)
                      dout <= 8'd255;
                    else
                      dout <= dout3_dly[34] + quotient2;
                  end
              end
            else
              dout <= dout3_dly[34];
          end
        else
          dout <= dout3_dly[34];
          
      always@(posedge clk or posedge reset)
        if(reset)
          vdout <= 1'd0;
        else if(vd_data==12'd1 && hd_data==12'd36)
          vdout <= 1'd1;
        else if(vd_data==12'd1441 && hd_data==12'd2093)
          vdout <= 1'd0;
    
      always@(posedge clk or posedge reset)
        if(reset)
          hdout <= 1'd0;
        else if(vdout==1)
          begin
            if(hd_data>=12'd62 && hd_data<=12'd1981)
              hdout <= 1'd1;
            else
              hdout <= 1'd0;
          end
        else
          hdout <= 1'd0;
          
      
      always@(posedge clk or posedge reset)
        if(reset)
          srst <= 1'd0;
        else if(vd_data==12'd1450)
          srst <= 1'd1;
        else 
          srst <= 1'd0;  
      
    fifo_1920x8 fifo1 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din1  ), // input [7 : 0] din
      .wr_en         (wr_en1), // input wr_en
      .rd_en         (rd_en1), // input rd_en
      .dout          (dout1 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    fifo_1920x8 fifo2 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din2  ), // input [7 : 0] din
      .wr_en         (wr_en2), // input wr_en
      .rd_en         (rd_en2), // input rd_en
      .dout          (dout2 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    fifo_1920x8 fifo3 (
      .clk           (clk   ), // input clk
      .srst          (srst  ), // input srst
      .din           (din3  ), // input [7 : 0] din
      .wr_en         (wr_en3), // input wr_en
      .rd_en         (rd_en3), // input rd_en
      .dout          (dout3 ), // output [7 : 0] dout
      .full          (      ), // output full
      .empty         (      )  // output empty
    );
    
    //u8xu8   avg_window*avg_window;
    mult_u8_u8  u_mult_u8_u8_2(
      .clk           (clk   ),
      .a             (a2    ),
      .b             (b2    ),
      .p             (p2    )
    );
    
    //u8xu8   dout1*dout1;
    mult_u8_u8  u_mult_u8_u8_4(
      .clk           (clk   ),
      .a             (a4    ),
      .b             (b4    ),
      .p             (p4    )
    );
    
    //u8xu8   dout2*dout2;
    mult_u8_u8  u_mult_u8_u8_5(
      .clk           (clk   ),
      .a             (a5    ),
      .b             (b5    ),
      .p             (p5    )
    );
    
    //u8xu8   dout3*dout3;
    mult_u8_u8  u_mult_u8_u8_6(
      .clk           (clk   ),
      .a             (a6    ),
      .b             (b6    ),
      .p             (p6    )
    );
    
    //u8xu8   din*din;
    mult_u8_u8  u_mult_u8_u8_7(
      .clk           (clk   ),
      .a             (a7    ),
      .b             (b7    ),
      .p             (p7    )
    );
    
    //计算噪声的方差
    div_u21_u13 u_div_u24_u16_1 (
        .clk           (clk       ), // input clk
        .rfd           (          ), // output rfd
        .dividend      (dividend1 ), // input [30 : 0] dividend
        .divisor       (divisor1  ), // input [15 : 0] divisor
        .quotient      (quotient1 ), // output [20 : 0] quotient
        .fractional    (          )  // output [6 : 0] fractional
        );
        
    //u16*u8    diff_value*quotient1;
    mult_u13_u8  u_mult_u13_u8(
      .clk           (clk   ),
      .a             (a3    ),
      .b             (b3    ),
      .p             (p3    )
    );
    
    div_u21_u13 u_div_u24_u16_2 (
        .clk           (clk       ), // input clk
        .rfd           (          ), // output rfd
        .dividend      (dividend2 ), // input [30 : 0] dividend
        .divisor       (divisor2  ), // input [15 : 0] divisor
        .quotient      (quotient2 ), // output [20 : 0] quotient
        .fractional    (          )  // output [6 : 0] fractional
        );
        
    endmodule
    View Code
  • 相关阅读:
    剑指offer03-04
    五大算法-1.回溯法
    linux与操作系统(1)- 用户接口
    python中的装饰器
    mysql 创建数据库,用户并给用户设置权限
    centOS6.5 桌面状态栏消失 解决
    centOS linux 远程Mysql 记录之root用户密码丢失
    XStream.toXML() 简单两种使用实例
    FileInputStream和FileOutStream 简单的使用实例;
    orale 行转列或者 字符拼接函数 wmsys.wm_concat()函数 /instr(listagg(name,';') within group (order by o.srclinkedid)
  • 原文地址:https://www.cnblogs.com/xingjian92/p/9257539.html
Copyright © 2011-2022 走看看