admin 发表于 2022-8-27 22:29:26

【设计实例】CMOS摄像头帧率和PCLK频率测量逻辑设计


本代码用来测量CMOS 摄像头的帧率和PCLK频率。
将camera_param_get例化在工程顶层,连接复位、已知频率的一个时钟信号给Clk,并通过名为FCLK的parameter参数来告知该时钟的具体频率。把摄像头的PCLK、VSYNC信号连接到本模块。摄像头工作时就能读到Fps以及Fpclk的值了,Fps是帧率,Fpclk是PCLK频率。
Fps和Fpclk的值,可以使用ISSP、VIO等JTAG工具在电脑端软件实时查看,也可以通过串口发送给电脑,也可以连接数码管显示驱动显示在数码管上。





module camera_param_get(
      Clk,
      Rst_n,
      Pclk,
      VSync,
      
      Fps,
      Fpclk
);

      input Clk;
      input Rst_n;
      input Pclk;
      input VSync;
         
      output reg Fps;
      output regFpclk;
      
      parameter FCLK = 50_000_000;
      
      reg r_VSync;
      always@(posedge Clk)
                r_VSync <= {r_VSync,VSync};
      
      
      reg sec_cnt;
      //计时1秒
      always@(posedge Clk or negedge Rst_n)
      if(!Rst_n)
                sec_cnt <= 0;
      else if(sec_cnt >= FCLK - 1)
                sec_cnt <= 0;
      else
                sec_cnt <= sec_cnt + 1'd1;
      
      //计数帧
      reg Fps_cnt;
      always@(posedge Clk or negedge Rst_n)
      if(!Rst_n)
                Fps_cnt <= 0;
      else if(sec_cnt == FCLK - 1)
                Fps_cnt <= 0;
      else if(r_VSync == 2'b01)
                Fps_cnt <= Fps_cnt + 1'd1;
      else
                Fps_cnt <= Fps_cnt;
      
      //输出帧统计结果
      always@(posedge Clk)
      if(sec_cnt == FCLK - 1)
                Fps <= Fps_cnt ;
      else
                Fps <= Fps;      
      
      //考虑到PCLK有可能高于FCLK,所以先预分频
      regpre_div_cnt;      
      always@(posedge Pclk or negedge Rst_n)
      if(!Rst_n)
                pre_div_cnt <= 0;
      else
                pre_div_cnt <= pre_div_cnt + 1'd1;
               
      regr_pre256_pclk;      
      always@(posedge Clk)
                r_pre256_pclk <= {r_pre256_pclk,pre_div_cnt};
      
      reg pre_pclk_cnt;
      always@(posedge Clk or negedge Rst_n)
      if(!Rst_n)
                pre_pclk_cnt <= 0;
      else if(sec_cnt == FCLK - 1)
                pre_pclk_cnt <= 0;
      else if(r_pre256_pclk == 2'b01)
                pre_pclk_cnt <= pre_pclk_cnt + 1'd1;
      else
                pre_pclk_cnt <= pre_pclk_cnt;
               
      always@(posedge Clk or negedge Rst_n)
      if(!Rst_n)      
                Fpclk <= 0;
      else if(sec_cnt == FCLK - 1)
                Fpclk <= {pre_pclk_cnt,8'd0};
      else
                Fpclk <= Fpclk;
               
endmodule




testbench


`timescale 1ns/1ns

module camera_param_get_tb;

      reg Clk;
      reg Rst_n;
      reg Pclk;
      reg Vsync;
      reg Href;
   reg Data;
         
      wire Fps;
      wire Fpclk;
      
      camera_param_get camera_param_get(
                Clk,
                Rst_n,
                Pclk,
                Vsync,
               
                Fps,
                Fpclk
      );

      initial Clk = 1;
   always#100 Clk = ~Clk;
      
      initial Pclk = 1;
   always#4 Pclk = ~Pclk;
   
    /*定义时序生成器输出图像的宽和高*/
    parameter WIDTH = 1200;
    parameter HIGHT = 720;
   
    integer i,j;
   
    initial begin
      Rst_n = 0;
      Vsync = 0;
      Href = 0;
      Data = 0;
      #805;
      Rst_n = 1;
      #400;
      repeat(15)begin
            Vsync = 1;
            #320;
            Vsync = 0;
            #800;
            for(i=0;i<HIGHT;i=i+1)begin
                for(j=0;j<WIDTH*2;j=j+1)begin
                  Href = 1;
                  Data = Data+ 1;
                  #80;
                end
                Href = 0;
                #800;
            end
      end
      $stop;
    end


endmodule







另外实测,大家使用我们给大家提供的初始化表,帧率设置30帧时候,PCLK为84M,15帧为42M,7.5帧为21M

页: [1]
查看完整版本: 【设计实例】CMOS摄像头帧率和PCLK频率测量逻辑设计