DDR3联合HDMI进行图片数据的传输

DDR3联合HDMI进行图片数据的传输

 

  • 项目概况
  • DDR3 IP核调用及介绍
  1. DDR3 IP核的调取
  2. IP核引脚以及功能说明
  • DDR3内部模块
  1. 仲裁模块
  2. 读写模块
  3. 仿真测试
  • DDR3外部模块
  1. 外部读写模块
  2. 内外联合测试仿真
  • HDMI模块
  1. encode模块
  2. par2ser模块
  3. HDMI仿真测试
  • DDR3联合HDMI

项目概述

本次项目是为了实现DDR3联合HDMI,进行一幅1024*768图片的显示,在PC机上利用串口讲图片的数据发送给DDR3并存入到DDR3中,然后由HDMI将数据取出来,显示到显示器上。

项目框图如下:

      DDR3联合HDMI进行图片数据的传输_第1张图片

本次项目的主要目的是通过DDR3和HDMI这种联合的方式,掌握DDR3的存取原理和HDMI的显示原理,自己搭建起DD3的控制器,将DDR3灵活的运用起来,同时编写HDMI_trans模块去发送我们想要显示的图像数据,以达到通用的效果。

实验环境为Vivado 16.4,Win10,64位,采用开发板为XC7A35T-2FGG484。

DDR3 IP核调取及介绍

一.DDR3 IP核的调取:

1.调取方法

 A7的DDR3调用方法和Spartan6一样,通过GUI界面调取IP的方法来调用DDR3

       下面为DDR3 IP核调用事项(放大后看清):

              在IP界面中选择7系列的MIG:

DDR3联合HDMI进行图片数据的传输_第2张图片

选择你的IP名字:

DDR3联合HDMI进行图片数据的传输_第3张图片

DDR3联合HDMI进行图片数据的传输_第4张图片

这一页改动很多,而且很重要,在这里有较为详细的解释:

DDR3联合HDMI进行图片数据的传输_第5张图片

DDR3数据的位宽是16位,并且是双沿数据,因为在用户端是只能上沿发送数据,所以用户端的数据位宽就为:16*2*4==128位的,这个的*4就是4:1造成的。

DDR3联合HDMI进行图片数据的传输_第6张图片

关于参考时钟:理论上应该给一个稳定200M的时钟,用来恢复主时钟的时钟质量,

       下面的一个页面全部选默认,到了绑定管教的界面直接绑定管脚就好了

DDR3联合HDMI进行图片数据的传输_第7张图片

接下来一点默认到生成IP核,之后会在你的工程中生成这样的文件夹:

DDR3联合HDMI进行图片数据的传输_第8张图片

在调取完成DDR3的IP核之后,就可以启动仿真来测试一下:

2.IP核的例化

 首先建立一个顶层文件,将DDR3的IP核例化进来:

DDR3联合HDMI进行图片数据的传输_第9张图片

在这个界面可以找到DDR3 IP核的例化模板,将IP核例化进去,然后需要将连接DDR3的绑定管脚的部分引到外面去,而那些中间用户变量需要模块中声明(ddr3开头为引脚,app的则为用户变量):

DDR3联合HDMI进行图片数据的传输_第10张图片

3.IP核的仿真

 将ip核例化好之后,在tb里面将顶层文件例化一下,声明各种中间变量,同时,还需要加一个DDR3的模型到tb中来充当DDR3。模型的位置如下:

DDR3联合HDMI进行图片数据的传输_第11张图片

DDR3联合HDMI进行图片数据的传输_第12张图片

启动仿真打开ModelSim之后,选择添加ddr3_ctrl模块,运行一段时间,如果init_calib_complete拉高,则表示DDR3初始化成功,调取DDR3 IP核可以进行更进一步的操作。

DDR3联合HDMI进行图片数据的传输_第13张图片

二 . 功能及引脚介绍

  1. DDR3时序介绍:

       如果想要完全的用起来DDR3的IP核,需要知道它内部的运作原理和时序。通过查阅相应的DataSheet可知:A7的DDR3突发长度是固定为8的,也就是一次突写写8次单位地址的长度,如果DDR3的数据线为8位,突写一次就需要些8*8=64bit,而16位的话则需要16*8=128bit。

  1. DDR3的两种模式:

       DDR3有4:1和2::1两种模式,,这个4:1 和 2:1 是我们在调取IP的时候可以选择的,这里的 4:和2指的是DDR3与DDR3的IP核完成一次突发所需要的时钟周期的长度,而1指的是用户端向DDR3的IP核发送数据所需要的时钟周期数,不同的模式,有不同时序。 以数据线为8为例来说:

        如果选择2:1的模式,用户需要用两个时钟周期发送一次突写的数据,8*8=64,一个时钟周期也就是32位,而DDR3与IP核交互数据时,需要64/2(双沿)/8(单位数据位宽)=4; DDR3与IP核交互完成一次突发所需要的时钟周期,和用户和IP核完成一次突发所需要的时钟周期之比,就为DDR3的这两种模式。

DDR3联合HDMI进行图片数据的传输_第14张图片

       同样的4:1也是如此,只不过在用户端与IP核交互时,一次突写只需要一个时钟周期。而DDR3与IP核交互数据不变。

  1. DDR3的时钟方面:

 DDR3有许多的时钟,不管是什么时钟,我们都需要弄清楚,从最开始调用IP核说明:DDR3联合HDMI进行图片数据的传输_第15张图片 这个Clock Peried就是DDR3的时钟,为400M,和芯片的种类和速度等级有关。而下         面的4:1就是上面所说到的DDR3的两种模式,也就是用户时钟和DDR3时钟的关系。

DDR3联合HDMI进行图片数据的传输_第16张图片

DDR3联合HDMI进行图片数据的传输_第17张图片 Input Clock Period :这个时钟是输入给DDR3 IP核的时钟,IP核中自带了一个PLL,它会将输入的时钟分倍频到DDR3所需要的时钟。如果输入到 IP 核的时钟是外部晶振生成的切单端,那就选择Singel_Ended ,如果是差分的,就选择Differential,但是现在我们决定用外部PLL产生一个200M的时钟,来给IP核,而PLL自带BUFFG,所以选择 No Buffer。

Reference Clock :参考时钟,利用这个参考时钟,来生成用户的100M时钟(ui_clk),它的精度要求范围为199M-201M,如果上面选择输入时钟为200M,则这个可以用输入的系统时钟来代替,如果不是则需要另外开一个接口输入进来200M的时钟。

  1. IP核的读写时序:
  1. 写时序:

 IP核往DDR3里面写入数据时,需要向AXI总线那样,给出一定的握手信号才能完成。

DDR3联合HDMI进行图片数据的传输_第18张图片

由上图可知:在采用4:1的模式下,数据(app_wdf_data[127:0])和写使能(app_wdf_wren)和数据突写结束信号(app_wdf_end)同时出现,标志着此时数据有效,但只有当准备信号(app_wdf_rdy)信号有效时,才标志着数据被暂时的缓存到了IP核中,只有当给出了写的命令,和地址,而且app_en 和 app_rdy同时拉高,表示命令(3’b000)和地址被接受,就会将缓存在IP核中的数据,真正的写入到了DDR3中。写的命令和地址,可以提前与数据,也可以同时或者落后,但是数据落后的时间不应超过两个时钟周期。

为了确保能正确的将数据送入到DDR3中,我们只选择一种模式,而且是和Spartan一样的先给出数据,再给出命令。

  1. 读时序:

DDR3联合HDMI进行图片数据的传输_第19张图片

在 4:1的模式下,首先给出读的命令(3‘b001)和地址,当app_en和app_rdy信号同时有效时,表示命令和地址被接受,在接下来的一段时间内,IP核会将所读地址的数据读出来并且伴随着一个有效的同步信号(app_rd_data_valid)。

  1. 读写时序总结:无论是读还是写,都会是分为两个部分,命令端和数据端。

对于写来说,先给出数据端(app_wdf_data[127:0], app_wdf_end, app_wdf_wren, app_wdf_rdy),等数据端被IP核接受了之后,发送命令端的信号(app_cmd,app_addr,app_en,app_rdy),将数据写入到DDR3中,只有这几个信号之间相互配合,才能将数据写入到DDR3中,完成一次数据写的突发。

对于读来说,是先给出命令端信号(app_cmd, app_addr, app_en, app_rdy),当IP核接受到这些命令之后,就会将数据端的信号送出来(app_rd_data[127:0], app_rd_data_valid)。从而完成一次数据读的突发。

  1. IP核引脚及功能说明:

IP的引脚共分为两个部分,一个是和DDR3直接交互的引脚部分,另一个则是和用户端交互的。

              DDR3联合HDMI进行图片数据的传输_第20张图片

下面是对引脚的说明:

 

Name

输入输出

备注

ddr3_dq[15:0]

inout

DDR3的数据位宽,传输数据的单位以它位基础,如果来8位,则是以字节为单位,而16位则是以Word为单位

ddr3_dqs_n[1:0]

inout

数据选通。读时是输出,边缘与读出的数据对齐。写时是输入,中心与写数据对齐。

ddr3_dqs_p[1:0]

inout

 

ddr3_addr[13:0]

output

和SDRAM一样采取行列复用的原则 2^3*2^14*2^10=2^27=128M

ddr3_ba[2:0]

output

BANK地址

ddr3_ras_n

output

行地址选通,低有效

ddr3_cas_n

output

列地址选通,低有效

ddr3_we_n

output

写使能,低有效

ddr3_reset_n

output

DDR3的复位,低有效

ddr3_ck_p

output

DDR3系统时钟,由200M倍频而来,差分对

ddr3_ck_n

output

 

ddr3_cke

output

时钟使能,高有效

ddr3_cs_n

output

片选,低有效

ddr3_dm[1:0]

output

Data mask DDR3输入数据的掩码

ddr3_odt

output

片上终端使能

app_addr[27:0]

input

用户地址,

app_cmd[2:0]

input

用户命令,3‘b000(写),3’b001(读)

app_en

input

命令使能信号,拉高表示命令被使能

app_wdf_data[127:0]

input

写数据,表示需要往DDR3里写的数据

app_wdf_end

input

一次突发的结束

app_wdf_mask[15:0]

input

数据掩码。一位掩码可以掩掉8bit数据,掩码位宽等于数据位宽/8

app_wdf_wren

input

数据写使能

app_rd_data[127:0]

output

读数据,DDR3中读取出来的数据

app_rd_data_valid

output

读数据的同步信号

app_rdy

output

IP核命令准备信号,拉高表示此时IP核能接受命令

app_wdf_rdy

output

IP核写命令信号,拉高表示此时IP核能接受数据

ui_clk

input

用户时钟,用参考时钟分频而来

ui_clk_sync_rst

input

用户时钟复位

init_calib_complete

output

DDR3初始化完成信号,一切对DDR3的操作应该在初始化完成之后。

 IP核与DDR3交互的接口,不需要我们去关心,Xilinx已经帮我们做好了。对于DDR3,都是基于用户接口来操作的,所以需要将app接口的各种信号相互配合,灵活的运用起来,已达到我们想要的目的。

DDR3内部模块

在A7这块芯片中,DDR3 IP核的用户接口和AXI总线有类似的地方,并没有像Spartan6那样方便,DDR3需要同时和不同的模块进行交互时在,这样的接口就显得有些不足,并没有通用性,为了以后方便使用A7的DDR3,可以在Spartan6的基础上,将A7的DDR3接口和用户交互功能做到和Spartan一样,即保证了通用性,还具有一定的统一性。

下图为Spartan 6 中的DDR控制器:

DDR3联合HDMI进行图片数据的传输_第21张图片

我们可以仿照Spartan6 作一个同样的:

DDR3联合HDMI进行图片数据的传输_第22张图片

我们可以将红色的线条内的逻辑,和Spartan6 一样具有相同的功能,用户只需要将命令和数据存储到命令FIFO和数据FIFO中,仲裁状态就会判断是否去执行读和写,从而启动WR_CTRL 和RD_CTRL,利用WR_CTRL 和RD_CTRL去和A7_DDR3的IP和交互,完成数据的收发

一.仲裁状态:

       仲裁模块是用户端和读写端的桥梁,同时也是控制器,当读或者写的命令FIFO中不为空,表示用户端发出读写的请求,则启动仲裁模块,下图为仲裁模块的时序图:

DDR3联合HDMI进行图片数据的传输_第23张图片

       uploading.4e448015.gif正在上传…重新上传取消

当命令fifo不就为空时,状态机就会从仲裁状态跳转到相应的读写状态,同时产生一个内部读写模块的启动信号,这个启动信号又去读取命令fifo中数据传到相应的读写模块中,当完成一次自定义的突发时,读写模块回传一个结束标志,状态机又跳转到仲裁状态,等待下一次命令的到来。

       接口定义解释:

Name

输入输出

备注

ui_clk

Input

IP核中由参考时钟分屏出来的100M用户时钟

calib_done

Input

IP核初始化完成信号,一切对IP核的操作需要在它拉高之后

pi_wr_start

Input

写命令FIFO的空信号取反,不空则表示有命令输入进来需要进行相对应的状态的跳转

pi_rd_start

Input

读命令FIFO的空信号取反,不空则表示有命令输入进来需要进行相对应的状态的跳转

wr_end

Input

写模块结束一次自定义突发长度时信号

rd_end

Input

读模块结束一次自定义突发长度时信号

po_wr_start

Output

写模块开始一次自定义突发长度时信号

po_rd_start

Output

写模块开始一次自定义突发长度时信号

二.内部读写模块:

       1.写模块

       对于写的操作,仲裁模块给出一个写的启动信号,然后模块开始工作,需要给出写的数据(app_wdf_data[127:0]),和写使能(app_wdf_wren),当IP核准备好接收这些数据时,就会把写准备拉高(app_wdf_rdy),那么数据就会被存入到IP核中,等到命令使能(app_en)和命令准备(app_rdy)同时拉高时,就会将数据写入到给出的地址当中。完成一次突发写的操作。用于DDR3的数据线为16位,一次固定突发为8,那么采用4:1的模式,用户数据位宽位128位,即一个用户时钟,就可以完成一次DDR3的突发,所以我们可以自定义IP核完成突发的个数。

       下图为内部写的时序图:

DDR3联合HDMI进行图片数据的传输_第24张图片

当收到wr_start_flag时,启动并完成bl=64的一次写。由于两个rdy信号不受我们控制,所以需要计数器去控制命令端和数据端的个数。当写使能和些准备同时为高,当前数据被写入,还需要data_req信号输出到外部去请求数据。命令端和数据端的使能信号和准备信号同时拉高了突写次数时,就完成了一次突发,可以将使能信号拉低,同时计数器归零,以备下一次突发。关于app_en的启动,可以检测app_wdf_wren的上升沿来判断。

       接口定义解释:

Name

输入输出

备注

ui_clk

input

 IP核中由参考时钟分屏出来的100M用户时钟

calib_done

input

 IP核初始化完成信号,一切对IP核的操作需要在它拉高之后

po_wr_flag

input

模块工作信号,相对于命令fifo的读使能晚一拍

data_req

 

数据请求

wr_end

 

IP核突写一次用户自定义长度的结束信号

app_wdf_rdy

input

IP核写准备信号,拉高表示能结束数据写入

app_rdy

input

IP核命令准备信号,拉高表示能接受命令写入

wr_data[127:0]

input

外模块传进来需要向IP核写入的数据

wr_cmd_addr[27:0]

input

外模块传进来需要给IP核的写入地址

wr_cmd_instr[5:0]

input

外模块传进来需要给IP核的一次用户自定义的突写长度

wr_cmd[2:0]

input

外模块传进来需要向IP核写入的命令

wr_data_mask[15:0]

input

外模块传进来数据掩码,某一位为高则表示相应的字节数据被掩掉

app_wdf_wren

output

IP核数据写使能

app_wdf_end

output

IP核突写的结束信号

app_en

output

命令使能信号

app_addr[27:0]

output

用户地址

app_cmd[2:0]

output

用户命令

app_wdf_data[127:0]

output

用户写数据

app_wdf_mask[15;0]

output

用户数据掩码

2.读模块:

       当仲裁模块传过来读的启动信号,RD_CTRL就会启动,读取一次用户自定义的突发长度的数据。 时序图如下:

DDR3联合HDMI进行图片数据的传输_第25张图片

uploading.4e448015.gif正在上传…重新上传取消

启动信号拉高后,app_en和app_rdy这两个命令端的必须同时拉高用户自定义突发长度个时钟周期,同时给出读命令和地址,然后延迟几个时钟周期,就会产生app_rd_data[127:0]和app_rd_data_valid信号。当app_rd_data_valid为高,表示读数据有效,而且当app_rd_data_valid拉高了用户自定义突发长度时,表示一次用户自定的突写结束,此时传出一个rd_end信号,告诉仲裁模块退出读状态 

      

3.内部连线:

       当内部模块完成之后,由于各个模块相互约束,交错连接,连线成了设计的一个难点,需要十分的认真仔细,注意位宽,给各个信号取不易混淆的变量名,一步一步,从顶端输入输出,一步一步连接下去。在顶端先加入Spartan一样的接口:

DDR3联合HDMI进行图片数据的传输_第26张图片

接下来就需要例化四个fifo,分别是命令的读和写的fifo,数据的读和写的fifo,命令fifo深度为16,位宽位({p2_cmd_instr[2:0],p2_cmd_bl[6:0],p2_cmd_byte_addr[27:0]})}因为对其去求量不大,可以采用分布式ram以减少逻辑资源的浪费。数据fifo可以用深度为64,位宽位144(p2_wr_mask[15:0],p2_wr_data[127:0]),读数据fifo中掩码的部分可以不用,用0代替。

DDR3联合HDMI进行图片数据的传输_第27张图片

 

   接下来就内部读和写模块,仲裁模块之间的相互接连,仲裁模块的启动信号是命令fifo的空信号,不空则跳转到相应的状态,同时读出命令fifo的数据给相对的读模块或者写模块,并且启动该模块,当完成时,传回一个结束信号,标志着此次突发完成,仲裁模块有重新判断命令FIFO的空信号,这样就使得各个模块循环起来。

DDR3联合HDMI进行图片数据的传输_第28张图片

连线完成之后,DDR3_CTRL模块就基本上和Spartan6的IP核一致了,具有通用性核统一性。

三.模块功能仿真,新建一个顶层,将DDR3_CTRL模块例化进去,通过控制P2 和 p3口,来达到写入数据,并且能读出来的效果。

       创建一个data_gen模块用于产生测试数据和读写信号,先将0-3f 64个数据写入到DDR3_ctrl模块的写数据fifo中,然后在给一个写的命令,仲裁模块会判断是否写,并且启动内部的写模块,从而将存储在DDR3_ctrl的写数据FIFO中的数据写入到DDR3中,然后在data_gen模块中在产生一个读的命令,仲裁模块就会启动内部的读模块,从而将数据从DDR3中读取出来存到读数据的FIFO中。一次的读和写给出相同的地址和突发长度,就会将刚刚写入的数据读出来,以达到完成ddr3_ctrl模块测试的效果。

DDR3联合HDMI进行图片数据的传输_第29张图片

 

 

       由上图所示,写入 0-3f数据后,又读出来0-3f,同时伴随着app_rd_data_valid同步有效信号,证明模块测试正确,达到了我们想要的目的。   

 

 

 

 

 

 

DDR3 外部模块

一.外部读写模块测试。

       外部的读写模块不同于内部,是直接与用户交互的模块,所以分别取名user_wr_ctrl和user_rd_ctrl 以区分内部和外部读写模块。在外部模块中,通过控制DDR3_CTLR的用户接口,达到和DDR3读写交互的效果,可以适当添加一下全局的参数来增加其通用性。

  1. 写模块:

 无论外部的数据是连续的还是间断的写入,都应该能将数据完整的写入到DDR3中,

所以在本模块中,应该起到一个适配的作用,将传过来的数据,在位宽和数量上进行一定的处理,假设数据是由串口过来的八bit数据图像数据,由于DDR3_ctrl的数据位宽位为28位,所以传给DDR3_ctr一次需要16次串口发过来的数据拼接在一起发送。本模块采用尝试采用全局参数的方法,不仅可以支持串口的8位数据拼接,也可以支持其他不同位宽的数据拼接。时序图如下:

DDR3联合HDMI进行图片数据的传输_第30张图片

        将传送过来的数据没拼接成128位时,就启动一次写使能,然后将128位数据写入到IP核中,等到突发的次数够了,启动一次写的命令,将IP核的数据,写入到DDR3中。

全局参数相关变量: 需要拼接的数据位宽,突写长度,读写基地址

DDR3联合HDMI进行图片数据的传输_第31张图片

利用二进制一位代表一个位宽的特点,采用下图函数计算参数的位宽:

DDR3联合HDMI进行图片数据的传输_第32张图片

Name

输入输出

备注

sys_clk

Input

系统时钟

sys_rst_n

Input

系统复位

in_data[8:0]

input

输入数据

in_flag

input

输入数据的同步信号

p2_wr_data[127:0]

output

拼接起来的数据

p2_wr_en

output

传给DDR3_ctrl模块的写使能

p2_cmd_en

output

传给DDR3_ctrl模块的命令使能

p2_wr_addr

output

传给DDR3_ctrl模块的地址

p2_cmd_instr

output

传给DDR3_ctrl模块的命令

p2_cmd_bl

output

传给DDR3_ctrl模块的突写长度

 

  1. 读模块:

  由于本次实验需要和HDMI联合进行图片的显示,由于两者的时钟不同,系统时钟为125M,而VGA的时钟为65M,所以需要在读模块中读取DDR3的数据,然后存储到一个用户fifo中,当HDMI场同步到来之后紧接着的第一个de有效信号表示显示的第一行,如果此时fifo的数据大于门限值,则可以将数据读出显示到HDMI上,而当fifo的数据小于一定的门限值时(可以是一行像素点的数据),读模块有继续向DDR3中读取数据,以此往复。形成循环。

        时序图如下:

DDR3联合HDMI进行图片数据的传输_第33张图片

当fifo中的数据小于门限值时,需要向DDR3中读取数据填充fifo:先给一个读的命令(伴随着地址,命令,地址,完成之后地址加一,为下一次做准备),然后当DDR3_CTRL中读数据fifo存储到够一次突写的长度时,拉高读使能,将数据读出来并且存储到fifo中,当HDMI需要数据时(图像的第一行),打开读使能,并且正确的将128位数据合理的分拆成24位一组的RGB数据。这样的话,就完成了DDR3方面的工作。

       模块引脚说明:

Name

输入输出

备注

sys_clk

input

系统时钟

sys_rst_n

input

系统复位

vclk

input

VGA时钟,fifo的读时钟

fifo_rd_en

input

Fifo的读使能,由HDMI模块给出

v_sync

input

场同步信号,用于同步图片

pixel_rgb[23:0

output

像素点的RGB值,由fifo中读出

p3_cmd_full

input

读端口的命令fifo慢信号,不能再满的时候给出信号

p3_rd_count

input

读端口数据fifo存储的数量

p3_rd_data[127:0]

input

DDR3中存储的RGB值,由

p3_cmd_instr[2:0]

output

传给DDR3_ctrl模块的命令

p3_cmd_bl[6:0]

output

传给DDR3_ctrl模块的突发长度

p3_cmd_en

output

传给DDR3_ctrl模块的命令使能

p3_rd_en      

output

传给DDR3_ctrl模块的读使能

p3_cmd_addr[27:0]

output

传给DDR3_ctrl模块的读地址

拆分时序图如下:

DDR3联合HDMI进行图片数据的传输_第34张图片

当fifo中有一定数量的值时,且场同步到了,此时拉高pixel_oe信号,作为数据和图像的同步信号,由于进来的数据为128位,而rgb的值为24位,不是整数倍的关系,股可以将128的数据每三个拼接在一起(128*3/24=16),先将384的shift_data填充满,当vga需要数据时,就将shift_data的低24位送出,然后右移24位,等全部移出后(rgb_cnt==15),在取出384位继续填充shift_data,以此往复,这样就循环起来了。

DDR3联合HDMI进行图片数据的传输_第35张图片

DDR3联合HDMI进行图片数据的传输_第36张图片

二.内外联合测试仿真,

   当完成了内部和外部的读写,就可以用仿真来测试自己的逻辑是否正确,测试模块有多种写法,就写一个最简单的吧,在DD3R复位后,首先在测试模块data_gen中,连续给出8位的数据和同步信号,知道满足一次突写的长度,也就是64*128=8192,而8192/8=1024,0也就是连续需要1024个8位的数据和同步信号,给到外部的user_wr_ctrl之后,而user_wr_ctrl将数据写入到DDR3_Ctrl中的写数据fifo,之后等存储的数据达到了突写的长度,就给出一次命令,就fifo的中的数据存入到DDR3中,之后拉高一次p3口的写使能,测试数据是否会存储到外部user_rd_ctrl中的fifo。由于还没有加上HDMI模块,所以不好断定读模块是否正常,所以可以将先测试写模块。

Data_gen模块波形图:

User_wr_ctrl模块波形图

   insder_wr_ctrl模块波形图:

DDR3联合HDMI进行图片数据的传输_第37张图片

 

由上波形图可以得出,数据在     User_wr_ctrl处拼接,然后送往内部写数据fifo,存到一定数据量时,就将数据存储到ddr3中,之后完成传出一个wr_end命令,标志这一次突发的写结束,初步达到了预期的效果,如果需要测试读模块是否正确的话,可以等加上HDMI模块之后,联合HDMI模块一起测试。这样的话,DDR3从调用到正常的使用自如,到这步算是初步完成了。

HDMI模块

一.HDMI介绍:

           HDMI的全称是“High Definition Multimedia Interface” 高清多媒体接口,是2002年,来自电子行业的七家公司,日立,松下,飞利浦,Silicon Image,索尼,汤姆逊,东芝共同组建了HDMI高清多媒体接口组织HDMI,开始制定一种符合高清时代标准的全新数字化视频、音频接口技术,经过半年多的时间准备工作,HDMI founders在2002年12月9日正式发布了HDMI1.0版标准,标志着HDMI正式进入历史舞台。

       DHMI传输原理如下:

DDR3联合HDMI进行图片数据的传输_第38张图片

     传输的方式是在VGA的基础上演变而来的,将VGA的时序,转化为4路TMDS通道(R,G,B,clk),HDMI使用最小跳变差分信号(TMDS)技术,差分信号上拉电压为+3.3v,端口阻抗为20欧姆,单端信号为400-600mV,标称为500mV,差分信号的逻辑摆幅在800-1200Mv之间,实际差分电压可以再150-1200Mv之间变化,而且偏置电压是由Sink端提供的。

  HDMI相对VGA具有以下优点:

  1. 更好的抗干扰性能,且兼容性更好
  2. 支持24bit色深处理,且支持音频,
  3. 一根线缆实现数字音频,视频信号的同步传输,有效降低成本和繁杂程度。
  4. 支持热插拔技术。

 

想要利用HDMI进行图像的显示,需要将VGA的时序转化我HDMI的时序,需要经过如下图所示的几个步骤:

      DDR3联合HDMI进行图片数据的传输_第39张图片

1.8b/10b编码

       进行8b/10b编码是为了防止在发送数据的过程中连续出现多个0或者是1,这样的话在这段时间内,数据线的电流可视为直流电压,而直流电流会影响数据的传输,8B10B编码转换的作用就是让DC平衡,使得电路中0和1出现的次数向接近,以达到DC平衡的作用。

DDR3联合HDMI进行图片数据的传输_第40张图片

在Xilinx的官网上,可以找到8b/10b转换的V文件和相关文档。将其下载下来可以直接使用,我们只需要将其例化进来,然后就能直接使用,就8bit的R,G,B数据转换为10bit的数据。

DDR3联合HDMI进行图片数据的传输_第41张图片

encode模块接口说明:

Name

输入输出

备注

clkin

Input

pixel clock input 数据同步时钟

rstin

Input

async. reset input (active high) 异步,高有效

din[7:0]

Input

8bit数据输入

c0

Input

Contrl Port 0,控制端口,数据为B时连接VGA的行同步信号

c1

Input

Contrl Port 0,控制端口,数据为B时连接VGA的场同步信号

de

Input

数据有效信号

dout[9:0]

output

输出的10bit数据

2.par2ser并转串模块:

       HDMI_trans模块中数据的发送是四路单bit串行数据发送,而VGA的数据是是由24bit R,G,B 8bit一组的并行数据,所以在数据发送的过程总需要并行数据转换为串行的数据, 在Vivado中,Xilinx为我们提供OSERDES的原语,作用是将并行数据串行化输出,

  DDR3联合HDMI进行图片数据的传输_第42张图片

对于原语更多的介绍,必须要查找相关的Datasheet手册才能准确的了解清楚。在Xilinx官方的7_Series FPGAs SelectIO Resources中,给出来OSERDES的具体介绍:

DDR3联合HDMI进行图片数据的传输_第43张图片

7系列的OSERDES具有支持多种模式和不同速率的并行转串行化输出的原语,同时支持三态门数据和双沿数据的转换,具有普遍性和统一性。在上一个模块这种,R,G,B的8bit数据已经变为10bit的具有DC平衡的数据,在本模块模块中需要使用到OSERDES的扩展模式(支持10bit数据输入),采用双沿模式输出串行数据,假设R,G,B的时钟为65M,如果采用单沿模式输出串行数据,则需要650M的同步时钟,而使用双沿模式,则只需要325M的时钟即可,减少了对时钟的要求,利于我们更好的做进一步的设计。

OSERDES原语参数说明:

 

由于数据为10bit,则需要使用OSERDES的扩展模式,需要将两个OSERDES级联在一起:

DDR3联合HDMI进行图片数据的传输_第44张图片   

 

 

扩展模式的OSERDES,具有主机和从机,需要将主机的SHIFTIN1和2分别与从机SHIFTOUT1和2相连,数据的低8bit由主机进入,高两位由从机进入,串行数据的输出从主机的OQ口输出。在OSERDES中,数据的传送如下所示:

DDR3联合HDMI进行图片数据的传输_第45张图片

输入的并行数据由低到高依次从OQ端输出,如果时串行数据进入到ISERDES,则串行数据先进来的进入到高位。

OSERDES 参数说明:

Name

可选项

说明

DATA_RATE_OQ

DDR, SDR

输出串行数据的模式

DATA_RATE_TQ

DDR, BUF, SDR

三态数据输出模式

DATA_WIDTH

2-8,10,14

并行数据的位宽

INIT_OQ

1'b0,1'b1

初始化是OQ的值

INIT_TQ

1'b0,1'b1

初始化是OQ的值

SERDES_MODE

MASTER, SLAVE

选择这个OSERDES是主机还是从机

SRVAL_OQ

1'b0,1'b1

复位时第一个寄存器的值

SRVAL_TQ

1'b0,1'b1

传输三态数据时复位时第一个寄存器的值

TBYTE_CTL

FALSE, TRUE

Only for use via the MIG tool. Set to FALSE

TBYTE_SRC

FALSE, TRUE

Only for use via the MIG tool. Set to FALSE

TRISTATE_WIDTH

1,4

三态数据的位宽

OSERDES 接口说明:

Name

输入输出

说明

OFB

output

用于联合ISERDES所用

OQ

output

串行化数据的输出

SHIFTOUT1

output

用于扩展模式,从机输出连接主机

SHIFTOUT2

output

用于扩展模式,从机输出连接主机

TBYTEOUT

output

Byte group tristate

TFB

output

3-state control

TQ

output

3-state control

CLK

Input

High speed clock 高速时钟,串行化数据的同步时钟

CLKDIV

Input

Divided clock 分频时钟,

D1 – D8

Input

并行数据的输入

OCE

Input

Output data clock enable,输出数据时钟使能

RST

Input

Reset,高有效

SHIFTIN1

Input

用于扩展模式,主机接收从机输入

SHIFTIN2

Input

用于扩展模式,主机接收从机输入

T1-T4

Input

三态数据

TBYTEIN

Input

Byte group tristate

TCE

Input

3-state clock enable

DDR3联合HDMI进行图片数据的传输_第46张图片

因为HDMI是四路通道,还需要一路像素时钟来同步R,G,B的数据,为了让时钟尽可能的和串行数据同步化,所以可以让10‘b111110000也经过OSERDES来产生一路随路时钟同步数据,

DDR3联合HDMI进行图片数据的传输_第47张图片

   在最后,由于HDMI端的输出是一对差分信号,差分信号的主要作用是为了抑制抗共模噪声,一对差分对在几乎相同的布局布线上,收到外面噪声的干扰几乎是一直,但因为是差分的,当接收端接收到了差分信号时,可以很好的解决掉噪声的干扰。所以,

需要给串行化的数据添加一个OBUFDS(单端转差分)的原语

DDR3联合HDMI进行图片数据的传输_第48张图片

例化之后如下所示:

DDR3联合HDMI进行图片数据的传输_第49张图片

 Par2ser模块接口说明:

Name

输入输出

说明

clk

input

慢时钟,10bit数据随路时钟

clk_5x

input

快时钟,串行化数据随路时钟

rst_n

input

复位,低有效

i_dat_10bit

input

输入10bit数据

ser_p

output

输出1bit差分数据      

ser_n

output

 

至此,HDMI_TRANS的三个模块就完成了,先例化VGA_TIMING模块,将R,G,B像素点的值和行场同步信号传出去,在顶层需要将encode模块例化三次(R,G,B),然后10bit的数据进入par2ser模块转成单端的数据输出,同时不要忘了对时钟也需要经过par2ser模块,注意在顶层需要输出一个HDMI_OUT_En信号,高电平有效,为HDMI的使能。

  1. Modelsim仿真:

 为了能观察的确切,将主时钟的时钟频率调到10M,5倍时钟为50M,这样的话就完

在Modelsim仿真时:出现了一个未知的错误:

DDR3联合HDMI进行图片数据的传输_第50张图片

好像说是encode模块没有定义时间,功能文件是不可不用定义的呀,只有tb测试文件才需要,在网上询问了一番,找到了解决的办法:对于这个错误,可以通过一个指令来屏蔽掉。具体如下:底层模块没有是`timescale或者timeunit/timepresicion定义,在仿真加载时会出错,而不是像之前版本一样作为告警。
解决:可以使用在vsim指令后加-supress 3009屏蔽该告警。

说的是好像ModelSim的版本不同导致的。

解决完之后,仿真波形如下:

由于RGB 赋值时连续一样,所以差分的串行输出也是一样,但并不影响结果。

 

    HDMI_trans模块算是基本完成了,但是还没有和DDR3挂和关系,如果要和DDR3方面联系在一起,就需要将VGA_TIMNG的R,G,B数据的值,由DDR3模块传送过来,而DDR3的值由串口发送过来的图像数据,这样就完成了DDR3联合HDMI进行图片的显示,这就是我们下一步该做的。

DDR3联合HDMI

在完成了各个模块之后,将DDR3模块和HDMI模块统一在一起,用一个大的顶层串在一起。如下所示:

DDR3联合HDMI进行图片数据的传输_第51张图片

关于时钟方面:外部晶振过来的时钟为50M,我的方法时50先经PLL分别生成100M,125M和200M时钟DDR3时钟,在用100M的时钟去经过PLL生成65M和325M的HDMI时钟。由于模块有点多参杂在一起,我的想法是先用Modelsim进行一些简单的功能仿真,当Modelsim觉得差不多了,可以下板子试试,如若出错,可以用Modelsim联合ChipSocpe的方法,依靠抓取实际的波形,和仿真波形对比,基本上能解决很多问题。

首先是添加XDC文件,先找到之前在DDR3 IP核中绑定过的管脚,其所在位置如下  

DDR3联合HDMI进行图片数据的传输_第52张图片

   复制一份然后在其基础上添加别的管脚的约束,包括时钟复位,HDMI模块:

DDR3联合HDMI进行图片数据的传输_第53张图片

 完成后启动ModelSim仿真,观察DDR3 和HDMI之间数据交互的情况:

 DDR3联合HDMI进行图片数据的传输_第54张图片

   由上波形图可以看出,DDR3刚复位时,,外部的fifo为空,需要向DDR3_ctrl给出命令,读出数据填充,,当等到HDMI显示的第一行有效区域时,将fifo中数据读取走,送给HDMI显示,,当fifo数据小于门限值时,就会继续向DDR3读取数据,以此往复,循环起来,这样的话,HDMI和DDR3的读模块就结合起来了,上面已经完成DDR3的写,这次完成了读,就可以联合串口,发送数据到DDR3,在读取DDR3的数据到HDMI显示,这是本次工程的最终实验结果。

 

 

 

将以前用过的串口可以直接拿过来用,切记将串口参数改一下,波特率改为115200,系统时钟为125M,例化串口并添加相对应的管脚约束后,用matlab将一幅图片转化为24bit的RGB数据,然后将数据通过串口发送到DDR3中

       Matlab代码如下:,

 

DDR3联合HDMI进行图片数据的传输_第55张图片

   在下板子之后,出现了屏幕画面闪动的问题,就像平时在打游戏的时候有掉帧的情况,在Modelsim观察不出问题之后,调取ChipSocpe来抓取工程中的信号,首先观察user_rd_ctrl模块中的pixel_rgb[23:0], fifo_rd_en, fifo_rd_count[10:0], fifo_wr_count[10:0],

触发信号为fifo_rd_en的上升沿,时钟为VGA的65M时钟,

DDR3联合HDMI进行图片数据的传输_第56张图片

计数器在这个时刻为0,但是RGB却有值,说明计数器曾经到到过门限值,而打开了FIFO的读使能,但是现在却为0,中间肯定出了一些现在还未知的错误,这就需要在抓一下其他的波形来观察。

       应当注意的是,当需要观察别的波形时,需要改变chipsocpe所添加的波形时,可以将原来观察的信号截图留下来,一边和之后的波形一起观察。

 

DDR3联合HDMI进行图片数据的传输_第57张图片

对着波形仔细找了下代码,发现swap是给出写命令或者读命令的条件,结果写反了,这也是自己一时粗心大意而造成的,改过之后,抓取波形图如下:

DDR3联合HDMI进行图片数据的传输_第58张图片

 

通过串口串口发送一幅(0-255)黑白渐变的图片数据,可以帮组我们更好的找出错误所在:

DDR3联合HDMI进行图片数据的传输_第59张图片

发送完成之后,在显示器上显示如下:

DDR3联合HDMI进行图片数据的传输_第60张图片

 

 

 

 

你可能感兴趣的:(FPGA,fpga,ddr,hdmi)