ov5640_hdmi

顶层模块

module ov5640_hdmi(    
    input                 sys_clk      ,  //系统时钟
    input                 sys_rst_n    ,  //系统复位,低电平有效
    //摄像头接口                       
    input                 cam_pclk     ,  //cmos 数据像素时钟
    input                 cam_vsync    ,  //cmos 场同步信号
    input                 cam_href     ,  //cmos 行同步信号
    input   [7:0]         cam_data     ,  //cmos 数据
    output                cam_rst_n    ,  //cmos 复位信号,低电平有效
    output                cam_pwdn     ,  //电源休眠模式选择 0:正常模式 1:电源休眠模式
    output                cam_scl      ,  //cmos SCCB_SCL线
    inout                 cam_sda      ,  //cmos SCCB_SDA线       
    // DDR3                            
    inout   [15:0]        ddr3_dq      ,  //DDR3 数据
    inout   [1:0]         ddr3_dqs_n   ,  //DDR3 dqs负
    inout   [1:0]         ddr3_dqs_p   ,  //DDR3 dqs正  
    output  [13:0]        ddr3_addr    ,  //DDR3 地址   
    output  [2:0]         ddr3_ba      ,  //DDR3 banck 选择
    output                ddr3_ras_n   ,  //DDR3 行选择
    output                ddr3_cas_n   ,  //DDR3 列选择
    output                ddr3_we_n    ,  //DDR3 读写选择
    output                ddr3_reset_n ,  //DDR3 复位
    output  [0:0]         ddr3_ck_p    ,  //DDR3 时钟正
    output  [0:0]         ddr3_ck_n    ,  //DDR3 时钟负
    output  [0:0]         ddr3_cke     ,  //DDR3 时钟使能
    output  [0:0]         ddr3_cs_n    ,  //DDR3 片选
    output  [1:0]         ddr3_dm      ,  //DDR3_dm
    output  [0:0]         ddr3_odt     ,  //DDR3_odt                                                                
    //hdmi接口                           
    output                tmds_clk_p   ,  // TMDS 时钟通道
    output                tmds_clk_n   ,
    output  [2:0]         tmds_data_p  ,  // TMDS 数据通道
    output  [2:0]         tmds_data_n  ,
    output                tmds_oen        // TMDS 输出使能
    );     

由于ov5640的时钟和屏幕的时钟不一样,所以必须将读取到的数据先进行缓存,然后在显示在屏幕上,该实验用的时65M时钟频率的像素模式,所以我们可以通过乒乓操作,让两者达到一个平衡。

时钟模块

clk_wiz_0 u_clk_wiz_0
   (
    // Clock out ports
    .clk_out1              (clk_200m),     
    .clk_out2              (clk_50m),
    .clk_out3              (pixel_clk_5x),
    .clk_out4              (pixel_clk),
    // Status and control signals
    .reset                 (~sys_rst_n), 
    .locked                (locked),       
   // Clock in ports
    .clk_in1               (sys_clk)
    );     

OV5640摄像头驱动模块

OV5640 驱动模块负责驱动 OV5640 SCCB 接口总线,将像素时钟驱动下的传感器输出的场同步信号、行同步信号以及 8 位数据转换成 DDR 读写控制模块的写使能信号和 16 位写数据信号,完成对 OV5640 传感器图像的采集。

module ov5640_dri (
    input           clk             ,  //时钟
    input           rst_n           ,  //复位信号,低电平有效
    //摄像头接口 
    input           cam_pclk        ,  //cmos 数据像素时钟
    input           cam_vsync       ,  //cmos 场同步信号
    input           cam_href        ,  //cmos 行同步信号
    input    [7:0]  cam_data        ,  //cmos 数据  
    output          cam_rst_n       ,  //cmos 复位信号,低电平有效
    output          cam_pwdn        ,  //cmos 电源休眠模式选择信号
    output          cam_scl         ,  //cmos SCCB_SCL线
    inout           cam_sda         ,  //cmos SCCB_SDA线
    
    //摄像头分辨率配置接口
    input    [12:0] cmos_h_pixel    ,  //水平方向分辨率
    input    [12:0] cmos_v_pixel    ,  //垂直方向分辨率
    input    [12:0] total_h_pixel   ,  //水平总像素大小
    input    [12:0] total_v_pixel   ,  //垂直总像素大小
    input           capture_start   ,  //图像采集开始信号
    output          cam_init_done   ,  //摄像头初始化完成
    
    //用户接口
    output          cmos_frame_vsync,  //帧有效信号    
    output          cmos_frame_href ,  //行有效信号
    output          cmos_frame_valid,  //数据有效使能信号
    output  [15:0]  cmos_frame_data    //有效数据  
);
//I2C配置模块
i2c_ov5640_rgb565_cfg u_i2c_cfg(
    .clk                (i2c_dri_clk),
    .rst_n              (rst_n),
            
    .i2c_exec           (i2c_exec),
    .i2c_data           (i2c_data),
    .i2c_rh_wl          (i2c_rh_wl),        //I2C读写控制信号
    .i2c_done           (i2c_done), 
    .i2c_data_r         (i2c_data_r),   
                
    .cmos_h_pixel       (cmos_h_pixel),     //CMOS水平方向像素个数
    .cmos_v_pixel       (cmos_v_pixel) ,    //CMOS垂直方向像素个数
    .total_h_pixel      (total_h_pixel),    //水平总像素大小
    .total_v_pixel      (total_v_pixel),    //垂直总像素大小
        
    .init_done          (cam_init_done) 
    );    
​
//I2C驱动模块
i2c_dri #(
    .SLAVE_ADDR         (SLAVE_ADDR),       //参数传递
    .CLK_FREQ           (CLK_FREQ  ),              
    .I2C_FREQ           (I2C_FREQ  ) 
    )
u_i2c_dr(
    .clk                (clk),
    .rst_n              (rst_n     ),
​
    .i2c_exec           (i2c_exec  ),   
    .bit_ctrl           (BIT_CTRL  ),   
    .i2c_rh_wl          (i2c_rh_wl),        //固定为0,只用到了IIC驱动的写操作   
    .i2c_addr           (i2c_data[23:8]),   
    .i2c_data_w         (i2c_data[7:0]),   
    .i2c_data_r         (i2c_data_r),   
    .i2c_done           (i2c_done  ),
    
    .scl                (cam_scl   ),   
    .sda                (cam_sda   ),   
​
    .dri_clk            (i2c_dri_clk)       //I2C操作时钟
    );
​
//CMOS图像数据采集模块
cmos_capture_data u_cmos_capture_data(      //系统初始化完成之后再开始采集数据 
    .rst_n              (rst_n & capture_start),
    
    .cam_pclk           (cam_pclk),
    .cam_vsync          (cam_vsync),
    .cam_href           (cam_href),
    .cam_data           (cam_data),         
    
    .cmos_frame_vsync   (cmos_frame_vsync),
    .cmos_frame_href    (cmos_frame_href ),
    .cmos_frame_valid   (cmos_frame_valid), //数据有效使能信号
    .cmos_frame_data    (cmos_frame_data )  //有效数据 
    );

I2C 驱动模块(i2c_dri)
module i2c_dri
    #(
      parameter   SLAVE_ADDR = 7'b1010000   ,  //EEPROM从机地址
      parameter   CLK_FREQ   = 26'd50_000_000, //模块输入的时钟频率
      parameter   I2C_FREQ   = 18'd250_000     //IIC_SCL的时钟频率
    )
   (                                                            
    input                clk        ,    
    input                rst_n      ,   
                                         
    //i2c interface                      
    input                i2c_exec   ,  //I2C触发执行信号
    input                bit_ctrl   ,  //字地址位控制(16b/8b)
    input                i2c_rh_wl  ,  //I2C读写控制信号
    input        [15:0]  i2c_addr   ,  //I2C器件内地址
    input        [ 7:0]  i2c_data_w ,  //I2C要写的数据
    output  reg  [ 7:0]  i2c_data_r ,  //I2C读出的数据
    output  reg          i2c_done   ,  //I2C一次操作完成
    output  reg          i2c_ack    ,  //I2C应答标志 0:应答 1:未应答
    output  reg          scl        ,  //I2C的SCL时钟信号
    inout                sda        ,  //I2C的SDA信号
                                       
    //user interface                   
    output  reg          dri_clk       //驱动I2C操作的驱动时钟
     );

I2C 驱动模块负责驱动 OV5640 SCCB接口总线 ,但SCCB协议和I2C协议的区别时I2C的第九位时从机应答位,二SCCB的第九位是任意,所以可以SCCB的驱动可以直接移植I2C的驱动。

i2c 配置模块(i2c_ov5640_rgb565_cfg)

该模块寄存需要配置的寄存器地址、数据以及控制初始化的开始与结束,同时该模块输出 OV5640 的寄存器地址和数据以及控制 I2C 驱动模块开始执行的控制信号,直接连接到 I2C 驱动模块的用户接口,从而完成对 OV5640 传感器的初始化 。

module i2c_ov5640_rgb565_cfg
   (  
    input                clk      ,     //时钟信号
    input                rst_n    ,     //复位信号,低电平有效
    
    input        [7:0]   i2c_data_r,    //I2C读出的数据
    input                i2c_done ,     //I2C寄存器配置完成信号
    input        [12:0]  cmos_h_pixel ,
    input        [12:0]  cmos_v_pixel ,
    input        [12:0]  total_h_pixel, //水平总像素大小
    input        [12:0]  total_v_pixel, //垂直总像素大小
    output  reg          i2c_exec ,     //I2C触发执行信号   
    output  reg  [23:0]  i2c_data ,     //I2C要配置的地址与数据(高16位地址,低8位数据)
    output  reg          i2c_rh_wl,     //I2C读写控制信号
    output  reg          init_done      //初始化完成信号
    );
​

共需要配置250个寄存器

摄像头图像采集模块(cmos_capture_data)

摄像头采集模块在像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及 8 位数据转换成 DDR 读写控制模块的写使能信号和 16 位写数据信号,完成对 OV5640 传感器图像的采集 。

module cmos_capture_data(
    input                 rst_n            ,  //复位信号    
    //摄像头接口                           
    input                 cam_pclk         ,  //cmos 数据像素时钟
    input                 cam_vsync        ,  //cmos 场同步信号
    input                 cam_href         ,  //cmos 行同步信号
    input  [7:0]          cam_data         ,                      
    //用户接口                              
    output                cmos_frame_vsync ,  //帧有效信号    
    output                cmos_frame_href  ,  //行有效信号
    output                cmos_frame_valid ,  //数据有效使能信号
    output       [15:0]   cmos_frame_data     //有效数据        
    );

将采集到的颜色数据最为wr_fifo的输入

DDR3控制器模块

DDR3 控制模块负责驱动 DDR3 片外存储器,缓存图像传感器输出的图像数据

module ddr3_top(
    input              sys_clk_i           ,   //MIG IP核输入时钟  
    input              clk_ref_i           ,   //ddr3参考时钟
    input              rst_n               ,   //复位,低有效            
    //DDR3接口信号                           
    input   [27:0]     app_addr_rd_min     ,   //读ddr3的起始地址
    input   [27:0]     app_addr_rd_max     ,   //读ddr3的结束地址
    input   [7:0]      rd_bust_len         ,   //从ddr3中读数据时的突发长度
    input   [27:0]     app_addr_wr_min     ,   //读ddr3的起始地址
    input   [27:0]     app_addr_wr_max     ,   //读ddr3的结束地址
    input   [7:0]      wr_bust_len         ,   //从ddr3中读数据时的突发长度
    // DDR3 IO接口 
    inout   [15:0]     ddr3_dq             ,   //ddr3 数据
    inout   [1:0]      ddr3_dqs_n          ,   //ddr3 dqs负
    inout   [1:0]      ddr3_dqs_p          ,   //ddr3 dqs正  
    output  [13:0]     ddr3_addr           ,   //ddr3 地址   
    output  [2:0]      ddr3_ba             ,   //ddr3 banck 选择
    output             ddr3_ras_n          ,   //ddr3 行选择
    output             ddr3_cas_n          ,   //ddr3 列选择
    output             ddr3_we_n           ,   //ddr3 读写选择
    output             ddr3_reset_n        ,   //ddr3 复位
    output  [0:0]      ddr3_ck_p           ,   //ddr3 时钟正
    output  [0:0]      ddr3_ck_n           ,   //ddr3 时钟负
    output  [0:0]      ddr3_cke            ,   //ddr3 时钟使能
    output  [0:0]      ddr3_cs_n           ,   //ddr3 片选
    output  [1:0]      ddr3_dm             ,   //ddr3_dm
    output  [0:0]      ddr3_odt            ,   //ddr3_odt      
    //用户
    input              ddr3_read_valid     ,   //DDR3 读使能   
    input              ddr3_pingpang_en    ,   //DDR3 乒乓操作使能       
    input              wr_clk              ,   //wfifo时钟   
    input              rd_clk              ,   //rfifo的读时钟      
    input              wr_en               ,   //数据有效使能信号
    input   [15:0]     wrdata              ,   //有效数据 
    input              rdata_req           ,   //请求像素点颜色数据输入  
    input              rd_load             ,   //输出源更新信号
    input              wr_load             ,   //输入源更新信号
    output  [15:0]     rddata              ,   //rfifo输出数据
    output             init_calib_complete     //ddr3初始化完成信号
    );  
DDR 读写模块(ddr3_rw)

该模块负责与 MIG 模块的命令和地址的交互,根据 FIFO 控制模块中 fifo 的剩余数据量来切换 DDR3 的读写命令和地址 。

module ddr3_rw(          
    input           ui_clk               ,  //用户时钟
    input           ui_clk_sync_rst      ,  //复位,高有效
    input           init_calib_complete  ,  //DDR3初始化完成
    input           app_rdy              ,  //MIG IP核空闲
    input           app_wdf_rdy          ,  //MIG写FIFO空闲
    input           app_rd_data_valid    ,  //读数据有效
    input   [9:0]   wfifo_rcount         ,  //写端口FIFO中的数据量
    input   [9:0]   rfifo_wcount         ,  //读端口FIFO中的数据量
    input           rd_load              ,  //输出源更新信号
    input           wr_load              ,  //输入源更新信号
    input   [27:0]  app_addr_rd_min      ,  //读DDR3的起始地址
    input   [27:0]  app_addr_rd_max      ,  //读DDR3的结束地址
    input   [7:0]   rd_bust_len          ,  //从DDR3中读数据时的突发长度
    input   [27:0]  app_addr_wr_min      ,  //写DDR3的起始地址
    input   [27:0]  app_addr_wr_max      ,  //写DDR3的结束地址
    input   [7:0]   wr_bust_len          ,  //从DDR3中写数据时的突发长度
​
    input           ddr3_read_valid      ,  //DDR3 读使能   
    input           ddr3_pingpang_en     ,  //DDR3 乒乓操作使能          
    output          rfifo_wren           ,  //从ddr3读出数据的有效使能 
    output  [27:0]  app_addr             ,  //DDR3地址                 
    output          app_en               ,  //MIG IP核操作使能
    output          app_wdf_wren         ,  //用户写使能   
    output          app_wdf_end          ,  //突发写当前时钟最后一个数据 
    output  [2:0]   app_cmd                 //MIG IP核操作命令,读或者写       
    );

MIG 模块(mig_series)

DDR3模块如何移植详见:DDR3介绍-CSDN博客

FIFO 控制模块(ddr3_fifo_ctrl)

负责对输入和输出的数据进行时钟域的切换和位宽的转换。

module ddr3_fifo_ctrl(
    input                rst_n            ,  //复位信号
    input                wr_clk           ,  //wfifo时钟
    input                rd_clk           ,  //rfifo时钟
    input                ui_clk           ,  //用户时钟
    input                wr_en            ,  //数据有效使能信号
    input  [15:0]        wrdata          ,   //有效数据
    input  [127:0]       rfifo_din        ,  //用户读数据
    input                rdata_req        ,  //请求像素点颜色数据输入 
    input                rfifo_wren       ,  //从ddr3读出数据的有效使能
    input                wfifo_rden       ,  //wfifo读使能
    input                rd_load          ,  //输出源场信号
    input                wr_load          ,  //输入源场信号          
​
    output [127:0]       wfifo_dout       ,  //用户写数据
    output [9:0]         rfifo_wcount     ,  //rfifo剩余数据计数
    output [9:0]         wfifo_rcount     ,  //wfifo写进数据计数
    output reg [15:0]    rddata              //读有效数据        
    );

hdmi显示模块

显示模块的代码可以移植hdmi的通用.v文件,RGB2DVI 模块 -----> DVI发送端顶层模块和video_driver------>视频显示驱动模块,在显示模块中,当像素坐标处于有有效区范围内时,video_driver会发送一个data_req(数据请求信号),rd_fifo就会从DDR3中一次读出128个数据,128/16=8,即8个像素点位置的数据,通过一个计数器,当这8个像素点的数据都显示出来后,再次让rd_fifo从DDR3中读取128个数据.这样,图像就能通过hdmi线顺利的显示在屏幕上了。

具体的hdmi模块如何移植详见:HDMI彩条实验-CSDN博客

  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值