-01-摄像头DVP输入IP核设计【OV5640】

来源:互联网 发布:斐讯efa中文安卓编程 编辑:程序博客网 时间:2024/05/20 03:41

在之前设计的OV5640输入接口逻辑上完善了一下代码,暂时出一版IP来用。

DVP Timing

首先看看OV5640的DVP信号时序:
这里写图片描述

先不考虑每个信号的具体时序,大致看一看他的波形,可以发现,这是一个很标准的时序。VSYNC是场同步信号,在图像数据发送之前会有一个高电平脉冲;HREF是数据有效信号,高电平时时代表D[9:0]的数据信号有效,可以理解为DE或者Data_valid;HSYNC是行同步信号,我们有了HREF就不需要这个信号了;D[9:0]是并口数据;以上四个信号都同步于摄像头的PCLK信号。

因为DVP这个并口的时序十分标准,其实是可以直接接入fpga内,并借用Xilinx的Video In to AXI4-Stream IP核实现并口到AXI4S总线的转换的。

RGB565

OV5640支持 RawRGB、 RGB(RGB565/RGB555/RGB444)、 CCIR656、 YUV(422/420)、 YCbCr( 422)和压缩图像( JPEG)输出格式。我们今后可能用到的格式包括:RawRGB、RGB565、YUV422、JPEG四种格式。
为了快速验证摄像头功能,选择了RGB565格式,因为Raw格式需要插值、YUV需要色彩空间转换、JPEG需要解码··总之都麻烦。而RGB565一个像素有16位数据,想要通过8位数据线将像素信号发送出来,只能通过两个PCLK时钟发送出来,每 2 个字节组成一个像素的颜色(低字节在前,高字节在后)。

图像尺寸测量

当通过I2C初始化摄像头后,DVP时序就能够正常输出了,但是为了确保输出的信号是稳定的,我们从接口中捕获10帧的图像,并测试输入图像的尺寸大小。
一来可以用来检测图像数据是否稳定和正常(尺寸大小是否发生了变化),二来测量出了输入图像的尺寸可以方便后面的缓存管理、图像边界识别。

以上的两个部分的功能写出RTL代码后,再结合Video In to AXI4-Stream IP核,即完成了DVP输入IP核的设计。Video In to AXI4-Stream IP的功能实现可以在vivado中看它的源码,还是很好理解的,可以选择直接使用它或者参照它的实现方法自行设计。

Custom IP的使用

生成的dvp_2_axi4s IP核按下图连接:
这里写图片描述

视频数据流按如下方式进入DDR缓存
DVP接口 -> dvp_2_axi4s -> axi vdma -> axi interconnect -> zynq -> DDR3

总结

代码可以从这里下载: https://coding.net/u/vacajk/p/zybo_ov5640_stereo_camera/git

也可以直接下载我整理好的:稍后上传>>

附:RTL代码

dvp_capture.v

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer: vacajk//// Create Date: 2017/03/15 23:48:18// Design Name:// Module Name: dvp_capture// Project Name:// Target Devices:// Tool Versions: vivado 2016.3// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module dvp_capture #(  parameter FPGA_FAMILY         = "zynq7000",  parameter DVP_DATA_FORMAT     = "RGB565",  parameter DVP_TIMING_ADJ_EN   = "ENABLE",  parameter DVP_TIMING_ADJ_CNT  = 4'd10,  parameter DVP_FRAME_WAIT_CNT  = 4'd10,  parameter DVP_XVCLK_OUT_EN    = "ENABLE"  ) (  //_____________________________________________ system clock  input iCLK,  input iRST_n,  //_____________________________________________ module control  input capture_en,  output capture_stable,  output capture_failure,  output [11:0] capture_h_size,  output [11:0] capture_v_size,  //_____________________________________________ DVP interface  output CAM_XVCLK,  input CAM_PCLK,  input CAM_HREF,  input CAM_VSYNC,  input [7:0] CAM_D,  //_____________________________________________ parallel signals  output rx_pclk,  output rx_href,  output rx_vsync,  output [23:0] rx_data  );/********************************************** * DVP timing diagram *        _ * VS____| |__________________________________ *               ______         ______ * HS___________|      |__...__|      |_______ * * **********************************************///_____________________________________________ external DVP interface, use IBUF and OBUFwire cam_xvclk_o;assign cam_xvclk_o = 1'b0;wire cam_pclk_i;wire cam_href_i;wire cam_vsync_i;wire [7:0] cam_d_i;//_____________________________________________ camera input interface IBUFgenerate    //FPGA_FAMILYif (FPGA_FAMILY == "zynq7000")      //FPGA_FAMILY    begin        IBUF #(          .IBUF_LOW_PWR("TRUE"),    // Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards          .IOSTANDARD("DEFAULT")    // Specify the input I/O standard        ) CAM_PCLK__IBUF_inst (          .O(cam_pclk_i),           // Buffer output          .I(CAM_PCLK)              // Buffer input (connect directly to top-level port)        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_HREF_IBUF_inst (          .O(cam_href_i),          .I(CAM_HREF)        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_VSYNC_IBUF_inst (          .O(cam_vsync_i),          .I(CAM_VSYNC)        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D0_IBUF_inst (          .O(cam_d_i[0]),          .I(CAM_D[0])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D1_IBUF_inst (          .O(cam_d_i[1]),          .I(CAM_D[1])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D2_IBUF_inst (          .O(cam_d_i[2]),          .I(CAM_D[2])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D3_IBUF_inst (          .O(cam_d_i[3]),          .I(CAM_D[3])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D4_IBUF_inst (          .O(cam_d_i[4]),          .I(CAM_D[4])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D5_IBUF_inst (          .O(cam_d_i[5]),          .I(CAM_D[5])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D6_IBUF_inst (          .O(cam_d_i[6]),          .I(CAM_D[6])        );        IBUF #(          .IBUF_LOW_PWR("TRUE"),          .IOSTANDARD("DEFAULT")        ) CAM_D7_IBUF_inst (          .O(cam_d_i[7]),          .I(CAM_D[7])        );    endelse    //FPGA_FAMILY    begin        assign cam_pclk_i   = CAM_PCLK;        assign cam_href_i   = CAM_HREF;        assign cam_vsync_i  = CAM_VSYNC;        assign cam_d_i      = CAM_D;    endendgenerate //FPGA_FAMILY//_____________________________________________ camera output xvclk OBUFgenerateif((FPGA_FAMILY == "zynq7000") && (DVP_XVCLK_OUT_EN == "ENABLE"))   //FPGA_FAMILY    OBUF #(        .DRIVE(12),             // Specify the output drive strength        .IOSTANDARD("DEFAULT"), // Specify the output I/O standard        .SLEW("SLOW")           // Specify the output slew rate    ) CAM_XVCLK_OBUF_inst (        .O(CAM_XVCLK),          // Buffer output (connect directly to top-level port)        .I(cam_xvclk_o)         // Buffer input    );else if(DVP_XVCLK_OUT_EN == "ENABLE")    assign CAM_XVCLK = cam_xvclk_o;else    assign CAM_XVCLK = 1'b0;endgeneratewire cam_rst_n;assign cam_rst_n = iRST_n;reg capture_en_1 = 1'b0;reg capture_en_2 = 1'b0;//_____________________________ capture_en shift -> _ralways@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) capture_en_1 <= 1'b0;    else                        capture_en_1 <= capture_en;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) capture_en_2 <= 1'b0;    else                        capture_en_2 <= capture_en_1;//_____________________________________________ camera sync signals edgereg cam_href_1 = 1'b0;reg cam_href_2 = 1'b0;reg cam_href_3 = 1'b0;reg cam_vsync_1 = 1'b0;reg cam_vsync_2 = 1'b0;reg cam_vsync_3 = 1'b0;reg [7:0] cam_d_1 = 8'b0;reg [7:0] cam_d_2 = 8'b0;reg [7:0] cam_d_3 = 8'b0;wire [1:0] cam_href_edge;wire [1:0] cam_vsync_edge;wire cam_href_rising;wire cam_href_falling;wire cam_vsync_rising;wire cam_vsync_falling;//_____________________________ cam_href_i shift -> _1always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_href_1 <= 1'b0;    else                        cam_href_1 <= cam_href_i;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_href_2 <= 1'b0;    else                        cam_href_2 <= cam_href_1;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_href_3 <= 1'b0;    else                        cam_href_3 <= cam_href_2;//_____________________________ cam_vsync_i shift -> _1always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_vsync_1 <= 1'b0;    else                        cam_vsync_1 <= cam_vsync_i;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_vsync_2 <= 1'b0;    else                        cam_vsync_2 <= cam_vsync_1;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_vsync_3 <= 1'b0;    else                        cam_vsync_3 <= cam_vsync_2;//_____________________________ cam_d_i shift -> _1always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_d_1 <= 8'b0;    else                        cam_d_1 <= cam_d_i;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_d_2 <= 8'b0;    else                        cam_d_2 <= cam_d_1;always@(posedge cam_pclk_i, negedge cam_rst_n)    if(~cam_rst_n) cam_d_3 <= 8'b0;    else                        cam_d_3 <= cam_d_2;//_____________________________ cam_href_i cam_vsync_i edgeassign cam_href_edge            = {cam_href_2, cam_href_1};assign cam_vsync_edge           = {cam_vsync_2, cam_vsync_1};assign cam_href_rising      = ((capture_en_2 == 1'b1) && (cam_href_edge     == 2'b01))? 1'b1: 1'b0;assign cam_href_falling     = ((capture_en_2 == 1'b1) && (cam_href_edge     == 2'b10))? 1'b1: 1'b0;assign cam_vsync_rising     = ((capture_en_2 == 1'b1) && (cam_vsync_edge    == 2'b01))? 1'b1: 1'b0;assign cam_vsync_falling    = ((capture_en_2 == 1'b1) && (cam_vsync_edge    == 2'b10))? 1'b1: 1'b0;reg rx_href_o = 1'b0;reg rx_vsync_o = 1'b0;reg [23:0] rx_data_o = 24'b0;reg pixel_odd_even_flag_1 = 1'b0;reg pixel_odd_even_flag_2 = 1'b0;reg cam_pclk_div2_stable = 1'b0;wire cam_pclk_div2;generate    //DVP_DATA_FORMATif(DVP_DATA_FORMAT == "RGB565") //DVP_DATA_FORMAT    begin        //_____________________________________________ pixel_odd_even_flag        //change ov5640 rgb565 two clock per pixel to rgb888 parallel data        always@(posedge cam_pclk_i)            if(~capture_stable)                pixel_odd_even_flag_1 <= 1'b0;            else if(cam_href_1)                pixel_odd_even_flag_1 <= ~pixel_odd_even_flag_1;            else                pixel_odd_even_flag_1 <= 1'b0;        //_____________________________________________ pixel_odd_even_flag_2        always@(posedge cam_pclk_i, negedge cam_rst_n)            if(~cam_rst_n) pixel_odd_even_flag_2 <= 1'b0;            else                        pixel_odd_even_flag_2 <= pixel_odd_even_flag_1;        //ov5640 rgb565 data from dvp: {r[4:0], g[5:3]} {g[2:0], b[4:0]}        reg [4:0] rx_data_red = 5'b0;        reg [5:0] rx_data_green = 6'b0;        reg [4:0] rx_data_blue = 5'b0;        always@(posedge cam_pclk_i, negedge cam_rst_n)            if(cam_rst_n & ~capture_stable)                begin              rx_data_red <= 5'b0;              rx_data_green <= 6'b0;              rx_data_blue <= 5'b0;                end          else if(cam_href_1)                if(~pixel_odd_even_flag_1)                    begin                        rx_data_blue <= cam_d_1[4:0];                        rx_data_green[2:0] <= cam_d_1[7:5];                    end                else                    begin                        rx_data_green[5:3] <= cam_d_1[2:0];                        rx_data_red <= cam_d_1[7:3];                    end          else            begin              rx_data_red <= 5'b0;              rx_data_green <= 6'b0;              rx_data_blue <= 5'b0;            end        //RGB Data Encoding referenced by m_axis_video_tdata of v_vid IP {R[7:0], B[7:0], G[7:0]}        always@(posedge cam_pclk_div2, negedge cam_rst_n)            if(cam_rst_n & ~capture_stable)                rx_data_o <= 24'b0;            else if(cam_href_2)                rx_data_o <= {rx_data_red, 3'b000, rx_data_blue, 3'b000, rx_data_green, 2'b00};            else                rx_data_o <= 24'b0;        always@(posedge cam_pclk_div2, negedge cam_rst_n)            if(cam_rst_n & ~capture_stable)                begin                    rx_href_o <= 1'b0;                    rx_vsync_o <= 1'b0;                end            else                begin                rx_href_o <= cam_href_3;                rx_vsync_o <= cam_vsync_3;                end        assign rx_pclk = cam_pclk_div2;    endelse //raw data    begin        always@(posedge cam_pclk_i)            if(cam_rst_n & ~capture_stable)                begin                    rx_href_o <= 1'b0;                    rx_vsync_o <= 1'b0;                    rx_data_o <= 24'b0;                end            else                begin                    rx_href_o <= cam_href_3;                    rx_vsync_o <= cam_vsync_3;                    rx_data_o <= {16'b0, cam_d_3};                end        assign rx_pclk = cam_pclk_i;    endendgenerategenerate    //FPGA_FAMILYif((DVP_DATA_FORMAT == "RGB565") && (FPGA_FAMILY == "zynq7000"))    begin        reg cam_pclk_div2_clr = 1'b1;        BUFR #(            .BUFR_DIVIDE("2"),          // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"            .SIM_DEVICE("7SERIES")  // Must be set to "7SERIES"        ) CAM_PCLK_DIV2_BUFR_inst (            .O(cam_pclk_div2),              // 1-bit output: Clock output port            .CE(1'b1),                              // 1-bit input: Active high, clock enable (Divided modes only)            .CLR(cam_pclk_div2_clr),    // 1-bit input: Active high, asynchronous clear (Divided modes only)            .I(cam_pclk_i)                      // 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect        );        always@(posedge cam_pclk_i, negedge cam_rst_n)            if(cam_rst_n & ~capture_stable)                begin                    cam_pclk_div2_clr <= 1'b1;                    cam_pclk_div2_stable <= 1'b0;                end            else if (cam_pclk_div2_stable == 1'b0)                begin                    cam_pclk_div2_clr <= 1'b1;                    if(pixel_odd_even_flag_1 == 1'b1)                        begin                            cam_pclk_div2_clr <= 1'b0;                            cam_pclk_div2_stable <= 1'b1;                        end                end            else                begin                    cam_pclk_div2_clr <= 1'b0;                    cam_pclk_div2_stable <= 1'b1;                end    endelse    //DVP_DATA_FORMAT RAW    begin        reg cam_pclk_div2_r = 1'b0;        always@(posedge cam_pclk_i, negedge cam_rst_n)            if(cam_rst_n & ~capture_stable)                begin                    cam_pclk_div2_r <= 1'b0;                    cam_pclk_div2_stable <= 1'b0;                end            else if (cam_pclk_div2_stable == 1'b0)                begin                    cam_pclk_div2_r <= 1'b0;                    if(pixel_odd_even_flag_1 == 1'b1)                            cam_pclk_div2_stable <= 1'b1;                end            else                    cam_pclk_div2_r <= ~cam_pclk_div2_r;        assign cam_pclk_div2 = cam_pclk_div2_r;    endendgenerateassign rx_href = rx_href_o;assign rx_vsync = rx_vsync_o;assign rx_data = rx_data_o;reg pre_cap_stable = 1'b0;reg [3:0] pre_f_pix_cnt = 4'b0;generate    //DVP_TIMING_ADJ_ENif(DVP_TIMING_ADJ_EN == "ENABLE")   //DVP_TIMING_ADJ_EN    begin        //_____________________________________________ camera sync signals edge        //dvp pre capture, caculate the h and v size of video.        reg sta_dvp_pre_waitv_jump                  = 1'b0;        reg sta_dvp_pre_waitstable_hv_jump  = 1'b0;        reg sta_dvp_pre_waitstable_f_jump       = 1'b0;        reg sta_dvp_pre_done_jump                       = 1'b0;        localparam STA_DVP_PRE_IDLE                         = 8'b00000001;        localparam STA_DVP_PRE_WAITV                        = 8'b00000010;        localparam STA_DVP_PRE_WAITSTABLE_HV        = 8'b00000100;        localparam STA_DVP_PRE_WAITSTABLE_F         = 8'b00001000;        localparam STA_DVP_PRE_DONE                         = 8'b00010000;        localparam DVP_PRE_CNT_FAULT                        = 4'd10;        reg [7:0] dvp_pre_current_state = STA_DVP_PRE_IDLE;        reg [7:0] dvp_pre_next_state        = STA_DVP_PRE_IDLE;        reg [11:0] pre_h_pix_cnt    = 12'b0;        reg [11:0] pre_v_pix_cnt    = 12'b0;        reg [11:0] pre_h_pix_size = 12'b0;        reg [11:0] pre_v_pix_size = 12'b0;        reg pre_cnt_fault   = 1'b0;        reg [3:0] pre_hv_pix_size_diff  = 4'b0;        //_____________________________________________ state machine        always@(posedge cam_pclk_i, negedge cam_rst_n)            begin                if(~cam_rst_n) dvp_pre_current_state <= STA_DVP_PRE_IDLE;                else                        dvp_pre_current_state <= dvp_pre_next_state;            end        always@(*)            begin                dvp_pre_next_state = STA_DVP_PRE_IDLE;                case(dvp_pre_current_state)                    STA_DVP_PRE_IDLE:                        if(sta_dvp_pre_waitv_jump)                  dvp_pre_next_state = STA_DVP_PRE_WAITV;                        else                                                                dvp_pre_next_state = STA_DVP_PRE_IDLE;                    STA_DVP_PRE_WAITV:                        if(sta_dvp_pre_waitstable_hv_jump)  dvp_pre_next_state = STA_DVP_PRE_WAITSTABLE_HV;                        else                                                                dvp_pre_next_state = STA_DVP_PRE_WAITV;                    STA_DVP_PRE_WAITSTABLE_HV:                        if(sta_dvp_pre_waitstable_f_jump)       dvp_pre_next_state = STA_DVP_PRE_WAITSTABLE_F;                        else                                                                dvp_pre_next_state = STA_DVP_PRE_WAITSTABLE_HV;                    STA_DVP_PRE_WAITSTABLE_F:                        if(sta_dvp_pre_waitstable_hv_jump)  dvp_pre_next_state = STA_DVP_PRE_WAITSTABLE_HV;                        else if(sta_dvp_pre_done_jump)          dvp_pre_next_state = STA_DVP_PRE_DONE;                        else                                                                dvp_pre_next_state = STA_DVP_PRE_WAITSTABLE_F;                    STA_DVP_PRE_DONE:                        if(~capture_en_1)                                      dvp_pre_next_state = STA_DVP_PRE_IDLE;                        else                                                                dvp_pre_next_state = STA_DVP_PRE_DONE;                    default:                        dvp_pre_next_state = STA_DVP_PRE_IDLE;                endcase            end        //_____________________________ jump        always@(posedge cam_pclk_i, negedge cam_rst_n) begin            if(~cam_rst_n)                begin                    sta_dvp_pre_waitv_jump                  <= 1'b0;                    sta_dvp_pre_waitstable_hv_jump  <= 1'b0;                    sta_dvp_pre_waitstable_f_jump       <= 1'b0;                    sta_dvp_pre_done_jump                       <= 1'b0;                end            else                begin                    sta_dvp_pre_waitv_jump                  <= 1'b0;                    sta_dvp_pre_waitstable_hv_jump  <= 1'b0;                    sta_dvp_pre_waitstable_f_jump       <= 1'b0;                    sta_dvp_pre_done_jump                       <= 1'b0;                    case(dvp_pre_next_state)                        STA_DVP_PRE_IDLE:                            if(capture_en_1)                                                    sta_dvp_pre_waitv_jump <= 1'b1;                        STA_DVP_PRE_WAITV:                            if(cam_vsync_falling)                                           sta_dvp_pre_waitstable_hv_jump <= 1'b1;                        STA_DVP_PRE_WAITSTABLE_HV:                            if(cam_vsync_rising)                                            sta_dvp_pre_waitstable_f_jump <= 1'b1;                        STA_DVP_PRE_WAITSTABLE_F:                            if(pre_f_pix_cnt >= DVP_TIMING_ADJ_CNT)     sta_dvp_pre_done_jump <= 1'b1;                            else if(cam_vsync_falling)                              sta_dvp_pre_waitstable_hv_jump <= 1'b1;                        STA_DVP_PRE_DONE:                            begin                                sta_dvp_pre_waitv_jump                  <= 1'b0;                                sta_dvp_pre_waitstable_hv_jump  <= 1'b0;                                sta_dvp_pre_waitstable_f_jump       <= 1'b0;                                sta_dvp_pre_done_jump                       <= 1'b0;                            end                    default:                        begin                            sta_dvp_pre_waitv_jump                  <= 1'b0;                            sta_dvp_pre_waitstable_hv_jump  <= 1'b0;                            sta_dvp_pre_waitstable_f_jump       <= 1'b0;                            sta_dvp_pre_done_jump                       <= 1'b0;                        end                    endcase                end        end        //_____________________________        always@(posedge cam_pclk_i, negedge cam_rst_n)            begin                if(~cam_rst_n) begin                    pre_cap_stable  <= 1'b0;                    pre_h_pix_cnt       <= 12'd0;                    pre_v_pix_cnt       <= 12'd0;                    pre_h_pix_size  <= 12'd0;                    pre_v_pix_size  <= 12'd0;                    pre_f_pix_cnt       <= 4'd0;                    pre_cnt_fault       <= 1'b0;                    pre_hv_pix_size_diff        <= 4'd0;                end                else begin                    if(pre_hv_pix_size_diff >= DVP_PRE_CNT_FAULT) pre_cnt_fault <= 1'b1;                    case(dvp_pre_next_state)                        STA_DVP_PRE_IDLE:                            begin                                pre_cap_stable  <= 1'b0;                                pre_h_pix_cnt       <= 12'd0;                                pre_v_pix_cnt       <= 12'd0;                                pre_h_pix_size  <= 12'd0;                                pre_v_pix_size  <= 12'd0;                                pre_f_pix_cnt       <= 4'd0;                                pre_cnt_fault       <= 1'b0;                                pre_hv_pix_size_diff <= 4'd0;                            end                        STA_DVP_PRE_WAITV:                            begin                                pre_cap_stable  <= 1'b0;                                pre_h_pix_cnt       <= 12'd0;                                pre_v_pix_cnt       <= 12'd0;                                pre_h_pix_size  <= 12'd0;                                pre_v_pix_size  <= 12'd0;                                pre_f_pix_cnt       <= 4'd0;                                pre_cnt_fault       <= 1'b0;                                pre_hv_pix_size_diff <= 4'd0;                            end                        STA_DVP_PRE_WAITSTABLE_HV:                            begin                                pre_h_pix_cnt       <= 12'd0;                                if(cam_vsync_rising)                                    begin                                        pre_v_pix_cnt       <= 12'd0;                                        pre_v_pix_size  <= pre_v_pix_cnt;                                        pre_f_pix_cnt   <= pre_f_pix_cnt + 4'd1;                                        if(pre_v_pix_size != pre_v_pix_cnt) pre_hv_pix_size_diff <= pre_hv_pix_size_diff + 4'd1;                                    end                                else if(cam_href_falling)                                    begin                                        pre_v_pix_cnt       <= pre_v_pix_cnt + 12'd1;                                        pre_h_pix_size  <= pre_h_pix_cnt;                                        if(pre_h_pix_size != pre_h_pix_cnt) pre_hv_pix_size_diff <= pre_hv_pix_size_diff + 4'd1;                                    end                                else if(cam_href_1) pre_h_pix_cnt <= pre_h_pix_cnt + 12'd1;                            end                        STA_DVP_PRE_WAITSTABLE_F:                            if(cam_vsync_falling)                                begin                                    pre_h_pix_cnt <= 12'd0;                                    pre_v_pix_cnt <= 12'd0;                                end                        STA_DVP_PRE_DONE:                            pre_cap_stable <= 1'b1;                    default:                        begin                            pre_cap_stable  <= 1'b0;                            pre_h_pix_cnt       <= 12'd0;                            pre_v_pix_cnt       <= 12'd0;                            pre_h_pix_size  <= 12'd0;                            pre_v_pix_size  <= 12'd0;                            pre_f_pix_cnt       <= 4'd0;                            pre_cnt_fault       <= 1'b0;                            pre_hv_pix_size_diff        <= 4'd0;                        end                    endcase                end            end        assign capture_failure  = pre_cnt_fault;        assign capture_stable       = pre_cap_stable;        assign capture_h_size       = pre_h_pix_size;        assign capture_v_size       = pre_v_pix_size;    endelse    //DVP_TIMING_ADJ_EN    begin        always@(posedge cam_pclk_i, negedge cam_rst_n)            begin                if(~cam_rst_n)                    begin                        pre_cap_stable <= 1'b0;                        pre_f_pix_cnt <= 4'd0;                    end                else if(~pre_cap_stable & cam_vsync_rising)                    begin                        pre_f_pix_cnt <= pre_f_pix_cnt + 4'd1;                        if(pre_f_pix_cnt >= DVP_FRAME_WAIT_CNT)                            pre_cap_stable <= 1'b1;                    end                else                    pre_cap_stable <= pre_cap_stable;            end        assign capture_failure  = 1'b0;        assign capture_stable       = pre_cap_stable;        assign capture_h_size       = 12'b0;        assign capture_v_size       = 12'b0;    endendgenerateendmodule

dvp_2_axi4s.v

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2017/04/15 01:13:12// Design Name: // Module Name: dvp_2_axi4s// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module dvp_2_axi4s(  //_____________________________________________ axi4s clock    input axis_aclk,    input axis_aresetn,  //_____________________________________________ axi4s signals    output [23:0] m_axis_video_tdata,    output m_axis_video_tlast,    input m_axis_video_tready,    output m_axis_video_tuser,    output m_axis_video_tvalid,  //_____________________________________________ DVP interface  output CAM_XVCLK,  input CAM_PCLK,  input CAM_HREF,  input CAM_VSYNC,  input [7:0] CAM_D,  //_____________________________________________ module control  input capture_en,  output capture_stable,  output capture_failure,  output [11:0] capture_h_size,  output [11:0] capture_v_size    );wire iCLK       = axis_aclk;wire iRST_n = axis_aresetn;wire rx_pclk;wire rx_href;wire rx_vsync;wire [23:0] rx_data;dvp_capture tb_dvp_capture_inst(    //_____________________________________________ system clock    .iCLK(iCLK),    .iRST_n(iRST_n),      //_____________________________________________ module control    .capture_en(capture_en),    .capture_stable(capture_stable),    .capture_failure(capture_failure),    .capture_h_size(capture_h_size),    .capture_v_size(capture_v_size),      //_____________________________________________ DVP interface    .CAM_XVCLK(CAM_XVCLK),    .CAM_PCLK(CAM_PCLK),    .CAM_HREF(CAM_HREF),    .CAM_VSYNC(CAM_VSYNC),    .CAM_D(CAM_D),      //_____________________________________________ parallel signals    .rx_pclk(rx_pclk),    .rx_href(rx_href),    .rx_vsync(rx_vsync),    .rx_data(rx_data)    );wire vid_io_in_ce           = capture_stable;wire vid_io_in_clk      = rx_pclk;wire vid_active_video   = rx_href;wire vid_vsync              = rx_vsync;wire [23:0] vid_data    =   rx_data;wire aclk                   =   axis_aclk;wire aresetn            = axis_aresetn;wire axis_enable    = capture_stable;v_vid_in_axi4s_0 vid_in_inst (  .vid_io_in_clk(vid_io_in_clk),              // input wire vid_io_in_clk  .vid_io_in_ce(vid_io_in_ce),                // input wire vid_io_in_ce  .vid_io_in_reset(1'b0),                               // input wire vid_io_in_reset  .vid_active_video(rx_href),                           // input wire vid_active_video  .vid_vblank(1'b0),                                // input wire vid_vblank  .vid_hblank(1'b0),                                // input wire vid_hblank  .vid_vsync(vid_vsync),                      // input wire vid_vsync  .vid_hsync(1'b0),                                 // input wire vid_hsync  .vid_field_id(1'b0),                              // input wire vid_field_id  .vid_data(vid_data),                        // input wire [23 : 0] vid_data  .aclk(aclk),                                // input wire aclk  .aclken(1'b1),                                // input wire aclken  .aresetn(aresetn),                          // input wire aresetn  .m_axis_video_tdata(m_axis_video_tdata),    // output wire [23 : 0] m_axis_video_tdata  .m_axis_video_tvalid(m_axis_video_tvalid),  // output wire m_axis_video_tvalid  .m_axis_video_tready(m_axis_video_tready),  // input wire m_axis_video_tready  .m_axis_video_tuser(m_axis_video_tuser),    // output wire m_axis_video_tuser  .m_axis_video_tlast(m_axis_video_tlast),    // output wire m_axis_video_tlast  .fid(),                                       // output wire fid  .vtd_active_video(),                                      // output wire vtd_active_video  .vtd_vblank(),                                        // output wire vtd_vblank  .vtd_hblank(),                                        // output wire vtd_hblank  .vtd_vsync(),                                         // output wire vtd_vsync  .vtd_hsync(),                                         // output wire vtd_hsync  .vtd_field_id(),                                      // output wire vtd_field_id  .overflow(),                                      // output wire overflow  .underflow(),                                         // output wire underflow  .axis_enable(capture_stable)                // input wire axis_enable);endmodule

生成Video In to AXI4-Stream IP核的tcl脚本

# this is a collection of useful project utilities# implement touch - opens a file updating the time stamp,# creating it if it does not existproc touch {f} {   set FILEIN [open $f w]   close $FILEIN}# get the directory where this script residesset thisDir [file dirname [info script]]# source common utilitiessource -notrace $thisDir/utils.tclset ipDir ./ipcreate_project -force managed_ip_project_v_vid_in_axi4s $ipDir/managed_ip_project_v_vid_in_axi4s -part xc7z010clg400-1 -ip# Set project propertiesset obj [get_projects]set_property "board_part" "digilentinc.com:zybo:part0:1.0" $objset_property "simulator_language" "Mixed" $objset_property "target_language" "Verilog" $obj#set_property coreContainer.enable 1 $objset_property target_simulator XSim [current_project]create_ip -name v_vid_in_axi4s -vendor xilinx.com -library ip -module_name v_vid_in_axi4s_0 -dir $ipDirset_property -dict [list CONFIG.C_HAS_ASYNC_CLK {1}] [get_ips v_vid_in_axi4s_0]set_property -dict [list CONFIG.C_ADDR_WIDTH {11}] [get_ips v_vid_in_axi4s_0]generate_target all [get_files  v_vid_in_axi4s_0.xci]export_ip_user_files -of_objects [get_files v_vid_in_axi4s_0.xci] -no_script -ip_user_files_dir $ipDir -force -quiet create_ip_run [get_files -of_objects [get_fileset sources_1] [get_files */v_vid_in_axi4s_0.xci]]launch_run  v_vid_in_axi4s_0_synth_1wait_on_run v_vid_in_axi4s_0_synth_1export_simulation -of_objects [get_files v_vid_in_axi4s_0.xci] -force -quiet# If successful, "touch" a file so the make utility will know it's donetouch {.ip.done}
1 0
原创粉丝点击