• VGA接口时序约束


     SF-VGA模块板载VGA显示器DA转换驱动芯片AVD7123,FPGA通过OUPLLN连接器驱动ADV7123芯片产生供给VGA显示器的色彩以及同步信号。SF-CY3核心模块与SF-VGA子模块连接的系统框图如图所示。FPGA产生ADV7123的同步信号以及3组供给ADV7123内部3路并行DA的数字信号,经过ADV7123的这3组VGA色彩数字信号最终转换为0~0.7V的模拟电压送给VGA显示器。而FPGA另外会产生用于同步色彩数据的场同步信号VSYNC和行同步信号HSYNC。

             驱动VGA显示的接口,主要有以下3种信号:行同步信号HSYNC,场同步信号VSYNC和数据总线。数据的同步是靠前面两个信号来协助的。至于HSYNC和VSYNC和数据总线之间以什么样的关系进行传输,这都是相对固定的,虽然VGA收发双方没有时钟信号做同步,但我们通常会约定发送方有一个基本的时钟,VSYNC、HSYNC和数据都会按照这个时钟的节拍来确定状态。

             VGA的接口时序如图所示,场同步信号VSYNC在每帧(即送一次全屏的图像)开始的时候产生一个固定宽度的高脉冲,行同步信号HSYNC在每行开始的时候产生一个固定宽度的高脉冲,数据在某些固定的行和列交汇处有效。

                      对于ADV7123来说,在它的输入管脚上,理想的时钟和数据波形如图所示。在驱动时钟LCD_CLK信号的上升沿,将对所有的数据和控制信号进行锁存。

             我们还要进一步关心这些数据锁存时相对时钟信号的建立时间和保持时间。再来看下面这个图,这里所示意的t1其实就是数据的建立时间,而t2则是数据的保持时间。

             从对应的时序表中,我们找到了t1>0.2ns,t2>1.5ns这样的信息。

    VGA接口时序约束-中

    SF-VGA模块购买地址:http://myfpga.taobao.com/

             好,有了这些信息,我们可以分析一下这个接口的时序要求,然后对其进行约束。这个输出的信号,其实是很典型的源同步接口,它的时钟和数据都是由FPGA来驱动产生的。一般的源同步接口的寄存器模型如图所示。在我们的这个系统中,发送端是FPGA,而接收端是DA芯片ADV7123。如果传输的速率比较高,那么数据和时钟上升沿的严格对齐则要依靠PLL产生可调相位的时钟信号来保证。不过,我们这个25MHz或者50MHz的时钟通过较好的时序分析和约束后,则不必动用PLL。

             如图所示,FPGA产生的数据data_out和时钟clk_out的理想波形是时钟上升沿锁存到稳定可靠的数据。

             下面我们来探讨如何对这个设计进行约束。首先,对系统的输入时钟、PLL产生的时钟进行约束。

    create_clock -name {clk} -period 40.000 -waveform { 0.000 20.000 } [get_ports {clk}]

    derive_pll_clocks –use_tan_name

             以上的约束将会覆盖如下的时钟。

             接着,对LCD_CLK这个时钟进行约束,它需要约束为虚拟(virtul)时钟,将会被用于output port上的数据锁存时钟。因为我们这个工程可能会用到25MHz的LCD_CLK,也会用到50MHz的LCD_CLK,因此我们以频率更高的50MHz为例进行说明。系统的50MHz是PLL的clk[1]输出的,因此我们约束这个虚拟时钟如下。

    create_generated_clock -name LCD_CLK -source  [get_ports {vga_clk}]

             这个虚拟时钟将会在FPGA内部做tx_data的reg2pin时序分析时作为latch时钟。实际对于一般的reg2reg路径的分析,由于他们的launch和latch时钟都在FPGA内部,若像前面一样做过时钟的约束,那么FPGA对这些内部的时钟就已心知肚明,无需什么虚拟时钟。而对于pin2reg或reg2pin的路径分析,则一般都需要用户指定一个符合相关时钟要求的虚拟时钟。

    如图所示,有了时钟LCD_CLK,下面我们需要对数据总线进行约束,

             在这个图中,有两条关于时钟的路径延时,我们假设PLL输出的时钟是源和目的时钟的起点,以这个点为基准,时钟到达源寄存器,其路径延时为Tc2t;时钟达到ADV7123芯片的管脚,其路径延时为Tc2r,这个延时包括了时钟从PLL输出到FPGA管脚的延时以及时钟从FPGA的管脚到ADV7123的管脚的延时,后者的延时是PCB走线产生的延时。关于时钟的路径,首先是数据进入源寄存器的输入端口后,在源寄存器内部的一个延时Tco,接着是数据从源寄存器的输出端口到FPGA管脚上的延时,还有就是数据在PCB上的延时Tdpcb,最后在计算ADV7123的时序时,我们必须将数据的建立时间Tsu和保持时间Th考虑在内。

    下面我们可以简单的来分析一下数据的建立时间和保持时间应该满足怎样的关系才能保证被LCD_CLK稳定的锁存到ADV7123内。首先,我们需要提一下时钟的launch edge和latch edge的概念。如图所示,对于一个源寄存器和目的寄存器传输时钟一致的理想路径,他们的launch edge和latch edge的示意如图。我们可以这么理解,对于setup时间,launch edge是latch edge的上一个时钟节拍,latch edge通常是要去采样launch edge已经采样过的数据。而对于hold时间,launch edge是latch edge通常是同一个时钟沿,latch edge的hold时间不被冒犯,也就意味着latch edge不采样它前一拍的数据。

    对于建立时间,有:

    Launch edge + Tc2t + Tco + Tr2p +Tdpcb < latch edge + Tc2r - Tsu

             对于保持时间,有

    Launch edge + Tc2t + Tco + Tr2p +Tdpcb > latch edge + Tc2r + Th

             前面我们已经约束好了源时钟和目的时钟(虚拟时钟),因此,latch edge和launch edge是FPGA已经知道的参数。同样的,Tco和Tc2t、Tr2p、Tc2r的FPGA内部延时,也都是FPGA能够确定的,并且FPGA会通过设计者的约束,其控制这些内部的时序延时使得前面给出的两个基本公式得到满足。那么,就存在一个问题,FPGA并不知道这两个公式中FPGA外部的路径延时参数,我们下一步的数据路径约束要做的就是把这些参数告诉FPGA。Altera的TimeQuest中set output delay约束的功能就是要传递这个信息。我们下面来看看set output delay的值如何计算。

             如图所示,这是Altera的Handbook给出了set output delay的max和min值计算方法。大家可要睁大眼睛瞧好了,下面我们就要变通一下,具体问题具体分析。        

    Output delay max = dd_max + tsu_ext + (cd_altr_min - cd_ext_max)

    Output delay min = dd_min – th_ext + (cd_altr_max – cd_ext_min)

             在我们的应用中,仿照官方的分析方法,我们也同样可以得到set output delay的计算公式。

    Output delay max = Tdpcb_max + Tsu + (0 - Tc2r_max)

    Output delay min = Tdpcb_min – Th + (0 - Tc2r_min)

             关于PCB的延时,我们可以看看SF-CY3核心板以及SF-VG子板上的这部分时钟和数据走线。如图,在SF-CY3核心板上,LCD_CLK的走线约为21.4mm,而其他数据总线的延时在17.3mm~34.0mm。

             在SF-VGA子板上,我们看到LCD_CLK的走线约为23.7mm+5.0mm(匹配电阻的另一端,图中未显示数值)=28.7mm,而数据总线长度在16.0mm~28.9mm。

             结合两个板子的走线延时,我们可以计算出LCD_CLK的走线总长约为50.3mm,数据总线的总长约为33.3mm~62.9mm。根据0.17ns/25.4mm的PCB走线延时进行换算可以得到,LCD_CLK的走线延时约为0.34ns,而数据总线延时约为0.22ns~0.42ns。

             把我们的参数套进去,我们先不计算时钟偏斜(包括PCB的走线延时)那部分的参数,可以得到:

    output max delay = 0.42ns + 0.2ns = 0.62ns

    output min delay = 0.22ns – 1.5ns = - 1.28ns

             接着,我们可以对VGA的信号做如下的约束。

    set_output_delay -clock { LCD_CLK } -max 0.62 [get_ports {vga_b[0] vga_b[1] vga_b[2] vga_b[3] vga_b[4] vga_g[0] vga_g[1] vga_g[2] vga_g[3] vga_g[4] vga_g[5] vga_r[0] vga_r[1] vga_r[2] vga_r[3] vga_r[4] adv7123_blank_n}]

    set_output_delay -clock { LCD_CLK } -min -1.28 [get_ports {vga_b[0] vga_b[1] vga_b[2] vga_b[3] vga_b[4] adv7123_blank_n vga_g[0] vga_g[1] vga_g[2] vga_g[3] vga_g[4] vga_g[5] vga_r[0] vga_r[1] vga_r[2] vga_r[3] vga_r[4]}]

    VGA接口时序约束-下

             如此这般约束之后,我们可以重新编译一下系统,然后看看约束结果,我们拿到一条setup时间的分析报告。如图所示,数据路径的分析没有啥问题,我们约束的0.62ns的max set_output delay值出现在了data required path中,说明我们的约束生效了。

    17-1.jpg

     

             再来看hold报告,也是随便找一条路径。-1.28ns的min set_output_delay也已经生效了。

             即便如此,细心的读者一定没有忘记,前面的分析中我们忽略了时钟偏斜的延时值。没错,下面我们就要将它也考虑到路径延时中去。因为,我们的LCD_CLK直接就是连接到了驱动FPGA内部模块的时序产生时钟信号,所以它的偏斜其实就是PLL输出的这个时钟信号到管脚的延时值。因为这个路径其实也应该算在了reg2pin的时序路径中,如果不做约束系统不会对其进行分析的。所以,为了获得这条路径的延时信息,我们势必需要对这条路径做一下约束。我们可以先试试将这条路径用set maximum delay和set minimux delay约束在0~5ns之间(怎么?你还不了解这两条约束语句,你out了,赶紧回到SDRAM约束的章节中好好复习一下)。

    set_max_delay -to [get_ports {vga_clk}] 5.000

    set_min_delay -to [get_ports {vga_clk}] 0.000

             约束完成后,我们重新编译下系统,再来看看约束的结果。Setup时间余量最小的路径如下。

             Hold时间余量最小的路径如下。

             从这份报告中,我们获得的信息是,从PLL的clk[1]输出到LCD_CLK管脚的延时为2.116ns~2.598ns,那么给这个延时留一些余量,可以继续将他们的约束范围限制在2ns~2.7ns之间,即:

    set_max_delay -to [get_ports {vga_clk}] 2.700

    set_min_delay -to [get_ports {vga_clk}] 2.000

    加上前面我们已经计算的LCD_CLK在PCB上的走线延时,可以得到LCD_CLK的中偏斜时间约为2.44ns~3.14ns。留足余量,我们可以取LCD_CLK的时钟偏斜为2.4ns~3.2ns。其实在比较严谨的系统中,通常用于给外部芯片的时钟信号要走FPGA的pll输出专用管脚,并且也最好这个时钟信号是PLL直接输出供给的,满足这两个条件的时钟输出路径偏斜其实会限定在一个非常小的范围里,而不会像我们这个设计一样出现理论计算这么宽的时钟偏斜范围(大家领会精神就行,这个时钟速率还不算太高,不用苛刻的约束去做也就能够满足我们的系统要求)。我们这个设计实际上也是PLL直接供给的,虽然没有和数据驱动时钟没有做相位差调整。如果整个LCD_CLK连接到了FPGA的专用时钟输出管脚上,那么时钟偏斜会小很多,这也是只所以推荐走PLL专用输出时钟管脚的原因。

             接下来,我们需要将LCD_CLK的时钟偏斜值代入output max delay和output min delay的计算公式。原公式中,cd_alt参数实际上都出现在了时序分析的launch edge的时钟网络延时中(如图所示),所以我们无需再代入,直接取值为0ns即可。

    output max delay = 1ns + 0.2ns + (0ns – 3.2ns) = -2ns

    output min delay = 0ns – 1.5ns + (0ns – 2.4ns) = - 3.9ns

             重新约束后如下:

    set_output_delay -clock { LCD_CLK } -max -2.4 [get_ports {vga_b[0] vga_b[1] vga_b[2] vga_b[3] vga_b[4] vga_g[0] vga_g[1] vga_g[2] vga_g[3] vga_g[4] vga_g[5] vga_r[0] vga_r[1] vga_r[2] vga_r[3] vga_r[4] adv7123_blank_n}]

    set_output_delay -clock { LCD_CLK } -min -3.9 [get_ports {vga_b[0] vga_b[1] vga_b[2] vga_b[3] vga_b[4] adv7123_blank_n vga_g[0] vga_g[1] vga_g[2] vga_g[3] vga_g[4] vga_g[5] vga_r[0] vga_r[1] vga_r[2] vga_r[3] vga_r[4]}]

             最后,再次编译系统,查看时序报告。我们看到数据总线的Setup和Hold时间的余量都很充足,这样看来,我们的设计达到了时序收敛的目的。

             为了帮助大家进一步的理解时序的概念,这里可以找一条路径,将他们的建立时间和保持时间波形图同时拉出来,如图所示,大家便可一目了然。建立时间和保持时间会分别使用他们最坏的情况进行分析,然后得出相应的时序余量。左图的蓝色线条是时钟的latch沿,我们看在它前面9.713ns数据都是保持稳定的,完全满足ADV7123芯片datasheet上的0.2ns建立时间要求;右图的蓝色是保持时间的latch沿,它和launch沿是对齐的,我们看到它以后大约3.9ns数据才会发生变化,也完全满足ADV7123芯片datasheet上的1.5ns保持时间要求。

  • 相关阅读:
    nodejs cookie与session
    nodejs body-parser 解析post数据
    js四舍五入
    escape()、encodeURI()、encodeURIComponent()区别详解
    nodejs 搭建简易服务器
    ejs常用语法
    window.location
    response.writeHead
    response.write
    git 常用指令
  • 原文地址:https://www.cnblogs.com/lueguo/p/3374332.html
Copyright © 2020-2023  润新知