赞
踩
OV5640 是由豪威科技生产的一款 500 万像素级的 CMOS 图像传感器。它支持高达 2592x1944 分辨率的图像输出,同时能够以 15fps 的帧率输出 QSXGA 分辨率的图像,或者以 90fps 的帧率输出 VGA 分辨率的图像。OV5640 的感光阵列分辨率为 2624x1964(物理尺寸)。
OV5640 的输出接口支持 DVP 接口,控制接口则采用标准的 SCCB 接口(兼容 IIC)。这款摄像头的内部结构较为复杂,包括图像数据的采集、放大、数字信号转换等过程,最终通过 DVP 端口输出。DVP 接口本身拥有 10 位数据线,可以输出 10 位的 RAW 数据,但在大多数情况下,使用 8 位数据线来输出 RGB888 及 RGB565 等格式。
SCCB(Serial Camera Control Bus)是由OmniVision Technologies公司开发的一种串行通信协议,主要用于控制其OV系列的图像传感器。
最顶层模块 ov5640_lcd.v
- `timescale 1ns / 1ps
-
-
- module ov5640_lcd (
- //Differential system clocks
- input sys_clk_p,
- input sys_clk_n,
- 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线
- // DDR4
- output c0_ddr4_act_n, //DDR4激活信号,低电平有效,表示一个内存行被激活。
- output [16:0] c0_ddr4_adr,//地址线,用于指定要访问的内存单元的行和列地址。
- output [1:0] c0_ddr4_ba, //Bank地址线,用于选择内存的Bank。
- output [0:0] c0_ddr4_bg, //Bank组选择,用于选择DDR4内存中的Bank组。
- output [0:0] c0_ddr4_cke, //时钟使能信号,用于启动或停止时钟信号以进入或退出自刷新模式。
- output [0:0] c0_ddr4_odt, //On Die Termination(片上终止)信号,用于控制内存模块上的终端电阻。
- output [0:0] c0_ddr4_cs_n, //片选信号,低电平有效,用于选择哪个内存芯片。
- output [0:0] c0_ddr4_ck_t, //DDR4时钟信号,用于同步数据传输。
- output [0:0] c0_ddr4_ck_c, //DDR4时钟信号的互补信号。
- output c0_ddr4_reset_n, //复位信号,低电平有效,用于重置DDR4内存接口。
- inout [1:0] c0_ddr4_dm_dbi_n, //数据掩码/数据总线隔离信号,用于屏蔽写操作的数据位或在读取操作中提供数据总线隔离。
- inout [15:0] c0_ddr4_dq, //数据线,用于传输数据。
- inout [1:0] c0_ddr4_dqs_c, //数据选通信号(DQS)的互补信号,用于采样数据。
- inout [1:0] c0_ddr4_dqs_t, //数据选通信号,用于指示数据线上的数据是有效的。
-
- //lcd接口
- output lcd_hs, //LCD 行同步信号
- output lcd_vs, //LCD 场同步信号
- output lcd_de, //LCD 数据输入使能
- output [23:0] lcd_rgb, //LCD 颜色数据
- output lcd_bl, //LCD 背光控制信号
- output lcd_rst, //LCD 复位信号
- output lcd_pclk //LCD 采样时钟
- );
-
- //wire define
- wire clk_50m; //50mhz时钟,提供给lcd驱动时钟
- wire locked; //时钟锁定信号
- wire rst_n; //全局复位
- wire i2c_exec; //I2C触发执行信号
- wire [23:0] i2c_data; //I2C要配置的地址与数据(高8位地址,低8位数据)
- wire cam_init_done; //摄像头初始化完成
- wire i2c_done; //I2C寄存器配置完成信号
- wire i2c_dri_clk; //I2C操作时钟
- wire wr_en; //DDR4控制器模块写使能
- wire [15:0] wr_data; //DDR4控制器模块写数据
- wire rdata_req; //DDR4控制器模块读使能
- wire [15:0] rd_data; //DDR4控制器模块读数据
- wire cmos_frame_valid; //数据有效使能信号
- wire init_calib_complete; //DDR4初始化完成init_calib_complete
- wire sys_init_done; //系统初始化完成(DDR初始化+摄像头初始化)
- wire cmos_frame_vsync; //输出帧有效场同步信号
- wire cmos_frame_href; //输出帧有效行同步信号
- wire [27:0] app_addr_rd_min; //读DDR4的起始地址
- wire [27:0] app_addr_rd_max; //读DDR4的结束地址
- wire [7:0] rd_bust_len; //从DDR4中读数据时的突发长度
- wire [27:0] app_addr_wr_min; //写DDR4的起始地址
- wire [27:0] app_addr_wr_max; //写DDR4的结束地址
- wire [7:0] wr_bust_len; //从DDR4中写数据时的突发长度
- wire lcd_clk; //分频产生的LCD 采样时钟
-
- wire i2c_rh_wl; //I2C读写控制信号
- wire [7:0] i2c_data_r; //I2C读数据
- wire [10:0] h_pixel; //存入ddr4的水平分辨率
- wire [10:0] v_pixel; //存入ddr4的屏垂直分辨率
-
- wire [12:0] h_disp = 13'd800; //LCD屏水平分辨率
- wire [12:0] v_disp = 13'd480; //LCD屏垂直分辨率
- wire [27:0] ddr4_addr_max = 23'd384000; //存入DDR4的最大读写地址
- //对HTS及VTS的配置会影响摄像头输出图像的帧率
- wire [12:0] total_h_pixel = 13'd1800; //水平总像素大小
- wire [12:0] total_v_pixel = 13'd1000; //垂直总像素大小
- //*****************************************************
- //** main code
- //*****************************************************
- //系统初始化完成:DDR4初始化完成
- assign sys_init_done = init_calib_complete;
- assign cam_sda = cam_sda_t ? cam_sda_o : 1'bz;
- assign cam_sda_i = cam_sda;
-
- //ov5640 驱动
- ov5640_dri u_ov5640_dri (
- .clk (clk_50m),
- .rst_n(sys_rst_n),
-
- .cam_pclk (cam_pclk), //像素时钟,用于同步数据传输。
- .cam_vsync(cam_vsync), //垂直同步信号,表示一帧的开始。
- .cam_href (cam_href), //行有效信号,表示当前数据是有效图像数据。
- .cam_data (cam_data), //图像数据信号,用于传输图像的像素信息。
- .cam_rst_n(cam_rst_n), //OV5640的复位信号,低电平时复位传感器。
- .cam_pwdn (cam_pwdn), //电源休眠模式选择 0:正常模式 1:电源休眠模式
- .cam_scl (cam_scl), //cmos SCCB_SCL线
- .cam_sda_i(cam_sda_i), //cmos SCCB_SDA输入
- .cam_sda_o(cam_sda_o), //cmos SCCB_SDA输出
- .cam_sda_t(cam_sda_t), //cmos SCCB_SDA使能
-
- .capture_start (init_calib_complete), //开始捕获图像的信号
- .cmos_h_pixel (h_disp), //水平方向分辨率
- .cmos_v_pixel (v_disp), //垂直方向分辨率
- .total_h_pixel (total_h_pixel), //水平总像素大小
- .total_v_pixel (total_v_pixel), //垂直总像素大小
- .cmos_frame_vsync(cmos_frame_vsync), //帧有效信号
- .cmos_frame_href (),
- .cmos_frame_valid(cmos_frame_valid), //数据有效使能信号
- .cmos_frame_data (wr_data) //有效数据
- );
-
- ddr4_top u_ddr4_top (
-
- .sys_rst_n (sys_rst_n), //复位,低有效
- .sys_init_done (sys_init_done), //系统初始化完成
- .init_calib_complete(init_calib_complete), //ddr4初始化完成信号
- //ddr4接口信号
- .app_addr_rd_min (28'd0), //读ddr4的起始地址
- .app_addr_rd_max (ddr4_addr_max[27:0]), //读ddr4的结束地址
- .rd_bust_len (h_disp[10:3]), //从ddr4中读数据时的突发长度
- .app_addr_wr_min (28'd0), //写ddr4的起始地址
- .app_addr_wr_max (ddr4_addr_max[27:0]), //写ddr4的结束地址
- .wr_bust_len (h_disp[10:3]), //从ddr4中写数据时的突发长度
- // ddr4 IO接口
- .c0_sys_clk_p (sys_clk_p),
- .c0_sys_clk_n (sys_clk_n),
- .c0_ddr4_act_n (c0_ddr4_act_n),
- .c0_ddr4_adr (c0_ddr4_adr),
- .c0_ddr4_ba (c0_ddr4_ba),
- .c0_ddr4_bg (c0_ddr4_bg),
- .c0_ddr4_cke (c0_ddr4_cke),
- .c0_ddr4_odt (c0_ddr4_odt),
- .c0_ddr4_cs_n (c0_ddr4_cs_n),
- .c0_ddr4_ck_t (c0_ddr4_ck_t),
- .c0_ddr4_ck_c (c0_ddr4_ck_c),
- .c0_ddr4_reset_n (c0_ddr4_reset_n),
- .c0_ddr4_dm_dbi_n (c0_ddr4_dm_dbi_n),
- .c0_ddr4_dq (c0_ddr4_dq),
- .c0_ddr4_dqs_c (c0_ddr4_dqs_c),
- .c0_ddr4_dqs_t (c0_ddr4_dqs_t),
-
- //用户
- .clk_50m (clk_50m),
- .ddr4_read_valid (1'b1), //DDR4 读使能
- .ddr4_pingpang_en(1'b1), //DDR4 乒乓操作使能
- .wr_clk (cam_pclk), //写时钟
- .wr_load (cmos_frame_vsync), //输入源更新信号
- .datain_valid (cmos_frame_valid), //数据有效使能信号
- .datain (wr_data), //有效数据
- .rd_clk (lcd_clk), //读时钟
- .rd_load (rd_vsync), //输出源更新信号
- .dataout (rd_data), //rfifo输出数据
- .rdata_req (rdata_req) //请求数据输入
- );
-
- //LCD驱动显示模块
- lcd_rgb_top u_lcd_rgb_top (
- .sys_clk (clk_50m),
- .sys_rst_n (sys_rst_n),
- .sys_init_done(sys_init_done),
-
- //lcd接口
- .lcd_hs (lcd_hs), //LCD 行同步信号
- .lcd_vs (lcd_vs), //LCD 场同步信号
- .lcd_de (lcd_de), //LCD 数据输入使能
- .lcd_rgb (lcd_rgb), //LCD 颜色数据
- .lcd_bl (lcd_bl), //LCD 背光控制信号
- .lcd_rst (lcd_rst), //LCD 复位信号
- .lcd_pclk(lcd_pclk), //LCD 采样时钟
- .lcd_clk (lcd_clk), //LCD 驱动时钟
-
- //用户接口
- .out_vsync (rd_vsync), //lcd场信号
- .h_disp (), //行分辨率
- .v_disp (), //场分辨率
- .pixel_xpos(), //像素点横坐标
- .pixel_ypos(), //像素点纵坐标
- .data_in (rd_data), //rfifo输出数据
- .data_req (rdata_req) //请求数据输入
- );
-
- endmodule
ddr4_top.v
- `timescale 1ns / 1ps
- //ddr4顶层模块
-
- module ddr4_top (
- input sys_rst_n, //复位,低有效
- input sys_init_done, //系统初始化完成
- // //DDR4接口信号
- input [27:0] app_addr_rd_min, //读DDR4的起始地址
- input [27:0] app_addr_rd_max, //读DDR4的结束地址
- input [ 7:0] rd_bust_len, //从DDR4中读数据时的突发长度
- input [27:0] app_addr_wr_min, //读DDR4的起始地址
- input [27:0] app_addr_wr_max, //读DDR4的结束地址
- input [ 7:0] wr_bust_len, //从DDR4中读数据时的突发长度
- // DDR4 IO接口
- input c0_sys_clk_p,
- input c0_sys_clk_n,
- output c0_ddr4_act_n,
- output [16:0] c0_ddr4_adr,
- output [ 1:0] c0_ddr4_ba,
- output [ 0:0] c0_ddr4_bg,
- output [ 0:0] c0_ddr4_cke,
- output [ 0:0] c0_ddr4_odt,
- output [ 0:0] c0_ddr4_cs_n,
- output [ 0:0] c0_ddr4_ck_t,
- output [ 0:0] c0_ddr4_ck_c,
- output c0_ddr4_reset_n,
- inout [ 1:0] c0_ddr4_dm_dbi_n,
- inout [15:0] c0_ddr4_dq,
- inout [ 1:0] c0_ddr4_dqs_c,
- inout [ 1:0] c0_ddr4_dqs_t,
-
- //用户
- input ddr4_read_valid, //DDR4 读使能
- input ddr4_pingpang_en, //DDR4 乒乓操作使能
- input wr_clk, //wfifo时钟
- input rd_clk, //rfifo的读时钟
- input datain_valid, //数据有效使能信号
- input [15:0] datain, //有效数据
- input rdata_req, //请求像素点颜色数据输入
- input rd_load, //输出源更新信号
- input wr_load, //输入源更新信号
- output [15:0] dataout, //rfifo输出数据
- output clk_50m,
- output init_calib_complete //ddr4初始化完成信号
- );
-
- //wire define
- wire ui_clk; //用户时钟
- wire [ 27:0] app_addr; //ddr4 地址
- wire [ 2:0] app_cmd; //用户读写命令
- wire app_en; //MIG IP核使能
- wire app_rdy; //MIG IP核空闲
- wire [127:0] app_rd_data; //用户读数据
- wire app_rd_data_end; //突发读当前时钟最后一个数据
- wire app_rd_data_valid; //读数据有效
- wire [127:0] app_wdf_data; //用户写数据
- wire app_wdf_end; //突发写当前时钟最后一个数据
- wire [ 15:0] app_wdf_mask; //写数据屏蔽
- wire app_wdf_rdy; //写空闲
- wire app_sr_active; //保留
- wire app_ref_ack; //刷新请求
- wire app_zq_ack; //ZQ 校准请求
- wire app_wdf_wren; //ddr4 写使能
- wire clk_ref_i; //ddr4参考时钟
- wire sys_clk_i; //MIG IP核输入时钟
- wire ui_clk_sync_rst; //用户复位信号
- wire [ 20:0] rd_cnt; //实际读地址计数
- wire [3 : 0] state_cnt; //状态计数器
- wire [ 23:0] rd_addr_cnt; //用户读地址计数器
- wire [ 23:0] wr_addr_cnt; //用户写地址计数器
- wire rfifo_wren; //从ddr4读出数据的有效使能
- wire [ 10:0] wfifo_rcount; //rfifo剩余数据计数
- wire [ 10:0] rfifo_wcount; //wfifo写进数据计数
-
-
- //*****************************************************
- //** main code
- //*****************************************************
-
- //读写模块
- ddr4_rw u_ddr4_rw (
- .ui_clk(ui_clk),
- .ui_clk_sync_rst(ui_clk_sync_rst),
- //MIG 接口
- .init_calib_complete (init_calib_complete) , //ddr4初始化完成信号
- .app_rdy(app_rdy), //MIG IP核空闲
- .app_wdf_rdy(app_wdf_rdy), //写空闲
- .app_rd_data_valid(app_rd_data_valid), //读数据有效
- .app_addr(app_addr), //ddr4 地址
- .app_en(app_en), //MIG IP核使能
- .app_wdf_wren(app_wdf_wren), //ddr4 写使能
- .app_wdf_end (app_wdf_end) , //突发写当前时钟最后一个数据
- .app_cmd (app_cmd) , //用户读写命令
- //ddr4 地址参数
- .app_addr_rd_min(app_addr_rd_min), //读ddr4的起始地址
- .app_addr_rd_max(app_addr_rd_max), //读ddr4的结束地址
- .rd_bust_len (rd_bust_len) , //从ddr4中读数据时的突发长度
- .app_addr_wr_min(app_addr_wr_min), //写ddr4的起始地址
- .app_addr_wr_max(app_addr_wr_max), //写ddr4的结束地址
- .wr_bust_len (wr_bust_len) , //从ddr4中写数据时的突发长度
- //用户接口
- .rfifo_wren(rfifo_wren), //从ddr4读出数据的有效使能
- .rd_load(rd_load), //输出源更新信号
- .wr_load(wr_load), //输入源更新信号
- .ddr4_read_valid(ddr4_read_valid), //ddr4 读使能
- .ddr4_pingpang_en(ddr4_pingpang_en), //ddr4 乒乓操作使能
- .wfifo_rcount(wfifo_rcount), //rfifo剩余数据计数
- .rfifo_wcount(rfifo_wcount) //wfifo写进数据计数
- );
-
- ddr4_0 u_ddr4_0 (
- .c0_init_calib_complete(init_calib_complete), // output wire c0_init_calib_complete
- .dbg_clk(), // output wire dbg_clk
- .c0_sys_clk_p(c0_sys_clk_p), // input wire c0_sys_clk_p
- .c0_sys_clk_n(c0_sys_clk_n), // input wire c0_sys_clk_n
- .dbg_bus(), // output wire [511 : 0] dbg_bus
- .c0_ddr4_adr(c0_ddr4_adr), // output wire [16 : 0] c0_ddr4_adr
- .c0_ddr4_ba(c0_ddr4_ba), // output wire [1 : 0] c0_ddr4_ba
- .c0_ddr4_cke(c0_ddr4_cke), // output wire [0 : 0] c0_ddr4_cke
- .c0_ddr4_cs_n(c0_ddr4_cs_n), // output wire [0 : 0] c0_ddr4_cs_n
- .c0_ddr4_dm_dbi_n(c0_ddr4_dm_dbi_n), // inout wire [1 : 0] c0_ddr4_dm_dbi_n
- .c0_ddr4_dq(c0_ddr4_dq), // inout wire [15 : 0] c0_ddr4_dq
- .c0_ddr4_dqs_c(c0_ddr4_dqs_c), // inout wire [1 : 0] c0_ddr4_dqs_c
- .c0_ddr4_dqs_t(c0_ddr4_dqs_t), // inout wire [1 : 0] c0_ddr4_dqs_t
- .c0_ddr4_odt(c0_ddr4_odt), // output wire [0 : 0] c0_ddr4_odt
- .c0_ddr4_bg(c0_ddr4_bg), // output wire [0 : 0] c0_ddr4_bg
- .c0_ddr4_reset_n(c0_ddr4_reset_n), // output wire c0_ddr4_reset_n
- .c0_ddr4_act_n(c0_ddr4_act_n), // output wire c0_ddr4_act_n
- .c0_ddr4_ck_c(c0_ddr4_ck_c), // output wire [0 : 0] c0_ddr4_ck_c
- .c0_ddr4_ck_t(c0_ddr4_ck_t), // output wire [0 : 0] c0_ddr4_ck_t
- //user interface
- .c0_ddr4_ui_clk(ui_clk), // output wire c0_ddr4_ui_clk 用户时钟
- .c0_ddr4_ui_clk_sync_rst(ui_clk_sync_rst), // output wire c0_ddr4_ui_clk_sync_rst 用户复位
- .c0_ddr4_app_en(app_en), // input wire c0_ddr4_app_en
- .c0_ddr4_app_hi_pri(1'b0), // input wire c0_ddr4_app_hi_pri
- .c0_ddr4_app_wdf_end(app_wdf_end), // input wire c0_ddr4_app_wdf_end
- .c0_ddr4_app_wdf_wren(app_wdf_wren), // input wire c0_ddr4_app_wdf_wren
- .c0_ddr4_app_rd_data_end(app_rd_data_end), // output wire c0_ddr4_app_rd_data_end
- .c0_ddr4_app_rd_data_valid(app_rd_data_valid), // output wire c0_ddr4_app_rd_data_valid
- .c0_ddr4_app_rdy(app_rdy), // output wire c0_ddr4_app_rdy
- .c0_ddr4_app_wdf_rdy(app_wdf_rdy), // output wire c0_ddr4_app_wdf_rdy
- .c0_ddr4_app_addr(app_addr), // input wire [27 : 0] c0_ddr4_app_addr
- .c0_ddr4_app_cmd(app_cmd), // input wire [2 : 0] c0_ddr4_app_cmd
- .c0_ddr4_app_wdf_data(app_wdf_data), // input wire [127 : 0] c0_ddr4_app_wdf_data
- .c0_ddr4_app_wdf_mask(16'b0), // input wire [15 : 0] c0_ddr4_app_wdf_mask
- .c0_ddr4_app_rd_data(app_rd_data), // output wire [127 : 0] c0_ddr4_app_rd_data
- .addn_ui_clkout1(clk_50m), // output wire addn_ui_clkout1
- .sys_rst(~sys_rst_n) // input wire sys_rst
- );
-
- ddr4_fifo_ctrl u_ddr4_fifo_ctrl (
-
- .rst_n (sys_rst_n && sys_init_done),
- //输入源接口
- .wr_clk (wr_clk),
- .rd_clk (rd_clk),
- .clk_100 (ui_clk), //用户时钟
- .datain_valid(datain_valid), //数据有效使能信号
- .datain (datain), //有效数据
- .rfifo_din (app_rd_data), //用户读数据
- .rdata_req (rdata_req), //请求像素点颜色数据输入
- .rfifo_wren (rfifo_wren), //ddr4读出数据的有效使能
- .wfifo_rden (app_wdf_wren), //ddr4 写使能
- //用户接口
- .wfifo_rcount(wfifo_rcount), //rfifo剩余数据计数
- .rfifo_wcount(rfifo_wcount), //wfifo写进数据计数
- .wfifo_dout (app_wdf_data), //用户写数据
- .rd_load (rd_load), //输出源更新信号
- .wr_load (wr_load), //输入源更新信号
- .pic_data (dataout) //rfifo输出数据
- );
-
- endmodule
MIG配置
ddr4_rw.v
- `timescale 1ns / 1ps
- //ddr3控制器读写模块
-
-
- module ddr4_rw (
- input ui_clk, //用户时钟
- input ui_clk_sync_rst, //复位,高有效
- input init_calib_complete, //ddr4初始化完成
- input app_rdy, //MIG IP核空闲
- input app_wdf_rdy, //MIG写FIFO空闲
- input app_rd_data_valid, //读数据有效
- input [10:0] wfifo_rcount, //写端口FIFO中的数据量
- input [10:0] rfifo_wcount, //读端口FIFO中的数据量
- input rd_load, //输出源更新信号
- input wr_load, //输入源更新信号
- input [27:0] app_addr_rd_min, //读ddr4的起始地址
- input [27:0] app_addr_rd_max, //读ddr4的结束地址
- input [ 7:0] rd_bust_len, //从ddr4中读数据时的突发长度
- input [27:0] app_addr_wr_min, //写ddr4的起始地址
- input [27:0] app_addr_wr_max, //写ddr4的结束地址
- input [ 7:0] wr_bust_len, //从ddr4中写数据时的突发长度
-
- input ddr4_read_valid, //ddr4 读使能
- input ddr4_pingpang_en, //ddr4 乒乓操作使能
- output rfifo_wren, //从ddr4读出数据的有效使能
- output [27:0] app_addr, //ddr4地址
- output app_en, //MIG IP核操作使能
- output app_wdf_wren, //用户写使能
- output app_wdf_end, //突发写当前时钟最后一个数据
- output [ 2:0] app_cmd //MIG IP核操作命令,读或者写
- );
-
- //localparam
- localparam IDLE = 4'b0001; //空闲状态
- localparam ddr4_DONE = 4'b0010; //ddr4初始化完成状态
- localparam WRITE = 4'b0100; //读FIFO保持状态
- localparam READ = 4'b1000; //写FIFO保持状态
-
- //reg define
- reg [27:0] app_addr; //ddr4地址
- reg [27:0] app_addr_rd; //ddr4读地址
- reg [27:0] app_addr_wr; //ddr4写地址
- reg [ 3:0] state_cnt; //状态计数器
- reg [23:0] rd_addr_cnt; //用户读地址计数
- reg [23:0] wr_addr_cnt; //用户写地址计数
- reg [ 8:0] burst_rd_cnt; //突发读次数计数器
- reg [ 8:0] burst_wr_cnt; //突发写次数计数器
- reg [10:0] raddr_rst_h_cnt; //输出源的帧复位脉冲进行计数
- reg [27:0] app_addr_rd_min_a; //读ddr4的起始地址
- reg [27:0] app_addr_rd_max_a; //读ddr4的结束地址
- reg [ 7:0] rd_bust_len_a; //从ddr4中读数据时的突发长度
- reg [27:0] app_addr_wr_min_a; //写ddr4的起始地址
- reg [27:0] app_addr_wr_max_a; //写ddr4的结束地址
- reg [ 7:0] wr_bust_len_a; //从ddr4中写数据时的突发长度
- reg star_rd_flag; //复位后写入2帧的标志信号
- reg rd_load_d0;
- reg rd_load_d1;
- reg raddr_rst_h; //输出源的帧复位脉冲
- reg wr_load_d0;
- reg wr_load_d1;
- reg wr_rst; //输入源帧复位标志
- reg rd_rst; //输出源帧复位标志
- reg raddr_page; //ddr4读地址切换信号
- reg waddr_page; //ddr4写地址切换信号
- reg burst_done_wr; //一次突发写结束信号
- reg burst_done_rd; //一次读发写结束信号
- reg wr_end; //一次突发写结束信号
- reg rd_end; //一次读发写结束信号
-
- wire rst_n;
-
- //*****************************************************
- //** main code
- //*****************************************************
-
- //将数据有效信号赋给wfifo写使能
- assign rfifo_wren = app_rd_data_valid;
-
- assign rst_n = ~ui_clk_sync_rst;
-
- //在写状态MIG空闲且写有效,或者在读状态MIG空闲,此时使能信号为高,其他情况为低
- assign app_en = ((state_cnt == WRITE && (app_rdy && app_wdf_rdy))
- ||(state_cnt == READ && app_rdy)) ? 1'b1:1'b0;
-
- //在写状态,MIG空闲且写有效,此时拉高写使能
- assign app_wdf_wren = (state_cnt == WRITE && (app_rdy && app_wdf_rdy)) ? 1'b1 : 1'b0;
-
- //由于我们ddr4芯片时钟和用户时钟的分频选择4:1,突发长度为8,故两个信号相同
- assign app_wdf_end = app_wdf_wren;
-
- //处于读的时候命令值为1,其他时候命令值为0
- assign app_cmd = (state_cnt == READ) ? 3'd1 : 3'd0;
-
- //将数据读写地址赋给ddr地址
- always @(*) begin
- if (~rst_n) app_addr <= 0;
- else if (state_cnt == READ)
- if (ddr4_pingpang_en) app_addr <= {2'b0, raddr_page, app_addr_rd[24:0]};
- else app_addr <= {3'b0, app_addr_rd[24:0]};
- else if (ddr4_pingpang_en) app_addr <= {2'b0, waddr_page, app_addr_wr[24:0]};
- else app_addr <= {3'b0, app_addr_wr[24:0]};
- end
-
- //对信号进行打拍处理
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) begin
- rd_load_d0 <= 0;
- rd_load_d1 <= 0;
- wr_load_d0 <= 0;
- wr_load_d1 <= 0;
- end else begin
- rd_load_d0 <= rd_load;
- rd_load_d1 <= rd_load_d0;
- wr_load_d0 <= wr_load;
- wr_load_d1 <= wr_load_d0;
- end
- end
-
- //对异步信号进行打拍处理
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) begin
- app_addr_rd_min_a <= 0;
- app_addr_rd_max_a <= 0;
- rd_bust_len_a <= 0;
- app_addr_wr_min_a <= 0;
- app_addr_wr_max_a <= 0;
- wr_bust_len_a <= 0;
- end else begin
- app_addr_rd_min_a <= app_addr_rd_min;
- app_addr_rd_max_a <= app_addr_rd_max;
- rd_bust_len_a <= rd_bust_len;
- app_addr_wr_min_a <= app_addr_wr_min;
- app_addr_wr_max_a <= app_addr_wr_max;
- wr_bust_len_a <= wr_bust_len;
- end
- end
-
- //对输入源做个帧复位标志
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) wr_rst <= 0;
- else if (wr_load_d0 && !wr_load_d1) wr_rst <= 1;
- else wr_rst <= 0;
- end
-
- //对输出源做个帧复位标志
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) rd_rst <= 0;
- else if (rd_load_d0 && !rd_load_d1) rd_rst <= 1;
- else rd_rst <= 0;
- end
-
- //对输出源的读地址做个帧复位脉冲
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) raddr_rst_h <= 1'b0;
- else if (rd_load_d0 && !rd_load_d1) raddr_rst_h <= 1'b1;
- else if (app_addr_rd == app_addr_rd_min_a) raddr_rst_h <= 1'b0;
- else raddr_rst_h <= raddr_rst_h;
- end
- //对输出源的帧复位脉冲进行计数
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) raddr_rst_h_cnt <= 11'b0;
- else if (raddr_rst_h) raddr_rst_h_cnt <= raddr_rst_h_cnt + 1'b1;
- else raddr_rst_h_cnt <= 11'b0;
- end
-
- //对输出源帧的读地址高位切换
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) raddr_page <= 1'b0;
- else if (rd_end) raddr_page <= ~waddr_page;
- else raddr_page <= raddr_page;
- end
- //对输入源帧的写地址高位切换
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) waddr_page <= 1'b1;
- else if (wr_end) waddr_page <= ~waddr_page;
- else waddr_page <= waddr_page;
- end
-
- //ddr4读写逻辑实现
- always @(posedge ui_clk or negedge rst_n) begin
- if (~rst_n) begin
- state_cnt <= IDLE;
- wr_addr_cnt <= 24'd0;
- rd_addr_cnt <= 24'd0;
- app_addr_wr <= 28'd0;
- app_addr_rd <= 28'd0;
- wr_end <= 1'b0;
- rd_end <= 1'b0;
- end else begin
- case (state_cnt)
- IDLE: begin
- if (init_calib_complete) state_cnt <= ddr4_DONE;
- else state_cnt <= IDLE;
- end
- ddr4_DONE: begin
- if (wr_rst) begin //当帧复位到来时,对寄存器进行复位
- state_cnt <= ddr4_DONE;
- wr_addr_cnt <= 24'd0;
- app_addr_wr <= app_addr_wr_min_a;
- end //当读到结束地址对寄存器复位
- else if(app_addr_rd >= app_addr_rd_max_a - 8)begin
- state_cnt <= ddr4_DONE;
- rd_addr_cnt <= 24'd0;
- app_addr_rd <= app_addr_rd_min_a;
- rd_end <= 1'b1;
- end //当写到结束地址对寄存器复位
- else if(app_addr_wr >= app_addr_wr_max_a - 8)begin
- state_cnt <= ddr4_DONE;
- rd_addr_cnt <= 24'd0;
- app_addr_wr <= app_addr_wr_min_a;
- wr_end <= 1'b1;
- end else if (wfifo_rcount >= wr_bust_len_a - 2) begin
- state_cnt <= WRITE; //跳到写操作
- wr_addr_cnt <= 24'd0;
- app_addr_wr <= app_addr_wr; //写地址保持不变
- end else if (raddr_rst_h) begin //当帧复位到来时,对寄存器进行复位
- if (raddr_rst_h_cnt >= 1000 && ddr4_read_valid) begin
- state_cnt <= READ; //保证读fifo在复位时不回写入数据
- rd_addr_cnt <= 24'd0;
- app_addr_rd <= app_addr_rd_min_a;
- end else begin
- state_cnt <= ddr4_DONE;
- rd_addr_cnt <= 24'd0;
- app_addr_rd <= app_addr_rd;
- end
- end //当rfifo存储数据少于一次突发长度时,并且ddr已经写入了1帧数据
- else if(rfifo_wcount < rd_bust_len_a && ddr4_read_valid )begin
- state_cnt <= READ; //跳到读操作
- rd_addr_cnt <= 24'd0;
- app_addr_rd <= app_addr_rd; //读地址保持不变
- end else begin
- state_cnt <= state_cnt;
- wr_addr_cnt <= 24'd0;
- rd_addr_cnt <= 24'd0;
- rd_end <= 1'b0;
- wr_end <= 1'b0;
- end
- end
- WRITE: begin
- if((wr_addr_cnt == (wr_bust_len_a - 1)) &&
- (app_rdy && app_wdf_rdy))begin //写到设定的长度跳到等待状态
- state_cnt <= ddr4_DONE; //写到设定的长度跳到等待状态
- app_addr_wr <= app_addr_wr + 8; //一次性写进8个数,故加8
- end else if (app_rdy && app_wdf_rdy) begin //写条件满足
- wr_addr_cnt <= wr_addr_cnt + 1'd1; //写地址计数器自加
- app_addr_wr <= app_addr_wr + 8; //一次性写进8个数,故加8
- end else begin //写条件不满足,保持当前值
- wr_addr_cnt <= wr_addr_cnt;
- app_addr_wr <= app_addr_wr;
- end
- end
- READ: begin //读到设定的地址长度
- if ((rd_addr_cnt == (rd_bust_len_a - 1)) && app_rdy) begin
- state_cnt <= ddr4_DONE; //则跳到空闲状态
- app_addr_rd <= app_addr_rd + 8;
-
- end else if (app_rdy) begin //若MIG已经准备好,则开始读
- rd_addr_cnt <= rd_addr_cnt + 1'd1; //用户地址计数器每次加一
- app_addr_rd <= app_addr_rd + 8; //一次性读出8个数,ddr4地址加8
- end else begin //若MIG没准备好,则保持原值
- rd_addr_cnt <= rd_addr_cnt;
- app_addr_rd <= app_addr_rd;
- end
- end
- default: begin
- state_cnt <= IDLE;
- wr_addr_cnt <= 24'd0;
- rd_addr_cnt <= 24'd0;
- end
- endcase
- end
- end
- endmodule
读FIFO配置
写FIFO配置
ddr4_fifo_ctrl.v
- // ddr控制器fifo控制模块
-
-
- `timescale 1ns / 1ps
- module ddr4_fifo_ctrl (
- input rst_n, //复位信号
- input wr_clk, //wfifo时钟
- input rd_clk, //rfifo时钟
- input clk_100, //用户时钟
- input datain_valid, //数据有效使能信号
- input [ 15:0] datain, //有效数据
- input [127:0] rfifo_din, //用户读数据
- input rdata_req, //请求像素点颜色数据输入
- input rfifo_wren, //从ddr4读出数据的有效使能
- input wfifo_rden, //wfifo读使能
- input rd_load, //输出源场信号
- input wr_load, //输入源场信号
-
- output [127:0] wfifo_dout, //用户写数据
- output [ 10:0] wfifo_rcount, //rfifo剩余数据计数
- output [ 10:0] rfifo_wcount, //wfifo写进数据计数
- output reg [ 15:0] pic_data //有效数据
- );
-
- //reg define
- reg [127:0] datain_t; //由16bit输入源数据移位拼接得到
- reg [7:0] cam_data_d0;
- reg [4:0] i_d0;
- reg [30:0] rd_load_d; //由输出源场信号移位拼接得到
- reg [6:0] byte_cnt; //写数据移位计数器
- reg [127:0] data; //rfifo输出数据打拍得到
- reg [4:0] i; //读数据移位计数器
- reg [15:0] wr_load_d; //由输入源场信号移位拼接得到
- reg [3:0] cmos_ps_cnt; //等待帧数稳定计数器
- reg cam_href_d0;
- reg cam_href_d1;
- reg wr_load_d0;
- reg rd_load_d0;
- reg rdfifo_rst_h; //rfifo复位信号,高有效
- reg wr_load_d1;
- reg wfifo_rst_h; //wfifo复位信号,高有效
- reg wfifo_wren; //wfifo写使能信号
-
- //wire define
- wire [127:0] rfifo_dout; //rfifo输出数据
- wire [127:0] wfifo_din; //wfifo写数据
- wire [15:0] dataout[0:15]; //定义输出数据的二维数组
- wire rfifo_rden; //rfifo的读使能
-
- //*****************************************************
- //** main code
- //*****************************************************
-
- //rfifo输出的数据存到二维数组
- assign dataout[0] = data[127:112];
- assign dataout[1] = data[111:96];
- assign dataout[2] = data[95:80];
- assign dataout[3] = data[79:64];
- assign dataout[4] = data[63:48];
- assign dataout[5] = data[47:32];
- assign dataout[6] = data[31:16];
- assign dataout[7] = data[15:0];
-
- assign wfifo_din = datain_t;
-
- //移位寄存器计满时,从rfifo读出一个数据
- assign rfifo_rden = (rdata_req && (i == 7)) ? 1'b1 : 1'b0;
-
- //16位数据转128位RGB565数据
- always @(posedge wr_clk or negedge rst_n) begin
- if (!rst_n) begin
- datain_t <= 0;
- byte_cnt <= 0;
- end else if (datain_valid) begin
- if (byte_cnt == 7) begin
- byte_cnt <= 0;
- datain_t <= {datain_t[111:0], datain};
- end else begin
- byte_cnt <= byte_cnt + 1;
- datain_t <= {datain_t[111:0], datain};
- end
- end else begin
- byte_cnt <= byte_cnt;
- datain_t <= datain_t;
- end
- end
-
- //wfifo写使能产生
- always @(posedge wr_clk or negedge rst_n) begin
- if (!rst_n) wfifo_wren <= 0;
- else if (wfifo_wren == 1) wfifo_wren <= 0;
- else if (byte_cnt == 7 && datain_valid) //输入源数据传输8次,写使能拉高一次
- wfifo_wren <= 1;
- else wfifo_wren <= 0;
- end
-
- always @(posedge rd_clk or negedge rst_n) begin
- if (!rst_n) data <= 127'b0;
- else data <= rfifo_dout;
- end
- //对rfifo出来的128bit数据拆解成16个16bit数据
- always @(posedge rd_clk or negedge rst_n) begin
- if (!rst_n) begin
- pic_data <= 16'b0;
- i <= 0;
- i_d0 <= 0;
- end else if (rdata_req) begin
- if (i == 7) begin
- pic_data <= dataout[i_d0];
- i <= 0;
- i_d0 <= i;
- end else begin
- pic_data <= dataout[i_d0];
- i <= i + 1;
- i_d0 <= i;
- end
- end else begin
- pic_data <= pic_data;
- i <= 0;
- i_d0 <= 0;
- end
- end
-
- always @(posedge clk_100 or negedge rst_n) begin
- if (!rst_n) rd_load_d0 <= 1'b0;
- else rd_load_d0 <= rd_load;
- end
- //对输出源场信号进行移位寄存
- always @(posedge clk_100 or negedge rst_n) begin
- if (!rst_n) rd_load_d <= 1'b0;
- else rd_load_d <= {rd_load_d[30:0], rd_load_d0};
- end
-
- //产生一段复位电平,满足fifo复位时序
- always @(posedge clk_100 or negedge rst_n) begin
- if (!rst_n) rdfifo_rst_h <= 1'b0;
- else if (rd_load_d[0] && !rd_load_d[29]) rdfifo_rst_h <= 1'b1;
- else rdfifo_rst_h <= 1'b0;
- end
- //对输入源场信号进行移位寄存
- always @(posedge wr_clk or negedge rst_n) begin
- if (!rst_n) begin
- wr_load_d0 <= 1'b0;
- wr_load_d <= 16'b0;
- end else begin
- wr_load_d0 <= wr_load;
- wr_load_d <= {wr_load_d[14:0], wr_load_d0};
- end
- end
- //产生一段复位电平,满足fifo复位时序
- always @(posedge wr_clk or negedge rst_n) begin
- if (!rst_n) wfifo_rst_h <= 1'b0;
- else if (wr_load_d[0] && !wr_load_d[15]) wfifo_rst_h <= 1'b1;
- else wfifo_rst_h <= 1'b0;
- end
-
- rd_fifo u_rd_fifo (
- .rst (~rst_n | rdfifo_rst_h),
- .wr_clk (clk_100),
- .rd_clk (rd_clk),
- .din (rfifo_din),
- .wr_en (rfifo_wren),
- .rd_en (rfifo_rden),
- .dout (rfifo_dout),
- .full (),
- .empty (),
- .rd_data_count(),
- .wr_data_count(rfifo_wcount),
- .wr_rst_busy (),
- .rd_rst_busy ()
- );
-
- wr_fifo u_wr_fifo (
- .rst (~rst_n | wfifo_rst_h),
- .wr_clk (wr_clk),
- .rd_clk (clk_100),
- .din (wfifo_din),
- .wr_en (wfifo_wren),
- .rd_en (wfifo_rden),
- .dout (wfifo_dout),
- .full (),
- .empty (),
- .rd_data_count(wfifo_rcount),
- .wr_data_count(),
- .wr_rst_busy (),
- .rd_rst_busy ()
- );
-
- endmodule
-
ov5640_dri.v
- `timescale 1ns / 1ps
- //ov5640驱动顶层模块
-
-
- module ov5640_dri (
- input clk, //50m时钟
- 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线
- input cam_sda_i, //cmos SCCB_SDA输入
- output cam_sda_o, //cmos SCCB_SDA输出
- output cam_sda_t, //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 //有效数据
- );
-
- //parameter define
- parameter SLAVE_ADDR = 7'h3c; //OV5640的器件地址7'h3c
- parameter BIT_CTRL = 1'b1; //OV5640的字节地址为16位 0:8位 1:16位
- parameter CLK_FREQ = 27'd50_000_000; //i2c_dri模块的驱动时钟频率
- parameter I2C_FREQ = 18'd250_000; //I2C的SCL时钟频率,不超过400KHz
- //wire difine
- wire i2c_exec; //I2C触发执行信号
- wire [23:0] i2c_data; //I2C要配置的地址与数据(高8位地址,低8位数据)
- wire i2c_done; //I2C寄存器配置完成信号
- wire i2c_dri_clk; //I2C操作时钟
- wire [ 7:0] i2c_data_r; //I2C读出的数据
- wire i2c_rh_wl; //I2C读写控制信号
- //*****************************************************
- //** main code
- //*****************************************************
- //电源休眠模式选择 0:正常模式 1:电源休眠模式
- assign cam_pwdn = 1'b0;
- assign cam_rst_n = 1'b1;
- //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_i (cam_sda_i),
- .sda_o (cam_sda_o),
- .sda_t (cam_sda_t),
- .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) //有效数据
- );
- endmodule
i2c_ov5640_rgb565_cfg.
- `timescale 1ns / 1ps
- //ov5640通过IIC配置的寄存器
-
-
- 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触发执行信号,上电等待20ms将信号拉高,表示开始配置寄存器,配置时也一直为高
- output reg [23:0] i2c_data, //I2C要配置的地址与数据(高16位地址,低8位数据)
- output reg i2c_rh_wl, //I2C读写控制信号
- output reg init_done //初始化完成信号,将所有寄存器配置完成后信号拉高
- );
-
- //parameter define
- localparam REG_NUM = 8'd250; //总共需要配置的寄存器个数
- //reg define
- reg [14:0] start_init_cnt; //等待延时计数器
- reg [ 7:0] init_reg_cnt; //寄存器配置个数计数器
- //*****************************************************
- //** main code
- //*****************************************************
- //clk时钟配置成1Mhz,周期为20000*1000ns = 20ms
- //OV5640上电到开始配置IIC至少等待20ms
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) start_init_cnt <= 15'b0;
- else if (start_init_cnt < 15'd20000) begin
- start_init_cnt <= start_init_cnt + 1'b1;
- end
- end
-
- //寄存器配置个数计数
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) init_reg_cnt <= 8'd0;
- else if (i2c_exec) init_reg_cnt <= init_reg_cnt + 8'b1;
- end
-
- //i2c触发执行信号
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) i2c_exec <= 1'b0;
- else if (start_init_cnt == 15'd19999) i2c_exec <= 1'b1;
- else if (i2c_done && (init_reg_cnt < REG_NUM)) i2c_exec <= 1'b1;
- else i2c_exec <= 1'b0;
- end
- //配置I2C读写控制信号
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) i2c_rh_wl <= 1'b1;
- else if (init_reg_cnt == 8'd2) i2c_rh_wl <= 1'b0;
- end
-
- //初始化完成信号
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) init_done <= 1'b0;
- else if ((init_reg_cnt == REG_NUM) && i2c_done) init_done <= 1'b1;
- end
-
- //配置寄存器地址与数据
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) i2c_data <= 24'b0;
- else begin
- case (init_reg_cnt)
- //先对寄存器进行软件复位,使寄存器恢复初始值
- //寄存器软件复位后,需要延时1ms才能配置其它寄存器
- 8'd0: i2c_data <= {16'h300a, 8'h0}; //
- 8'd1: i2c_data <= {16'h300b, 8'h0}; //
- 8'd2: i2c_data <= {16'h3008, 8'h82}; //Bit[7]:复位 Bit[6]:电源休眠
- 8'd3: i2c_data <= {16'h3008, 8'h02}; //正常工作模式
- 8'd4: i2c_data <= {16'h3103, 8'h02}; //Bit[1]:1 PLL Clock
- //引脚输入/输出控制 FREX/VSYNC/HREF/PCLK/D[9:6]
- 8'd5: i2c_data <= {8'h30, 8'h17, 8'hff};
- //引脚输入/输出控制 D[5:0]/GPIO1/GPIO0
- 8'd6: i2c_data <= {16'h3018, 8'hff};
- 8'd7: i2c_data <= {16'h3037, 8'h13}; //PLL分频控制
- 8'd8: i2c_data <= {16'h3108, 8'h01}; //系统根分频器
- 8'd9: i2c_data <= {16'h3630, 8'h36};
- 8'd10: i2c_data <= {16'h3631, 8'h0e};
- 8'd11: i2c_data <= {16'h3632, 8'he2};
- 8'd12: i2c_data <= {16'h3633, 8'h12};
- 8'd13: i2c_data <= {16'h3621, 8'he0};
- 8'd14: i2c_data <= {16'h3704, 8'ha0};
- 8'd15: i2c_data <= {16'h3703, 8'h5a};
- 8'd16: i2c_data <= {16'h3715, 8'h78};
- 8'd17: i2c_data <= {16'h3717, 8'h01};
- 8'd18: i2c_data <= {16'h370b, 8'h60};
- 8'd19: i2c_data <= {16'h3705, 8'h1a};
- 8'd20: i2c_data <= {16'h3905, 8'h02};
- 8'd21: i2c_data <= {16'h3906, 8'h10};
- 8'd22: i2c_data <= {16'h3901, 8'h0a};
- 8'd23: i2c_data <= {16'h3731, 8'h12};
- 8'd24: i2c_data <= {16'h3600, 8'h08}; //VCM控制,用于自动聚焦
- 8'd25: i2c_data <= {16'h3601, 8'h33}; //VCM控制,用于自动聚焦
- 8'd26: i2c_data <= {16'h302d, 8'h60}; //系统控制
- 8'd27: i2c_data <= {16'h3620, 8'h52};
- 8'd28: i2c_data <= {16'h371b, 8'h20};
- 8'd29: i2c_data <= {16'h471c, 8'h50};
- 8'd30: i2c_data <= {16'h3a13, 8'h43}; //AEC(自动曝光控制)
- 8'd31: i2c_data <= {16'h3a18, 8'h00}; //AEC 增益上限
- 8'd32: i2c_data <= {16'h3a19, 8'hf8}; //AEC 增益上限
- 8'd33: i2c_data <= {16'h3635, 8'h13};
- 8'd34: i2c_data <= {16'h3636, 8'h03};
- 8'd35: i2c_data <= {16'h3634, 8'h40};
- 8'd36: i2c_data <= {16'h3622, 8'h01};
- 8'd37: i2c_data <= {16'h3c01, 8'h34};
- 8'd38: i2c_data <= {16'h3c04, 8'h28};
- 8'd39: i2c_data <= {16'h3c05, 8'h98};
- 8'd40: i2c_data <= {16'h3c06, 8'h00}; //light meter 1 阈值[15:8]
- 8'd41: i2c_data <= {16'h3c07, 8'h08}; //light meter 1 阈值[7:0]
- 8'd42: i2c_data <= {16'h3c08, 8'h00}; //light meter 2 阈值[15:8]
- 8'd43: i2c_data <= {16'h3c09, 8'h1c}; //light meter 2 阈值[7:0]
- 8'd44: i2c_data <= {16'h3c0a, 8'h9c}; //sample number[15:8]
- 8'd45: i2c_data <= {16'h3c0b, 8'h40}; //sample number[7:0]
- 8'd46: i2c_data <= {16'h3810, 8'h00}; //Timing Hoffset[11:8]
- 8'd47: i2c_data <= {16'h3811, 8'h10}; //Timing Hoffset[7:0]
- 8'd48: i2c_data <= {16'h3812, 8'h00}; //Timing Voffset[10:8]
- 8'd49: i2c_data <= {16'h3708, 8'h64};
- 8'd50: i2c_data <= {16'h4001, 8'h02}; //BLC(黑电平校准)补偿起始行号
- 8'd51: i2c_data <= {16'h4005, 8'h1a}; //BLC(黑电平校准)补偿始终更新
- 8'd52: i2c_data <= {16'h3000, 8'h00}; //系统块复位控制
- 8'd53: i2c_data <= {16'h3004, 8'hff}; //时钟使能控制
- 8'd54: i2c_data <= {16'h4300, 8'h61}; //格式控制 RGB565
- 8'd55: i2c_data <= {16'h501f, 8'h01}; //ISP RGB
- 8'd56: i2c_data <= {16'h440e, 8'h00};
- 8'd57: i2c_data <= {16'h5000, 8'ha7}; //ISP控制
- 8'd58: i2c_data <= {16'h3a0f, 8'h30}; //AEC控制;stable range in high
- 8'd59: i2c_data <= {16'h3a10, 8'h28}; //AEC控制;stable range in low
- 8'd60: i2c_data <= {16'h3a1b, 8'h30}; //AEC控制;stable range out high
- 8'd61: i2c_data <= {16'h3a1e, 8'h26}; //AEC控制;stable range out low
- 8'd62: i2c_data <= {16'h3a11, 8'h60}; //AEC控制; fast zone high
- 8'd63: i2c_data <= {16'h3a1f, 8'h14}; //AEC控制; fast zone low
- //LENC(镜头校正)控制 16'h5800~16'h583d
- 8'd64: i2c_data <= {16'h5800, 8'h23};
- 8'd65: i2c_data <= {16'h5801, 8'h14};
- 8'd66: i2c_data <= {16'h5802, 8'h0f};
- 8'd67: i2c_data <= {16'h5803, 8'h0f};
- 8'd68: i2c_data <= {16'h5804, 8'h12};
- 8'd69: i2c_data <= {16'h5805, 8'h26};
- 8'd70: i2c_data <= {16'h5806, 8'h0c};
- 8'd71: i2c_data <= {16'h5807, 8'h08};
- 8'd72: i2c_data <= {16'h5808, 8'h05};
- 8'd73: i2c_data <= {16'h5809, 8'h05};
- 8'd74: i2c_data <= {16'h580a, 8'h08};
- 8'd75: i2c_data <= {16'h580b, 8'h0d};
- 8'd76: i2c_data <= {16'h580c, 8'h08};
- 8'd77: i2c_data <= {16'h580d, 8'h03};
- 8'd78: i2c_data <= {16'h580e, 8'h00};
- 8'd79: i2c_data <= {16'h580f, 8'h00};
- 8'd80: i2c_data <= {16'h5810, 8'h03};
- 8'd81: i2c_data <= {16'h5811, 8'h09};
- 8'd82: i2c_data <= {16'h5812, 8'h07};
- 8'd83: i2c_data <= {16'h5813, 8'h03};
- 8'd84: i2c_data <= {16'h5814, 8'h00};
- 8'd85: i2c_data <= {16'h5815, 8'h01};
- 8'd86: i2c_data <= {16'h5816, 8'h03};
- 8'd87: i2c_data <= {16'h5817, 8'h08};
- 8'd88: i2c_data <= {16'h5818, 8'h0d};
- 8'd89: i2c_data <= {16'h5819, 8'h08};
- 8'd90: i2c_data <= {16'h581a, 8'h05};
- 8'd91: i2c_data <= {16'h581b, 8'h06};
- 8'd92: i2c_data <= {16'h581c, 8'h08};
- 8'd93: i2c_data <= {16'h581d, 8'h0e};
- 8'd94: i2c_data <= {16'h581e, 8'h29};
- 8'd95: i2c_data <= {16'h581f, 8'h17};
- 8'd96: i2c_data <= {16'h5820, 8'h11};
- 8'd97: i2c_data <= {16'h5821, 8'h11};
- 8'd98: i2c_data <= {16'h5822, 8'h15};
- 8'd99: i2c_data <= {16'h5823, 8'h28};
- 8'd100: i2c_data <= {16'h5824, 8'h46};
- 8'd101: i2c_data <= {16'h5825, 8'h26};
- 8'd102: i2c_data <= {16'h5826, 8'h08};
- 8'd103: i2c_data <= {16'h5827, 8'h26};
- 8'd104: i2c_data <= {16'h5828, 8'h64};
- 8'd105: i2c_data <= {16'h5829, 8'h26};
- 8'd106: i2c_data <= {16'h582a, 8'h24};
- 8'd107: i2c_data <= {16'h582b, 8'h22};
- 8'd108: i2c_data <= {16'h582c, 8'h24};
- 8'd109: i2c_data <= {16'h582d, 8'h24};
- 8'd110: i2c_data <= {16'h582e, 8'h06};
- 8'd111: i2c_data <= {16'h582f, 8'h22};
- 8'd112: i2c_data <= {16'h5830, 8'h40};
- 8'd113: i2c_data <= {16'h5831, 8'h42};
- 8'd114: i2c_data <= {16'h5832, 8'h24};
- 8'd115: i2c_data <= {16'h5833, 8'h26};
- 8'd116: i2c_data <= {16'h5834, 8'h24};
- 8'd117: i2c_data <= {16'h5835, 8'h22};
- 8'd118: i2c_data <= {16'h5836, 8'h22};
- 8'd119: i2c_data <= {16'h5837, 8'h26};
- 8'd120: i2c_data <= {16'h5838, 8'h44};
- 8'd121: i2c_data <= {16'h5839, 8'h24};
- 8'd122: i2c_data <= {16'h583a, 8'h26};
- 8'd123: i2c_data <= {16'h583b, 8'h28};
- 8'd124: i2c_data <= {16'h583c, 8'h42};
- 8'd125: i2c_data <= {16'h583d, 8'hce};
- //AWB(自动白平衡控制) 16'h5180~16'h519e
- 8'd126: i2c_data <= {16'h5180, 8'hff};
- 8'd127: i2c_data <= {16'h5181, 8'hf2};
- 8'd128: i2c_data <= {16'h5182, 8'h00};
- 8'd129: i2c_data <= {16'h5183, 8'h14};
- 8'd130: i2c_data <= {16'h5184, 8'h25};
- 8'd131: i2c_data <= {16'h5185, 8'h24};
- 8'd132: i2c_data <= {16'h5186, 8'h09};
- 8'd133: i2c_data <= {16'h5187, 8'h09};
- 8'd134: i2c_data <= {16'h5188, 8'h09};
- 8'd135: i2c_data <= {16'h5189, 8'h75};
- 8'd136: i2c_data <= {16'h518a, 8'h54};
- 8'd137: i2c_data <= {16'h518b, 8'he0};
- 8'd138: i2c_data <= {16'h518c, 8'hb2};
- 8'd139: i2c_data <= {16'h518d, 8'h42};
- 8'd140: i2c_data <= {16'h518e, 8'h3d};
- 8'd141: i2c_data <= {16'h518f, 8'h56};
- 8'd142: i2c_data <= {16'h5190, 8'h46};
- 8'd143: i2c_data <= {16'h5191, 8'hf8};
- 8'd144: i2c_data <= {16'h5192, 8'h04};
- 8'd145: i2c_data <= {16'h5193, 8'h70};
- 8'd146: i2c_data <= {16'h5194, 8'hf0};
- 8'd147: i2c_data <= {16'h5195, 8'hf0};
- 8'd148: i2c_data <= {16'h5196, 8'h03};
- 8'd149: i2c_data <= {16'h5197, 8'h01};
- 8'd150: i2c_data <= {16'h5198, 8'h04};
- 8'd151: i2c_data <= {16'h5199, 8'h12};
- 8'd152: i2c_data <= {16'h519a, 8'h04};
- 8'd153: i2c_data <= {16'h519b, 8'h00};
- 8'd154: i2c_data <= {16'h519c, 8'h06};
- 8'd155: i2c_data <= {16'h519d, 8'h82};
- 8'd156: i2c_data <= {16'h519e, 8'h38};
- //Gamma(伽马)控制 16'h5480~16'h5490
- 8'd157: i2c_data <= {16'h5480, 8'h01};
- 8'd158: i2c_data <= {16'h5481, 8'h08};
- 8'd159: i2c_data <= {16'h5482, 8'h14};
- 8'd160: i2c_data <= {16'h5483, 8'h28};
- 8'd161: i2c_data <= {16'h5484, 8'h51};
- 8'd162: i2c_data <= {16'h5485, 8'h65};
- 8'd163: i2c_data <= {16'h5486, 8'h71};
- 8'd164: i2c_data <= {16'h5487, 8'h7d};
- 8'd165: i2c_data <= {16'h5488, 8'h87};
- 8'd166: i2c_data <= {16'h5489, 8'h91};
- 8'd167: i2c_data <= {16'h548a, 8'h9a};
- 8'd168: i2c_data <= {16'h548b, 8'haa};
- 8'd169: i2c_data <= {16'h548c, 8'hb8};
- 8'd170: i2c_data <= {16'h548d, 8'hcd};
- 8'd171: i2c_data <= {16'h548e, 8'hdd};
- 8'd172: i2c_data <= {16'h548f, 8'hea};
- 8'd173: i2c_data <= {16'h5490, 8'h1d};
- //CMX(彩色矩阵控制) 16'h5381~16'h538b
- 8'd174: i2c_data <= {16'h5381, 8'h1e};
- 8'd175: i2c_data <= {16'h5382, 8'h5b};
- 8'd176: i2c_data <= {16'h5383, 8'h08};
- 8'd177: i2c_data <= {16'h5384, 8'h0a};
- 8'd178: i2c_data <= {16'h5385, 8'h7e};
- 8'd179: i2c_data <= {16'h5386, 8'h88};
- 8'd180: i2c_data <= {16'h5387, 8'h7c};
- 8'd181: i2c_data <= {16'h5388, 8'h6c};
- 8'd182: i2c_data <= {16'h5389, 8'h10};
- 8'd183: i2c_data <= {16'h538a, 8'h01};
- 8'd184: i2c_data <= {16'h538b, 8'h98};
- //SDE(特殊数码效果)控制 16'h5580~16'h558b
- 8'd185: i2c_data <= {16'h5580, 8'h06};
- 8'd186: i2c_data <= {16'h5583, 8'h40};
- 8'd187: i2c_data <= {16'h5584, 8'h10};
- 8'd188: i2c_data <= {16'h5589, 8'h10};
- 8'd189: i2c_data <= {16'h558a, 8'h00};
- 8'd190: i2c_data <= {16'h558b, 8'hf8};
- 8'd191: i2c_data <= {16'h501d, 8'h40}; //ISP MISC
- //CIP(颜色插值)控制 (16'h5300~16'h530c)
- 8'd192: i2c_data <= {16'h5300, 8'h08};
- 8'd193: i2c_data <= {16'h5301, 8'h30};
- 8'd194: i2c_data <= {16'h5302, 8'h10};
- 8'd195: i2c_data <= {16'h5303, 8'h00};
- 8'd196: i2c_data <= {16'h5304, 8'h08};
- 8'd197: i2c_data <= {16'h5305, 8'h30};
- 8'd198: i2c_data <= {16'h5306, 8'h08};
- 8'd199: i2c_data <= {16'h5307, 8'h16};
- 8'd200: i2c_data <= {16'h5309, 8'h08};
- 8'd201: i2c_data <= {16'h530a, 8'h30};
- 8'd202: i2c_data <= {16'h530b, 8'h04};
- 8'd203: i2c_data <= {16'h530c, 8'h06};
- 8'd204: i2c_data <= {16'h5025, 8'h00};
- //系统时钟分频 Bit[7:4]:系统时钟分频 input clock =24Mhz, PCLK = 48Mhz
- 8'd205: i2c_data <= {16'h3035, 8'h11};
- 8'd206: i2c_data <= {16'h3036, 8'h3c}; //PLL倍频
- 8'd207: i2c_data <= {16'h3c07, 8'h08};
- //时序控制 16'h3800~16'h3821
- 8'd208: i2c_data <= {16'h3820, 8'h46};
- 8'd209: i2c_data <= {16'h3821, 8'h01};
- 8'd210: i2c_data <= {16'h3814, 8'h31};
- 8'd211: i2c_data <= {16'h3815, 8'h31};
- 8'd212: i2c_data <= {16'h3800, 8'h00};
- 8'd213: i2c_data <= {16'h3801, 8'h00};
- 8'd214: i2c_data <= {16'h3802, 8'h00};
- 8'd215: i2c_data <= {16'h3803, 8'h04};
- 8'd216: i2c_data <= {16'h3804, 8'h0a};
- 8'd217: i2c_data <= {16'h3805, 8'h3f};
- 8'd218: i2c_data <= {16'h3806, 8'h07};
- 8'd219: i2c_data <= {16'h3807, 8'h9b};
- //设置输出像素个数
- //DVP 输出水平像素点数高4位
- 8'd220: i2c_data <= {16'h3808, {4'd0, cmos_h_pixel[11:8]}};
- //DVP 输出水平像素点数低8位
- 8'd221: i2c_data <= {16'h3809, cmos_h_pixel[7:0]};
- //DVP 输出垂直像素点数高3位
- 8'd222: i2c_data <= {16'h380a, {5'd0, cmos_v_pixel[10:8]}};
- //DVP 输出垂直像素点数低8位
- 8'd223: i2c_data <= {16'h380b, cmos_v_pixel[7:0]};
- //水平总像素大小高5位
- 8'd224: i2c_data <= {16'h380c, {3'd0, total_h_pixel[12:8]}};
- //水平总像素大小低8位
- 8'd225: i2c_data <= {16'h380d, total_h_pixel[7:0]};
- //垂直总像素大小高5位
- 8'd226: i2c_data <= {16'h380e, {3'd0, total_v_pixel[12:8]}};
- //垂直总像素大小低8位
- 8'd227: i2c_data <= {16'h380f, total_v_pixel[7:0]};
- 8'd228: i2c_data <= {16'h3813, 8'h06};
- 8'd229: i2c_data <= {16'h3618, 8'h00};
- 8'd230: i2c_data <= {16'h3612, 8'h29};
- 8'd231: i2c_data <= {16'h3709, 8'h52};
- 8'd232: i2c_data <= {16'h370c, 8'h03};
- 8'd233: i2c_data <= {16'h3a02, 8'h17}; //60Hz max exposure
- 8'd234: i2c_data <= {16'h3a03, 8'h10}; //60Hz max exposure
- 8'd235: i2c_data <= {16'h3a14, 8'h17}; //50Hz max exposure
- 8'd236: i2c_data <= {16'h3a15, 8'h10}; //50Hz max exposure
- 8'd237: i2c_data <= {16'h4004, 8'h02}; //BLC(背光) 2 lines
- 8'd238: i2c_data <= {16'h4713, 8'h03}; //JPEG mode 3
- 8'd239: i2c_data <= {16'h4407, 8'h04}; //量化标度
- 8'd240: i2c_data <= {16'h460c, 8'h22};
- 8'd241: i2c_data <= {16'h4837, 8'h22}; //DVP CLK divider
- 8'd242: i2c_data <= {16'h3824, 8'h02}; //DVP CLK divider
- 8'd243: i2c_data <= {16'h5001, 8'ha3}; //ISP 控制
- 8'd244: i2c_data <= {16'h3b07, 8'h0a}; //帧曝光模式
- //彩条测试使能
- 8'd245: i2c_data <= {16'h503d, 8'h00}; //8'h00:正常模式 8'h80:彩条显示
- //测试闪光灯功能
- 8'd246: i2c_data <= {16'h3016, 8'h02};
- 8'd247: i2c_data <= {16'h301c, 8'h02};
- 8'd248: i2c_data <= {16'h3019, 8'h02}; //打开闪光灯
- 8'd249: i2c_data <= {16'h3019, 8'h00}; //关闭闪光灯
- //只读存储器,防止在case中没有列举的情况,之前的寄存器被重复改写
- default: i2c_data <= {16'h300a, 8'h00}; //器件ID高8位
- endcase
- end
- end
-
- endmodule
i2c_dri.v
- `timescale 1ns / 1ps
- //IIC驱动
-
-
- module i2c_dri #(
- parameter SLAVE_ADDR = 7'h3c, //器件地址
- parameter CLK_FREQ = 26'd50_000_000, //模块输入的时钟频率
- parameter I2C_FREQ = 18'd250_000 //IIC_SCL的时钟频率
- ) (
- input clk, //50m时钟
- input rst_n,
- //i2c interface
- input i2c_exec, //I2C触发执行信号
- input bit_ctrl, //字地址位控制(16b/8b),在此处固定为16位,一直为1
- 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时钟信号
- input sda_i, //SDA输入
- output sda_o, //SDA输出
- output sda_t, //SDA使能
- //user interface
- output reg dri_clk //驱动I2C操作的驱动时钟
- );
- //localparam define
- localparam st_idle = 8'b0000_0001; //空闲状态
- localparam st_sladdr = 8'b0000_0010; //发送器件地址(slave address)
- localparam st_addr16 = 8'b0000_0100; //发送16位字地址
- localparam st_addr8 = 8'b0000_1000; //发送8位字地址
- localparam st_data_wr = 8'b0001_0000; //写数据(8 bit)
- localparam st_addr_rd = 8'b0010_0000; //发送器件地址读
- localparam st_data_rd = 8'b0100_0000; //读数据(8 bit)
- localparam st_stop = 8'b1000_0000; //结束I2C操作
- //reg define
- reg sda_dir; //I2C数据(SDA)方向控制
- reg sda_out; //SDA输出信号
- reg st_done; //状态结束
- reg wr_flag; //写标志
- reg [ 6:0] cnt; //计数
- reg [ 7:0] cur_state; //状态机当前状态
- reg [ 7:0] next_state; //状态机下一状态
- reg [15:0] addr_t; //地址
- reg [ 7:0] data_r; //读取的数据
- reg [ 7:0] data_wr_t; //I2C需写的数据的临时寄存
- reg [ 9:0] clk_cnt; //分频时钟计数
- //wire define
- wire sda_in; //SDA输入信号
- wire [ 8:0] clk_divide; //模块驱动时钟的分频系数
- //*****************************************************
- //** main code
- //*****************************************************
- //SDA控制
- assign sda_o = sda_out;
- assign sda_in = sda_i;
- assign sda_t = sda_dir;
- assign clk_divide = (CLK_FREQ / I2C_FREQ) >> 2'd2; //模块驱动时钟的分频系数
-
- //生成I2C的SCL的四倍频率的驱动时钟用于驱动i2c的操作
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) begin
- dri_clk <= 1'b0;
- clk_cnt <= 10'd0;
- end else if (clk_cnt == clk_divide[8:1] - 1'd1) begin
- clk_cnt <= 10'd0;
- dri_clk <= ~dri_clk;
- end else clk_cnt <= clk_cnt + 1'b1;
- end
- //(三段式状态机)同步时序描述状态转移
- always @(posedge dri_clk or negedge rst_n) begin
- if (!rst_n) cur_state <= st_idle;
- else cur_state <= next_state;
- end
- //组合逻辑判断状态转移条件
- always @(*) begin
- next_state = st_idle;
- case (cur_state)
- st_idle: begin //空闲状态
- if (i2c_exec) begin
- next_state = st_sladdr;
- end else next_state = st_idle;
- end
- st_sladdr: begin
- if (st_done) begin
- if (bit_ctrl) //判断是16位还是8位字地址
- next_state = st_addr16;
- else next_state = st_addr8;
- end else next_state = st_sladdr;
- end
- st_addr16: begin //写16位字地址
- if (st_done) begin
- next_state = st_addr8;
- end else begin
- next_state = st_addr16;
- end
- end
- st_addr8: begin //8位字地址
- if (st_done) begin
- if (wr_flag == 1'b0) //读写判断
- next_state = st_data_wr;
- else next_state = st_addr_rd;
- end else begin
- next_state = st_addr8;
- end
- end
- st_data_wr: begin //写数据(8 bit)
- if (st_done) next_state = st_stop;
- else next_state = st_data_wr;
- end
- st_addr_rd: begin //写地址以进行读数据
- if (st_done) begin
- next_state = st_data_rd;
- end else begin
- next_state = st_addr_rd;
- end
- end
- st_data_rd: begin //读取数据(8 bit)
- if (st_done) next_state = st_stop;
- else next_state = st_data_rd;
- end
- st_stop: begin //结束I2C操作
- if (st_done) next_state = st_idle;
- else next_state = st_stop;
- end
- default: next_state = st_idle;
- endcase
- end
-
- //时序电路描述状态输出
- always @(posedge dri_clk or negedge rst_n) begin
- //复位初始化
- if (!rst_n) begin
- scl <= 1'b1;
- sda_out <= 1'b1;
- sda_dir <= 1'b1;
- i2c_done <= 1'b0;
- i2c_ack <= 1'b0;
- cnt <= 1'b0;
- st_done <= 1'b0;
- data_r <= 1'b0;
- i2c_data_r <= 1'b0;
- wr_flag <= 1'b0;
- addr_t <= 1'b0;
- data_wr_t <= 1'b0;
- end else begin
- st_done <= 1'b0;
- cnt <= cnt + 1'b1;
- case (cur_state)
- st_idle: begin //空闲状态
- scl <= 1'b1;
- sda_out <= 1'b1;
- sda_dir <= 1'b1;
- i2c_done <= 1'b0;
- cnt <= 7'b0;
- if (i2c_exec) begin
- wr_flag <= i2c_rh_wl ;
- addr_t <= i2c_addr ;
- data_wr_t <= i2c_data_w;
- i2c_ack <= 1'b0;
- end
- end
- st_sladdr: begin //写地址(器件地址和字地址)
- case (cnt)
- 7'd1: sda_out <= 1'b0; //开始I2C
- 7'd3: scl <= 1'b0;
- 7'd4: sda_out <= SLAVE_ADDR[6]; //传送器件地址
- 7'd5: scl <= 1'b1;
- 7'd7: scl <= 1'b0;
- 7'd8: sda_out <= SLAVE_ADDR[5];
- 7'd9: scl <= 1'b1;
- 7'd11: scl <= 1'b0;
- 7'd12: sda_out <= SLAVE_ADDR[4];
- 7'd13: scl <= 1'b1;
- 7'd15: scl <= 1'b0;
- 7'd16: sda_out <= SLAVE_ADDR[3];
- 7'd17: scl <= 1'b1;
- 7'd19: scl <= 1'b0;
- 7'd20: sda_out <= SLAVE_ADDR[2];
- 7'd21: scl <= 1'b1;
- 7'd23: scl <= 1'b0;
- 7'd24: sda_out <= SLAVE_ADDR[1];
- 7'd25: scl <= 1'b1;
- 7'd27: scl <= 1'b0;
- 7'd28: sda_out <= SLAVE_ADDR[0];
- 7'd29: scl <= 1'b1;
- 7'd31: scl <= 1'b0;
- 7'd32: sda_out <= 1'b0; //0:写
- 7'd33: scl <= 1'b1;
- 7'd35: scl <= 1'b0;
- 7'd36: begin
- sda_dir <= 1'b0;
- sda_out <= 1'b1;
- end
- 7'd37: scl <= 1'b1;
- 7'd38: begin //从机应答
- st_done <= 1'b1;
- if (sda_in == 1'b1) //高电平表示未应答
- i2c_ack <= 1'b1; //拉高应答标志位
- end
- 7'd39: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- end
- default: ;
- endcase
- end
- st_addr16: begin
- case (cnt)
- 7'd0: begin
- sda_dir <= 1'b1;
- sda_out <= addr_t[15]; //传送字地址
- end
- 7'd1: scl <= 1'b1;
- 7'd3: scl <= 1'b0;
- 7'd4: sda_out <= addr_t[14];
- 7'd5: scl <= 1'b1;
- 7'd7: scl <= 1'b0;
- 7'd8: sda_out <= addr_t[13];
- 7'd9: scl <= 1'b1;
- 7'd11: scl <= 1'b0;
- 7'd12: sda_out <= addr_t[12];
- 7'd13: scl <= 1'b1;
- 7'd15: scl <= 1'b0;
- 7'd16: sda_out <= addr_t[11];
- 7'd17: scl <= 1'b1;
- 7'd19: scl <= 1'b0;
- 7'd20: sda_out <= addr_t[10];
- 7'd21: scl <= 1'b1;
- 7'd23: scl <= 1'b0;
- 7'd24: sda_out <= addr_t[9];
- 7'd25: scl <= 1'b1;
- 7'd27: scl <= 1'b0;
- 7'd28: sda_out <= addr_t[8];
- 7'd29: scl <= 1'b1;
- 7'd31: scl <= 1'b0;
- 7'd32: begin
- sda_dir <= 1'b0;
- sda_out <= 1'b1;
- end
- 7'd33: scl <= 1'b1;
- 7'd34: begin //从机应答
- st_done <= 1'b1;
- if (sda_in == 1'b1) //高电平表示未应答
- i2c_ack <= 1'b1; //拉高应答标志位
- end
- 7'd35: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- end
- default: ;
- endcase
- end
- st_addr8: begin
- case (cnt)
- 7'd0: begin
- sda_dir <= 1'b1;
- sda_out <= addr_t[7]; //字地址
- end
- 7'd1: scl <= 1'b1;
- 7'd3: scl <= 1'b0;
- 7'd4: sda_out <= addr_t[6];
- 7'd5: scl <= 1'b1;
- 7'd7: scl <= 1'b0;
- 7'd8: sda_out <= addr_t[5];
- 7'd9: scl <= 1'b1;
- 7'd11: scl <= 1'b0;
- 7'd12: sda_out <= addr_t[4];
- 7'd13: scl <= 1'b1;
- 7'd15: scl <= 1'b0;
- 7'd16: sda_out <= addr_t[3];
- 7'd17: scl <= 1'b1;
- 7'd19: scl <= 1'b0;
- 7'd20: sda_out <= addr_t[2];
- 7'd21: scl <= 1'b1;
- 7'd23: scl <= 1'b0;
- 7'd24: sda_out <= addr_t[1];
- 7'd25: scl <= 1'b1;
- 7'd27: scl <= 1'b0;
- 7'd28: sda_out <= addr_t[0];
- 7'd29: scl <= 1'b1;
- 7'd31: scl <= 1'b0;
- 7'd32: begin
- sda_dir <= 1'b0;
- sda_out <= 1'b1;
- end
- 7'd33: scl <= 1'b1;
- 7'd34: begin //从机应答
- st_done <= 1'b1;
- if (sda_in == 1'b1) //高电平表示未应答
- i2c_ack <= 1'b1; //拉高应答标志位
- end
- 7'd35: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- end
- default: ;
- endcase
- end
- st_data_wr: begin //写数据(8 bit)
- case (cnt)
- 7'd0: begin
- sda_out <= data_wr_t[7]; //I2C写8位数据
- sda_dir <= 1'b1;
- end
- 7'd1: scl <= 1'b1;
- 7'd3: scl <= 1'b0;
- 7'd4: sda_out <= data_wr_t[6];
- 7'd5: scl <= 1'b1;
- 7'd7: scl <= 1'b0;
- 7'd8: sda_out <= data_wr_t[5];
- 7'd9: scl <= 1'b1;
- 7'd11: scl <= 1'b0;
- 7'd12: sda_out <= data_wr_t[4];
- 7'd13: scl <= 1'b1;
- 7'd15: scl <= 1'b0;
- 7'd16: sda_out <= data_wr_t[3];
- 7'd17: scl <= 1'b1;
- 7'd19: scl <= 1'b0;
- 7'd20: sda_out <= data_wr_t[2];
- 7'd21: scl <= 1'b1;
- 7'd23: scl <= 1'b0;
- 7'd24: sda_out <= data_wr_t[1];
- 7'd25: scl <= 1'b1;
- 7'd27: scl <= 1'b0;
- 7'd28: sda_out <= data_wr_t[0];
- 7'd29: scl <= 1'b1;
- 7'd31: scl <= 1'b0;
- 7'd32: begin
- sda_dir <= 1'b0;
- sda_out <= 1'b1;
- end
- 7'd33: scl <= 1'b1;
- 7'd34: begin //从机应答
- st_done <= 1'b1;
- if (sda_in == 1'b1) //高电平表示未应答
- i2c_ack <= 1'b1; //拉高应答标志位
- end
- 7'd35: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- end
- default: ;
- endcase
- end
- st_addr_rd: begin //写地址以进行读数据
- case (cnt)
- 7'd0: begin
- sda_dir <= 1'b1;
- sda_out <= 1'b1;
- end
- 7'd1: scl <= 1'b1;
- 7'd2: sda_out <= 1'b0; //重新开始
- 7'd3: scl <= 1'b0;
- 7'd4: sda_out <= SLAVE_ADDR[6]; //传送器件地址
- 7'd5: scl <= 1'b1;
- 7'd7: scl <= 1'b0;
- 7'd8: sda_out <= SLAVE_ADDR[5];
- 7'd9: scl <= 1'b1;
- 7'd11: scl <= 1'b0;
- 7'd12: sda_out <= SLAVE_ADDR[4];
- 7'd13: scl <= 1'b1;
- 7'd15: scl <= 1'b0;
- 7'd16: sda_out <= SLAVE_ADDR[3];
- 7'd17: scl <= 1'b1;
- 7'd19: scl <= 1'b0;
- 7'd20: sda_out <= SLAVE_ADDR[2];
- 7'd21: scl <= 1'b1;
- 7'd23: scl <= 1'b0;
- 7'd24: sda_out <= SLAVE_ADDR[1];
- 7'd25: scl <= 1'b1;
- 7'd27: scl <= 1'b0;
- 7'd28: sda_out <= SLAVE_ADDR[0];
- 7'd29: scl <= 1'b1;
- 7'd31: scl <= 1'b0;
- 7'd32: sda_out <= 1'b1; //1:读
- 7'd33: scl <= 1'b1;
- 7'd35: scl <= 1'b0;
- 7'd36: begin
- sda_dir <= 1'b0;
- sda_out <= 1'b1;
- end
- 7'd37: scl <= 1'b1;
- 7'd38: begin //从机应答
- st_done <= 1'b1;
- if (sda_in == 1'b1) //高电平表示未应答
- i2c_ack <= 1'b1; //拉高应答标志位
- end
- 7'd39: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- end
- default: ;
- endcase
- end
- st_data_rd: begin //读取数据(8 bit)
- case (cnt)
- 7'd0: sda_dir <= 1'b0;
- 7'd1: begin
- data_r[7] <= sda_in;
- scl <= 1'b1;
- end
- 7'd3: scl <= 1'b0;
- 7'd5: begin
- data_r[6] <= sda_in;
- scl <= 1'b1;
- end
- 7'd7: scl <= 1'b0;
- 7'd9: begin
- data_r[5] <= sda_in;
- scl <= 1'b1;
- end
- 7'd11: scl <= 1'b0;
- 7'd13: begin
- data_r[4] <= sda_in;
- scl <= 1'b1;
- end
- 7'd15: scl <= 1'b0;
- 7'd17: begin
- data_r[3] <= sda_in;
- scl <= 1'b1;
- end
- 7'd19: scl <= 1'b0;
- 7'd21: begin
- data_r[2] <= sda_in;
- scl <= 1'b1;
- end
- 7'd23: scl <= 1'b0;
- 7'd25: begin
- data_r[1] <= sda_in;
- scl <= 1'b1;
- end
- 7'd27: scl <= 1'b0;
- 7'd29: begin
- data_r[0] <= sda_in;
- scl <= 1'b1;
- end
- 7'd31: scl <= 1'b0;
- 7'd32: begin
- sda_dir <= 1'b1;
- sda_out <= 1'b1;
- end
- 7'd33: scl <= 1'b1;
- 7'd34: st_done <= 1'b1; //非应答
- 7'd35: begin
- scl <= 1'b0;
- cnt <= 1'b0;
- i2c_data_r <= data_r;
- end
- default: ;
- endcase
- end
- st_stop: begin //结束I2C操作
- case (cnt)
- 7'd0: begin
- sda_dir <= 1'b1; //结束I2C
- sda_out <= 1'b0;
- end
- 7'd1: scl <= 1'b1;
- 7'd3: sda_out <= 1'b1;
- 7'd15: st_done <= 1'b1;
- 7'd16: begin
- cnt <= 1'b0;
- i2c_done <= 1'b1; //向上层模块传递I2C结束信号
- end
- default: ;
- endcase
- end
- endcase
- end
- end
-
- endmodule
cmos_capture_data.v
- `timescale 1ns / 1ps
- //摄像头采集模块
-
-
- 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 //有效数据
- );
-
- //寄存器全部配置完成后,先等待10帧数据
- //待寄存器配置生效后再开始采集图像
- parameter WAIT_FRAME = 4'd10; //寄存器数据稳定等待的帧个数
- //reg define
- reg cam_vsync_d0;
- reg cam_vsync_d1;
- reg cam_href_d0;
- reg cam_href_d1;
- reg [ 3:0] cmos_ps_cnt; //等待帧数稳定计数器
- reg [ 7:0] cam_data_d0;
- reg [15:0] cmos_data_t; //用于8位转16位的临时寄存器
- reg byte_flag; //16位RGB数据转换完成的标志信号
- reg byte_flag_d0;
- reg frame_val_flag; //帧有效的标志
- wire pos_vsync; //采输入场同步信号的上升沿
- //*****************************************************
- //** main code
- //*****************************************************
- //采输入场同步信号的上升沿
- assign pos_vsync = (~cam_vsync_d1) & cam_vsync_d0;
- //输出帧有效信号
- assign cmos_frame_vsync = frame_val_flag ? cam_vsync_d1 : 1'b0;
-
- //输出行有效信号
- assign cmos_frame_href = frame_val_flag ? cam_href_d1 : 1'b0;
- //输出数据使能有效信号
- assign cmos_frame_valid = frame_val_flag ? byte_flag_d0 : 1'b0;
-
- //输出数据
- assign cmos_frame_data = frame_val_flag ? cmos_data_t : 1'b0;
- always @(posedge cam_pclk or negedge rst_n) begin
- if (!rst_n) begin
- cam_vsync_d0 <= 1'b0;
- cam_vsync_d1 <= 1'b0;
- cam_href_d0 <= 1'b0;
- cam_href_d1 <= 1'b0;
- end else begin
- cam_vsync_d0 <= cam_vsync;
- cam_vsync_d1 <= cam_vsync_d0;
- cam_href_d0 <= cam_href;
- cam_href_d1 <= cam_href_d0;
- end
- end
- //对帧数进行计数
- always @(posedge cam_pclk or negedge rst_n) begin
- if (!rst_n) cmos_ps_cnt <= 4'd0;
- else if (pos_vsync && (cmos_ps_cnt < WAIT_FRAME)) cmos_ps_cnt <= cmos_ps_cnt + 4'd1;
- end
- //帧有效标志
- always @(posedge cam_pclk or negedge rst_n) begin
- if (!rst_n) frame_val_flag <= 1'b0;
- else if ((cmos_ps_cnt == WAIT_FRAME) && pos_vsync) frame_val_flag <= 1'b1;
- else;
- end
- //8位数据转16位RGB565数据
- always @(posedge cam_pclk or negedge rst_n) begin
- if (!rst_n) begin
- cmos_data_t <= 16'd0;
- cam_data_d0 <= 8'd0;
- byte_flag <= 1'b0;
- end else if (cam_href) begin
- byte_flag <= ~byte_flag;
- cam_data_d0 <= cam_data;
- if (byte_flag) cmos_data_t <= {cam_data_d0, cam_data};
-
- else;
- end else begin
- byte_flag <= 1'b0;
- cam_data_d0 <= 8'b0;
- cmos_data_t <= 16'd0;
- end
- end
- //产生输出数据有效信号(cmos_frame_valid)
- always @(posedge cam_pclk or negedge rst_n) begin
- if (!rst_n) byte_flag_d0 <= 1'b0;
- else byte_flag_d0 <= byte_flag;
- end
-
- endmodule
lcd_rgb_top.v
- `timescale 1ns / 1ps
- //LCD顶层模块
-
-
- module lcd_rgb_top (
- input sys_clk, //系统时钟
- input sys_rst_n, //复位信号
- input sys_init_done,
-
- //lcd接口
- output lcd_clk, //LCD驱动时钟
- output lcd_hs, //LCD 行同步信号
- output lcd_vs, //LCD 场同步信号
- output lcd_de, //LCD 数据输入使能
- output [23:0] lcd_rgb, //LCD RGB颜色数据
- output lcd_bl, //LCD 背光控制信号
- output lcd_rst, //LCD 复位信号
- output lcd_pclk, //LCD 采样时钟
-
- output out_vsync, //lcd场信号
- output [10:0] pixel_xpos, //像素点横坐标
- output [10:0] pixel_ypos, //像素点纵坐标
- output [10:0] h_disp, //LCD屏水平分辨率
- output [10:0] v_disp, //LCD屏垂直分辨率
- input [15:0] data_in, //数据输入
- output data_req //请求数据输入
-
- );
-
- //wire define
- wire [15:0] lcd_rgb_565; //输出的16位lcd数据
-
-
- //*****************************************************
- //** main code
- //*****************************************************
- //将摄像头16bit数据转换为24bit的lcd数据
- assign lcd_rgb = {lcd_rgb_565[15:11], 3'b000, lcd_rgb_565[10:5], 2'b00, lcd_rgb_565[4:0], 3'b000};
- //时钟分频模块
- clk_div u_clk_div (
- .clk (sys_clk),
- .rst_n(sys_rst_n),
- .lcd_pclk(lcd_clk)
- );
- //lcd驱动模块
- lcd_driver u_lcd_driver (
- .lcd_clk (lcd_clk),
- .sys_rst_n(sys_rst_n & sys_init_done),
- .lcd_hs (lcd_hs),
- .lcd_vs (lcd_vs),
- .lcd_de (lcd_de),
- .lcd_rgb (lcd_rgb_565),
- .lcd_bl (lcd_bl),
- .lcd_rst (lcd_rst),
- .lcd_pclk(lcd_pclk),
- .pixel_data(data_in),
- .data_req (data_req),
- .out_vsync (out_vsync),
- .h_disp (h_disp),
- .v_disp (v_disp),
- .pixel_xpos(pixel_xpos),
- .pixel_ypos(pixel_ypos)
- );
- endmodule
clk_div.v
- `timescale 1ns / 1ps
- //时钟分频模块
-
-
- module clk_div (
- input clk, //50Mhz
- input rst_n,
-
- output reg lcd_pclk
- );
-
- reg clk_25m;
-
-
- //时钟2分频 输出25MHz时钟
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) clk_25m <= 1'b0;
- else clk_25m <= ~clk_25m;
- end
- always @(*) begin
- lcd_pclk = clk_25m;
- end
- endmodule
lcd_driver.v
- `timescale 1ns / 1ps
-
-
- module lcd_driver (
- input lcd_clk, //lcd模块驱动时钟
- input sys_rst_n, //复位信号
-
- input [15:0] pixel_data, //像素点数据
- output data_req, //请求像素点颜色数据输入
- output [10:0] pixel_xpos, //像素点横坐标
- output [10:0] pixel_ypos, //像素点纵坐标
- output [10:0] h_disp, //LCD屏水平分辨率
- output [10:0] v_disp, //LCD屏垂直分辨率
- output out_vsync, //帧复位,高有效
- //RGB LCD接口
- output lcd_hs, //LCD 行同步信号
- output lcd_vs, //LCD 场同步信号
- output lcd_de, //LCD 数据输入使能
- output [15:0] lcd_rgb, //LCD RGB565颜色数据
- output lcd_bl, //LCD 背光控制信号
- output lcd_rst, //LCD 复位信号
- output lcd_pclk //LCD 采样时钟
- );
-
- //parameter define
-
-
- // 7' 800*480
- parameter H_SYNC_7084 = 11'd128; //行同步
- parameter H_BACK_7084 = 11'd88; //行显示后沿
- parameter H_DISP_7084 = 11'd800; //行有效数据
- parameter H_FRONT_7084 = 11'd40; //行显示前沿
- parameter H_TOTAL_7084 = 11'd1056; //行扫描周期
-
- parameter V_SYNC_7084 = 11'd2; //场同步
- parameter V_BACK_7084 = 11'd33; //场显示后沿
- parameter V_DISP_7084 = 11'd480; //场有效数据
- parameter V_FRONT_7084 = 11'd10; //场显示前沿
- parameter V_TOTAL_7084 = 11'd525; //场扫描周期
- //reg define
- reg [10:0] h_sync;
- reg [10:0] h_back;
- reg [10:0] h_total;
- reg [10:0] v_sync;
- reg [10:0] v_back;
- reg [10:0] v_total;
- reg [10:0] h_cnt;
- reg [10:0] v_cnt;
- reg [10:0] h_disp; //LCD屏水平分辨率
- reg [10:0] v_disp; //LCD屏垂直分辨率
- reg lcd_de; //LCD 数据输入使能
- reg [15:0] lcd_rgb; //LCD RGB565颜色数据
- //wire define
- wire lcd_en;
- wire out_vsync;
- //*****************************************************
- //** main code
- //*****************************************************
- assign lcd_bl = 1'b1; //RGB LCD显示模块背光控制信号
- assign lcd_rst = 1'b1; //RGB LCD显示模块系统复位信号
- assign lcd_pclk = lcd_clk; //RGB LCD显示模块采样时钟
- //RGB LCD 采用数据输入使能信号同步时,行场同步信号需要拉高
- assign lcd_hs = 1'b1;
- assign lcd_vs = 1'b1;
- //使能RGB565数据输出
- assign lcd_en = ((h_cnt >= h_sync + h_back) && (h_cnt < h_sync + h_back + h_disp)
- && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp))
- ? 1'b1 : 1'b0;
- //帧复位,高有效
- assign out_vsync = ((h_cnt <= 100) && (v_cnt == 1)) ? 1'b1 : 1'b0;
- //请求像素点颜色数据输入
- assign data_req = ((h_cnt >= h_sync + h_back - 1'b1) && (h_cnt < h_sync + h_back + h_disp - 1'b1)
- && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp))
- ? 1'b1 : 1'b0;
- //像素点坐标
- assign pixel_xpos = data_req ? (h_cnt - (h_sync + h_back - 1'b1)) : 11'd0;
- assign pixel_ypos = data_req ? (v_cnt - (v_sync + v_back - 1'b1)) : 11'd0;
- //LCD输入的颜色数据采用数据输入使能信号同步
- always @(posedge lcd_clk or negedge sys_rst_n) begin
- if (!sys_rst_n) lcd_de <= 11'd0;
- else begin
- lcd_de <= lcd_en;
- end
- end
-
- //RGB565数据输出
- always @(posedge lcd_clk or negedge sys_rst_n) begin
- if (!sys_rst_n) lcd_rgb <= 16'd0;
- else begin
- if (lcd_en) lcd_rgb <= pixel_data;
- else lcd_rgb <= 16'd0;
- end
- end
-
- //行场时序参数
- always @(*) begin
- h_sync = H_SYNC_7084;
- h_back = H_BACK_7084;
- h_disp = H_DISP_7084;
- h_total = H_TOTAL_7084;
- v_sync = V_SYNC_7084;
- v_back = V_BACK_7084;
- v_disp = V_DISP_7084;
- v_total = V_TOTAL_7084;
- end
-
- //行计数器对像素时钟计数
- always @(posedge lcd_pclk or negedge sys_rst_n) begin
- if (!sys_rst_n) h_cnt <= 11'd0;
- else begin
- if (h_cnt == h_total - 1'b1) h_cnt <= 11'd0;
- else h_cnt <= h_cnt + 1'b1;
- end
- end
-
- //场计数器对行计数
- always @(posedge lcd_clk or negedge sys_rst_n) begin
- if (!sys_rst_n) v_cnt <= 11'd0;
- else begin
- if (h_cnt == h_total - 1'b1) begin
- if (v_cnt == v_total - 1'b1) v_cnt <= 11'd0;
- else v_cnt <= v_cnt + 1'b1;
- end
- end
- end
- endmodule
- #IO管脚约束
- #时钟周期约束
- #create_clock -name sys_clk_p -period 10.000 [get_ports sys_clk_p]
- #时钟
- set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_p]
- set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_n]
- set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]
- set_property PACKAGE_PIN AF5 [get_ports sys_clk_n]
- #复位
- set_property -dict {PACKAGE_PIN AH11 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
-
- #RGB LCD
- set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[0]}]
- set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[1]}]
- set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[2]}]
- set_property -dict {PACKAGE_PIN Y13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[3]}]
- set_property -dict {PACKAGE_PIN W12 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[4]}]
- set_property -dict {PACKAGE_PIN Y12 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[5]}]
- set_property -dict {PACKAGE_PIN W11 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[6]}]
- set_property -dict {PACKAGE_PIN AA12 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[7]}]
- set_property -dict {PACKAGE_PIN AC14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[8]}]
- set_property -dict {PACKAGE_PIN AD15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[9]}]
- set_property -dict {PACKAGE_PIN AC13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[10]}]
- set_property -dict {PACKAGE_PIN AD14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[11]}]
- set_property -dict {PACKAGE_PIN AE15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[12]}]
- set_property -dict {PACKAGE_PIN AA13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[13]}]
- set_property -dict {PACKAGE_PIN AE14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[14]}]
- set_property -dict {PACKAGE_PIN AB13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[15]}]
- set_property -dict {PACKAGE_PIN AG14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[16]}]
- set_property -dict {PACKAGE_PIN AB15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[17]}]
- set_property -dict {PACKAGE_PIN AH14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[18]}]
- set_property -dict {PACKAGE_PIN AB14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[19]}]
- set_property -dict {PACKAGE_PIN AG13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[20]}]
- set_property -dict {PACKAGE_PIN AE13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[21]}]
- set_property -dict {PACKAGE_PIN AH13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[22]}]
- set_property -dict {PACKAGE_PIN AF13 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[23]}]
-
- set_property -dict {PACKAGE_PIN J11 IOSTANDARD LVCMOS33} [get_ports lcd_hs]
- set_property -dict {PACKAGE_PIN K12 IOSTANDARD LVCMOS33} [get_ports lcd_vs]
- set_property -dict {PACKAGE_PIN J10 IOSTANDARD LVCMOS33} [get_ports lcd_de]
- set_property -dict {PACKAGE_PIN J12 IOSTANDARD LVCMOS33} [get_ports lcd_bl]
- set_property -dict {PACKAGE_PIN K13 IOSTANDARD LVCMOS33} [get_ports lcd_pclk]
- set_property -dict {PACKAGE_PIN F10 IOSTANDARD LVCMOS33} [get_ports lcd_rst]
-
- #CAMERA
-
- #摄像头接口的时钟
- create_clock -period 40.000 -name cmos_pclk [get_ports cam_pclk]
- set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_IBUF]
-
- #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_IBUF_inst/O]
-
- set_property -dict {PACKAGE_PIN C13 IOSTANDARD LVCMOS33} [get_ports cam_pclk]
- set_property -dict {PACKAGE_PIN F13 IOSTANDARD LVCMOS33} [get_ports cam_rst_n]
- set_property -dict {PACKAGE_PIN B15 IOSTANDARD LVCMOS33} [get_ports cam_pwdn]
- set_property -dict {PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports {cam_data[0]}]
- set_property -dict {PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports {cam_data[1]}]
- set_property -dict {PACKAGE_PIN E14 IOSTANDARD LVCMOS33 } [get_ports {cam_data[2]}]
- set_property -dict {PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports {cam_data[3]}]
- set_property -dict {PACKAGE_PIN E13 IOSTANDARD LVCMOS33 } [get_ports {cam_data[4]}]
- set_property -dict {PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports {cam_data[5]}]
- set_property -dict {PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports {cam_data[6]}]
- set_property -dict {PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports {cam_data[7]}]
-
-
-
- set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33} [get_ports cam_vsync]
- set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports cam_href]
- set_property -dict {PACKAGE_PIN H13 IOSTANDARD LVCMOS33} [get_ports cam_scl]
- set_property -dict {PACKAGE_PIN F15 IOSTANDARD LVCMOS33} [get_ports cam_sda]
- set_property PULLUP true [get_ports cam_scl]
- set_property PULLUP true [get_ports cam_sda]
- #DDR4
- set_property PACKAGE_PIN AH4 [get_ports {c0_ddr4_odt[0]}]
- set_property PACKAGE_PIN AE8 [get_ports {c0_ddr4_bg[0]}]
- set_property PACKAGE_PIN AB5 [get_ports {c0_ddr4_adr[16]}]
- set_property PACKAGE_PIN AB7 [get_ports {c0_ddr4_adr[15]}]
- set_property PACKAGE_PIN AF6 [get_ports {c0_ddr4_adr[14]}]
- set_property PACKAGE_PIN AD9 [get_ports {c0_ddr4_adr[13]}]
- set_property PACKAGE_PIN AC6 [get_ports {c0_ddr4_adr[12]}]
- set_property PACKAGE_PIN AH9 [get_ports {c0_ddr4_adr[11]}]
- set_property PACKAGE_PIN AE7 [get_ports {c0_ddr4_adr[10]}]
- set_property PACKAGE_PIN AC9 [get_ports {c0_ddr4_adr[9]}]
- set_property PACKAGE_PIN AH8 [get_ports {c0_ddr4_adr[8]}]
- set_property PACKAGE_PIN AE9 [get_ports {c0_ddr4_adr[7]}]
- set_property PACKAGE_PIN AH7 [get_ports {c0_ddr4_adr[6]}]
- set_property PACKAGE_PIN AD7 [get_ports {c0_ddr4_adr[5]}]
- set_property PACKAGE_PIN AF7 [get_ports {c0_ddr4_adr[4]}]
- set_property PACKAGE_PIN AC8 [get_ports {c0_ddr4_adr[3]}]
- set_property PACKAGE_PIN AF8 [get_ports {c0_ddr4_adr[2]}]
- set_property PACKAGE_PIN AB8 [get_ports {c0_ddr4_adr[1]}]
- set_property PACKAGE_PIN AG8 [get_ports {c0_ddr4_adr[0]}]
- set_property PACKAGE_PIN AD2 [get_ports {c0_ddr4_dqs_t[1]}]
- set_property PACKAGE_PIN AD1 [get_ports {c0_ddr4_dqs_c[1]}]
- set_property PACKAGE_PIN AE2 [get_ports {c0_ddr4_dqs_t[0]}]
- set_property PACKAGE_PIN AF2 [get_ports {c0_ddr4_dqs_c[0]}]
-
- set_property PACKAGE_PIN AC4 [get_ports {c0_ddr4_dq[15]}]
- set_property PACKAGE_PIN AC3 [get_ports {c0_ddr4_dq[14]}]
- set_property PACKAGE_PIN AB4 [get_ports {c0_ddr4_dq[13]}]
- set_property PACKAGE_PIN AB3 [get_ports {c0_ddr4_dq[12]}]
- set_property PACKAGE_PIN AB2 [get_ports {c0_ddr4_dq[11]}]
- set_property PACKAGE_PIN AC2 [get_ports {c0_ddr4_dq[10]}]
- set_property PACKAGE_PIN AB1 [get_ports {c0_ddr4_dq[9]}]
- set_property PACKAGE_PIN AC1 [get_ports {c0_ddr4_dq[8]}]
- set_property PACKAGE_PIN AG3 [get_ports {c0_ddr4_dq[7]}]
- set_property PACKAGE_PIN AH3 [get_ports {c0_ddr4_dq[6]}]
- set_property PACKAGE_PIN AE3 [get_ports {c0_ddr4_dq[5]}]
- set_property PACKAGE_PIN AF3 [get_ports {c0_ddr4_dq[4]}]
- set_property PACKAGE_PIN AH2 [get_ports {c0_ddr4_dq[3]}]
- set_property PACKAGE_PIN AH1 [get_ports {c0_ddr4_dq[2]}]
- set_property PACKAGE_PIN AF1 [get_ports {c0_ddr4_dq[1]}]
- set_property PACKAGE_PIN AG1 [get_ports {c0_ddr4_dq[0]}]
-
- set_property INTERNAL_VREF 0.6 [get_iobanks 64]
-
- set_property PACKAGE_PIN AB6 [get_ports {c0_ddr4_cs_n[0]}]
- set_property PACKAGE_PIN AG6 [get_ports {c0_ddr4_ck_t[0]}]
- set_property PACKAGE_PIN AG5 [get_ports {c0_ddr4_ck_c[0]}]
- set_property PACKAGE_PIN AE4 [get_ports {c0_ddr4_cke[0]}]
- set_property PACKAGE_PIN AG9 [get_ports c0_ddr4_reset_n]
- set_property PACKAGE_PIN AD4 [get_ports c0_ddr4_act_n]
- set_property PACKAGE_PIN AC7 [get_ports {c0_ddr4_ba[1]}]
- set_property PACKAGE_PIN AH6 [get_ports {c0_ddr4_ba[0]}]
- set_property PACKAGE_PIN AD5 [get_ports {c0_ddr4_dm_dbi_n[1]}]
- set_property PACKAGE_PIN AG4 [get_ports {c0_ddr4_dm_dbi_n[0]}]
-
- set_property DRIVE 12 [get_ports {lcd_rgb[23]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[22]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[21]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[20]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[19]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[18]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[17]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[16]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[15]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[14]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[13]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[12]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[11]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[10]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[9]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[8]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[7]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[6]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[5]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[4]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[3]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[2]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[1]}]
- set_property DRIVE 12 [get_ports {lcd_rgb[0]}]
- set_property DRIVE 12 [get_ports lcd_bl]
- set_property DRIVE 12 [get_ports lcd_de]
- set_property DRIVE 12 [get_ports lcd_hs]
- set_property DRIVE 12 [get_ports lcd_rst]
- set_property DRIVE 12 [get_ports lcd_vs]
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。