一.功能:把10bit数据转化为串行数据在一个时钟周期全部输出(先输出高位,再输出低位)
二.框图
二.思路
对于TMDS编码器,在每一个输入时钟周期,输入一次数据到TMDS编码器进行处理,然后又串行发送器输出串行数据。
为了在一个周期内输出10位数据,我们设置输出时钟频率是输入时钟频率的5倍。再利用ODDR(ddio_out)实现双沿输出,可以达到在一个输入周期内输出10位串行数据的效果。
输入输出时钟频率的关系可以用PLL来实现(5倍),ODDR在XILINX中是用原语实现,在quartus中可以调用IP核实现。
在quartus中包括altddio_bidir(双向双速率 IO)、altddio_in(输入型双速率 IO)、altddio_out (输出型双速率 IO)等IP核,在 MegaWizard Plug-In Manager 的搜索框中输入 ddio 搜索即可。(双沿采样模块已经在千兆以太网详细学习了,这里不再介绍)
三.使用的技巧
由于使用了双沿采样ddio_out模块,要实现10bit到1bit,得先把10bit转化为2bit,2bit双沿采样为1bit。(如果不用双沿采样,时钟频率就需要10倍,要求较高)
为了实现把10bit转化为2bit,我设计了一个2bit寄存器,每个周期把10bit中的2bit放进来采样。
为了实现这个目的,在代码中体现为:用1个模10计数器,每次加2,分别为:0,2,4,6,8。每次取两位,得到[1:0],[3:2]......[9:8]。同时使用了变量来取寄存器的内存值,变量的代码已经在前面介绍过了。
//定义模10移位计数器,用来分5次输出10bit的数据 reg [3:0]mod10_cnt ; always @(posedge clk_5f) if(!resetn) mod10_cnt <= 0 ; else if (mod10_cnt >= 'd8 ) mod10_cnt <= 0 ; else mod10_cnt <= mod10_cnt + 2 ; //定义两bit的寄存器,用来移存10bit数据,输出给oddr。 reg [1:0]TMDS_2bit ; always @( posedge clk_5f ) if(!resetn) TMDS_2bit <= 0 ; else TMDS_2bit <= TMDS_code[('d8 - mod10_cnt)+:2] ;//发送顺序:[9:8]-->[1:0].TMDS_2bit[1]为高位。
四.遇到的问题:
1.quartus不能在IP核的PLL文件夹中直接调用PLL(灰色,无法选中,一说是芯片IV代不可以,V及以上可以),需要在I/O文件夹中选择ALTPLL。ALTPLL复位信号为高电平有效,无法修改,使用时可以直接接0。
2.quartus调用IP核:
①创建IP核并调用:MegaWizard Plug-In Manager找到对应IP核,配置,输出时勾选inst.v文件,就可以复制出来例化了。
②IP核使用技巧:
对于Quartus 中的很多 IP,我们都是可以直接使用其名加重定义参数的方式来调用,无需通过MegaWizard Plug-In Manager调用。使用这种写法的好处在于针对不同系列,不同版本的Quaruts 软件,无需通过MegaWizard Plug-In Manager 创建 IP 核,当软件编译到该部分代码时会从软件自带的底层 IP 库中自动的例化DDIO 功能,非常的方便,把工程文件移植到别的电脑使用时不需要根据设定再重新创建IP(在VIVADO中需要,比较麻烦)
范围:如ddio, fifo、pll、双口 ram 等都可以使用该方法。 需要说明的是,该方法仅为开发者的技巧性应用,目前笔者也没找到厂家提供的这种方法的使用说明文档,仅限经验丰富的工程师根据自己的能力使用。(摘自小梅哥教程)
具体操作:从创建好的 IP 核的 xx.v 文件中 把模块xx xx() 和 defpara参数 一起 copy 出来的。要注意你创建的IP和核中,它的端口连线有些是模块内部定义的变量,你需要进行一定的修改。如下面的PLL,创建好的IP核如下:
圈出来的地方是xx.v文件的内部变量,我们例化时需要自己创建功能相同的变量,连接上。
需要修改IP核参数时,如PLL输入时钟频率,可以直接在defpara那里修改,不需要重新去定义IP核再例化。
创建完以后,就可以在你的顶层文件直接调用了。
3.差分信号
HDMI.DVI使用差分信号传输数据。
差分信号即是用两个线代替一根线来传输信号,增加了物理复杂度,好处是什么?
用一根导线传输信号,信息隐藏在对地电平中,如1.2V,xxV之类的,都是对地0V的相对电压。
用两根导线传输差分信号,信息隐藏在这两个差分信号的相对电压之中,由于差分信号幅度相同,相位相反。在计算机中又是用0/1表示,所以0/1为一对差分信号。一根导线表示的1,在差分信号中表示为 1 - 0 = 1 ;一根导线表示的 0,在差分信号中表示为 0 - 1 = -1 。
好处:
①屏蔽电磁干扰,电磁干扰对两个差分信号的影响相同,所以不会改变他们的差值,从而不会影响信息的传递。
②单导线依赖虚地的稳定性,双导线不依赖,更可靠。
4调用modelsim仿真时出现modelsim is existing with code 7 。
解决方法:跟据此链接建立新连接:【解决】计算机用户名是中文名导致软件安装失败!_Antrn的博客-CSDN博客_电脑用户名是中文
5.为了增强时序性,让某些信号延迟1ns再输出,可以避免多个信号同时跳变时,取了跳变后的状态。
语法如下:
assign #1 a = b;(assign必须是 #x 在前)
always@(*)begin a = #1 b ;end ;
always@(*)begin a <= #1 b ;end ;
always@(*)begin #1 a <= b ;end ;