基于HDMI接口和DDR存储器的VmodCAM双目摄像头驱动verilog程序开发

这篇具有很好参考价值的文章主要介绍了基于HDMI接口和DDR存储器的VmodCAM双目摄像头驱动verilog程序开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、理论基础

二、核心程序

三、仿真结论


一、理论基础

        VmodCAM板提供数字成像适用于任何Digilent FPGA系统的功能带有VHDCI连接器的板。它有两个特点Aptina MT9D112 200万像素CMOS数字图像传感器。传感器可以提供框架速率从15 FPS以上,具体取决于决议。其片上系统设计集成了图像流处理器,并启用可选输出格式、缩放和特殊效果。集成PLL(锁相环)和微处理器提供灵活的串行控制界面输出数据以并行方式发送处理后的YCrCb、RGB或原始拜耳中的总线格式。

功能包括:

•两个独立的Aptina MT9D112 2-百万像素CMOS数字图像传感器

•最大分辨率为1600x1200,分辨率为15每秒

•63mm摄像头间距(立体声基线)

•10位原始颜色深度

•I2C控制总线

•拜耳、RGB、YCrCb输出格式

•自动曝光、增益和白色均衡

•强大的图像校正算法

•图像缩放

•输出FIFO

•68针内螺纹VHDCI连接器

整个系统的结构如下所示:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

1.显示器HDMI口介绍:

这个部分对应的verilog程序为d_output.v

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这三个是时钟,复位,测试数据,

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是这个模块控制HDMI口的几个接口信号,其中最为关键的控制信号就是行列同步信号h_sync ,v_sync。行列同步信号是用来保证输出视频为稳定的,不抖动的视频信号。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是读写地址输出。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

具体的图像信息,我们这里通过RD_DATA,进行输出的。

下面,我们对这个模块进行简要的分析。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是个时钟分频信号,得到CLK的一半的时钟频率。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是产生行扫描计数器。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

产生列扫描计数器

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这两个模块产生行列同步信号。

其中摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

以下的程序是我测试HDMI口写的测试程序,就不用管了。

        那么这个模块的其本质功能就是产生行列同步信号,告诉HDMI接口,使得需要输出的视频信号按行列进行逐行的扫描,完成整个视频的显示。

2.摄像头配置介绍:

cam_input.v

cam_iic.v

这两个函数,其中第一个是将摄像头采集到的数据发送给SDRAM.

第二个函数式摄像头的配置函数,通过I2C接口进行配置。关于配置的详细信息,具体的配置参考这个datasheet。

        这个部分,所以的摄像头都是按这个步骤进行,即先进行配置,然后接收数据,你按你的摄像头进行进行处理即可。

        首先,我们来看下对应的程序:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

        摄像头图像采集信号,将摄像头采集到的信号写入到DDR中,这里下面的W*信号就 

         这个是由于这款摄像头是支持左右双通道的图像采集的,所以在采集的时候,需要设置为两倍的800X600。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是根据视频的宽度,进行line计数器的计数。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是根据视频的长度,进行pix计数器的计数。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个test是测试数据集,不用管,这里没有使用这个测试数据集。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

每16个时钟周期,产生一个写使能信号WDFIFO_WEN。

这个是数据写使能信号。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

每32个时钟周期,产生一个写使能信号WAFIFO_WEN。

这个是地址写使能信号。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

根据行列扫描器产生对应的地址信号。

        再写下摄像头的配置模块:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个模块是通过串行接口I2C,将配置数据传输到摄像头的寄存器中,

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

首先输入配置指令为comd这个变量,根据摄像头的datasheet文档可知:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

文档中写到对于MT9D112,需要输入78这个参数值。即我们这个程序中额comd这个值。

         然后代码中:

       摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是依据文档中:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

即上面159行,其余后面的根据数据手册中的地址寄存器的配置进行。

3.DDR配置介绍:

        这个模块,其对应的接口如下所示:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

这个是复位和时钟。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

        这六个信号分别为FPGA到外部芯片的写入数据以及写地址对应的数据,full以及写使能六个信号,通过这几个信号。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

读取DDR中的图像数据的读控制信号。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

MIG接口。

        首先介绍ddr_rwctrl.v这个模块,这个模块是MIG接口控制器,下面对这个模块进行介绍一下:这里是一个四状态机过程,状态机的过程如下所示:初始状态,准备状态,读状态,写状态

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

.......

到100行,这个是状态机的的状态转移过程。

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

...................

当状态机在WRITE_BURST状态的时候,则fifo写使能为1.否则为0.

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

...................

当状态机在READ_BURST状态的时候,则fifo读使能为1.否则为0.

这个模块的四个主要接口信号:

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头

分别用来控制读写数据传输FIFO,读写地址传输FIFO。

摄像头的图像采集以及显示的调试:

这个部分的调试,按如下的过程调试的:

第一:首先是使用简单的颜色对HDMI口进行测试,通过设置输出颜色像素,用来进行HDMI接口的显示。

第二:然后通过I2C对摄像头进行参数配置,然后将数据保存到DDR中,并从DDR中将数据读取。

第三:将从DDR中读取的数据放到HDMI口上进行显示。这里,主要的调试困难在于,反复的修改行列扫描的时序,直到得到较为稳定的输出图像为止。

二、核心程序

//tt_ddr_top
//05/10/2014

module tt_ddr_top#(
	parameter	PIX_DWIDTH = 16,
	parameter	PIX_AWIDTH = 11,
	//parameter	DDR_BANK_WIDTH	= 2,
	//parameter	DDR_COL_WIDTH	= 10,
	//parameter	DDR_ROW_WIDTH	= 13,
	parameter	APP_DWIDTH		= 128,
	parameter	APP_AWIDTH		= 31
)
(
	input							rst_n,
	input							vga_clk,
//	input	[PIX_DWIDTH-1:0]  vga_data,
//	input							vga_data_valid,
//	input	[PIX_AWIDTH-1:0]	addr_x,
//	input	[PIX_AWIDTH-1:0]	addr_y,
	input [APP_DWIDTH-1:0]	wdata_in,
	input [APP_AWIDTH-1:0]	waddr_in,
	output							wdfifo_afull,
	output							wafifo_afull,
	input							wdfifo_wen,
	input							wafifo_wen,
	
	input							dvi_clk,
	output read_data_fifo_prog_full,
	output read_addr_fifo_afull,
	input [APP_AWIDTH-1:0] raddr_in,
	input read_data_addr_valid,
	//input							frame_reset,
//	input 						frame_valid,
	input							wdfifo_rd_en,
	output[PIX_DWIDTH-1:0]  dvi_data,
	output						dvi_data_valid,
	
	input							ddr_clk,
	output [2:0]            app_af_cmd,
   output [30:0]           app_af_addr,
   output                  app_af_wen,
   output                  app_wdf_wen,
   output [APP_DWIDTH-1:0] app_wdf_data,
   input                   app_af_afull,
   input                   app_wdf_afull,
   input                   rd_data_valid,
   input [APP_DWIDTH-1:0]  rd_data_fifo_out,
   input                   phy_init_done,
	output	[1:0]				ready_status
	//output [3:0] led_tmp
    );


//input data/addr fifo ctrl
/*ddr_input_dctrl ddr_input_dctrl_ins(
	.vga_data		(vga_data),
	.vga_data_valid(vga_data_valid),
	.addr_x			(addr_x),
	.addr_y			(addr_y),
	.vga_clk			(vga_clk),	//40mhz
	.rst_n			(rst_n),
	.wdata_in		(wdata_in),		//data to wd fifo
	.waddr_in		(waddr_in),		//addr to wa fifo
	.wdfifo_afull	(wdfifo_afull),
	.wafifo_afull	(wafifo_afull),
	.wdfifo_wen		(wdfifo_wen),
	.wafifo_wen		(wafifo_wen)
);*/



/*ddr_read_addr_ctrl ddr_read_addr_ctrl_ins(
	.rst_n(rst_n),
	.dvi_clk(dvi_clk),
	
	.frame_valid(frame_valid),
	.read_data_fifo_prog_full(read_data_fifo_prog_full),
	.read_addr_fifo_afull(read_addr_fifo_afull),
	
	.read_data_addr(raddr_in),
	.read_data_addr_valid(read_data_addr_valid)
);*/


wire [APP_DWIDTH-1:0] rdata_out;
wire						read_data_fifo_empty;
wire						read_data_fifo_valid;
wire						read_data_fifo_ren;
wire [PIX_DWIDTH-1:0] dvi_data_tmp;
wire 						 dvi_tmp_data_valid;


wire 	write_fifo_ready;
wire	read_fifo_ready;
wire  rdwr_flag;
wire	write_data_fifo_ren;
wire	write_addr_fifo_ren;
wire	read_addr_fifo_ren;
wire	read_data_fifo_wen;
//mig interface ctrl
ddr_rwctrl ddr_rwctrl_ins(
	.ddr_clk						(ddr_clk),
	.rst_n						(rst_n),
	.phy_init_done				(phy_init_done),			//from mig 			input to this ctrl
	.write_fifo_ready			(write_fifo_ready),		//from wd/wa fifo input to this ctrl	
	.read_fifo_ready			(read_fifo_ready),		//from ra fifo 	input to this ctrl	
	.rd_data_valid				(rd_data_valid),			//from mig			input to this ctrl	
	
	.app_wdf_wen				(app_wdf_wen),				//output to mig
	.app_af_wen					(app_af_wen),				//output to mig
	.app_af_cmd					(app_af_cmd),				//output to mig
	
	.rdwr_flag					(rdwr_flag),				//select addr to addr_fifo
	.write_data_fifo_ren		(write_data_fifo_ren),	//output to wd fifo
	.write_addr_fifo_ren		(write_addr_fifo_ren),	//output to wa fifo
	.read_addr_fifo_ren		(read_addr_fifo_ren),	//output to ra fifo
	.read_data_fifo_wen		(read_data_fifo_wen)		//output to rd fifo
);

wire [APP_AWIDTH-1:0] raddr_tomig;
wire [APP_AWIDTH-1:0] waddr_tomig;
assign app_af_addr = (rdwr_flag==1'b0) ? waddr_tomig : raddr_tomig;

wire wdfifo_prog_empty;
wire wdfifo_empty;
wire wafifo_prog_empty;
wire wafifo_empty;
assign write_fifo_ready = (~wdfifo_prog_empty) && (~wafifo_prog_empty) && (~wdfifo_empty) && (~wafifo_empty) && (~app_wdf_afull) && (~app_af_afull);
//wdata_fifo
wdata_fifo wdata_fifo_ins(
	.rst				(~rst_n),
	.wr_clk			(~vga_clk),
	.wr_en			(wdfifo_wen),
	.din				(wdata_in),
	
	.rd_clk			(ddr_clk),
	.rd_en			(write_data_fifo_ren),
	.dout				(app_wdf_data),
	
	.almost_full	(wdfifo_afull),
	.empty			(wdfifo_empty),
	.full				(),
	.prog_empty		(wdfifo_prog_empty),
	.valid			()
);

//waddr_fifo
waddr_fifo waddr_fifo_ins(
	.rst				(~rst_n),
	.wr_clk			(~vga_clk),
	.wr_en			(wafifo_wen),
	.din				(waddr_in),
	
	.rd_clk			(ddr_clk),
	.rd_en			(write_addr_fifo_ren),
	.dout				(waddr_tomig),
	
	.almost_full	(wafifo_afull),
	.empty			(wafifo_empty),
	.full				(),
	.prog_empty		(wafifo_prog_empty),
	.valid			()
);

assign read_addr_fifo_wen = read_data_addr_valid;
wire rafifo_empty;
wire rafifo_prog_empty;
wire rdfifo_afull;
assign read_fifo_ready = (~rafifo_prog_empty) && (~rafifo_empty) && (~app_af_afull);//&& (~read_data_fifo_prog_full)
//raddr fifo
raddr_fifo raddr_fifo_ins(
	.rst				(~rst_n),
	.wr_clk			(~dvi_clk),
	.wr_en			(read_addr_fifo_wen),
	.din				(raddr_in),
	
	.rd_clk			(ddr_clk),
	.rd_en			(read_addr_fifo_ren),
	.dout				(raddr_tomig),
	
	.almost_full	(read_addr_fifo_afull),
	.empty			(rafifo_empty),
	.full				(),
	.prog_empty		(rafifo_prog_empty),
	.valid			()
);

output_data_fifo new_rdfifo_ins (
	.rst						(~rst_n),
	.wr_clk					(~ddr_clk),
	.wr_en					(read_data_fifo_wen),	
	.din						(rd_data_fifo_out), // Bus [127 : 0] 
	
	.rd_clk					(~dvi_clk),
	.rd_en					(wdfifo_rd_en),	
	.dout						(dvi_data), // Bus [15 : 0] 
	.valid					(dvi_data_valid),
	
	//.full						(full),
	.almost_full			(rdfifo_afull),
	.empty					(read_data_fifo_empty),
	.almost_empty			(),

	.prog_full				(read_data_fifo_prog_full)
	);


assign ready_status[0] = write_fifo_ready; 
assign ready_status[1] = read_fifo_ready;

endmodule
A10-30

三、仿真结论 

摄像头程序开发,FPGA,板块10:FPGA接口开发,fpga开发,HDMI接口,DDR存储器,VmodCAM双目摄像头文章来源地址https://www.toymoban.com/news/detail-670553.html

到了这里,关于基于HDMI接口和DDR存储器的VmodCAM双目摄像头驱动verilog程序开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 012 - STM32学习笔记 - DMA_存储器到存储器

    011 - STM32学习笔记 - DMA直接存储器 1、DMA简介 我们知道stm32在实际应用过程中具有很强大的功能,包含数据的采集、处理、逻辑功能的运算等,因此stm32一直在处理大量的事务,但是在实际使用过程中,我们知道有些事情实际上不需要CPU过多参与,比如:数据的复制和存储,当

    2024年02月08日
    浏览(49)
  • 计算机组成原理之机器:存储器之高速缓冲存储器

    笔记来源:哈尔滨工业大学计算机组成原理(哈工大刘宏伟) 3.1.1 为什么用cache? 角度一: I/O设备向主存请求的级别高于CPU访存 ,这就出现了CPU等待I/O设备访存的现象,致使CPU空等一段时间,降低CPU工作效率。为 避免CPU与I/O设备争抢访存 ,可在CPU与主存之间加一级缓存,

    2024年03月10日
    浏览(63)
  • 【DRAM存储器六】DRAM存储器的架构演进-part3

    👉个人主页:highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容  参考书籍:《Memory Systems - Cache, DRAM, Disk》      目录

    2024年02月08日
    浏览(38)
  • 【DRAM存储器五】DRAM存储器的架构演进-part2

    👉个人主页:highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容  参考书籍:《Memory Systems - Cache, DRAM, Disk》      目录

    2024年02月07日
    浏览(41)
  • 计算机的主存储器与辅助存储器

    今天给大家介绍计算机的 主存储器 和 辅助存储器 ,也就是我们所说的 主存 和 辅存 。 主存一般就是指内存,辅存指的就是磁盘 。在正式介绍之前,大家可以思考两个问题: 为什么计算机断电,内存数据会丢失?为什么计算机断电,磁盘数据不会丢失? 这两个问题贯穿我

    2024年02月05日
    浏览(62)
  • [深入理解NAND Flash (原理篇)] Flash(闪存)存储器底层原理 | 闪存存储器重要参数

    传送门 总目录  所在专栏   《 深入理解SSD》 个人辛苦整理,付费内容,禁止转载。 内容摘要 从底层物理原理上了解 Nand Flash。 现代计算机构想是基于冯 · 诺依曼架构的图灵计算机设备,图灵从理论上去论证了现代计算机可以实现,也就是给现代计算机注入了灵魂,而冯

    2024年02月06日
    浏览(47)
  • ROM、RAM、内存、内存条、外存、内部存储器、外部存储器、FLASH等之间的关系

    ​   各位看到这一系列的名词,是否也曾感受到一头雾水?研究了一上午终于理清了它们之间的关系,直接上图说明,相信你看完也能恍然大悟!若有错误麻烦在评论区指出。 这里有几点需要明确: 存BOIS的ROM也属于内存(因为CPU也可以对其直接寻址),但我们生活中常说

    2023年04月26日
    浏览(55)
  • 存储器的结构

    存储的基本结构如下: 控制逻辑会给出读写操作信号: 读操作时,控制逻辑会给出信号,读出相应的存储器单元的数据,然后交给数据寄存器。 写操作时,数据寄存器会先寄存数据,然后通知控制逻辑给出写信号,写入到相应的存储器元。 如下图所示,一个存储体是由很多

    2023年04月19日
    浏览(41)
  • 3.5 并行存储器

    如果我要学习并行存储器,我会采取以下几个步骤: 了解并行存储器的基本概念和原理。学习并行存储器的前提是要对存储器的基本原理有所了解,包括存储器的分类、工作原理、读写时序等。 学习并行存储器的特点和应用。并行存储器在高性能计算、图形图像处理等领域

    2024年02月02日
    浏览(38)
  • 2.存储器层次系统

    RAM(随机存储器) SRAM 双稳态触发器,有电就保持不变,干扰消除后时会恢复到稳定值,晶体管多因此密集度低 DRAM 每个位存储为对一个电容的充电,对干扰敏感,漏电所以需要刷新 刷新: 集中刷新:产生“死区”,2ms内集中刷新每一行 分散刷新:没有死区 异步刷新:结合

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包