1. Xilinx 时钟资源
xilinx 时钟资源分为两种:全局时钟和第二全局时钟。1. 全局时钟资源
Xilinx 全局时钟采用全铜工艺实现,并设计了专用时钟缓冲与驱动结构,可以到达芯片内部任何一个逻辑单元,包括CLB、I/O引脚、内嵌RAM、硬核乘法器等,而且时延和抖动都很小。对FPGA设计而言,全局时钟是最简单最可预测的时钟,最好的时钟方案是:由专用的全局时钟输入引脚驱动单个全局时钟,并用后者去控制设计中的每个触发器。全局时钟资源是专用布线资源,存在与全铜布线层上,使用全局时钟资源不影响芯片的其他布线资源,因此在可以使用全局时钟的时候尽可能使用。目前,主流芯片都集成了专用时钟资源、时钟管理模块(DCM)。以Virtex 5 为例,含有6个CMTs(Clock Management Tiles),每个CMTs包含2个DCM和一个PLL,1个DCM内包含2个DLL和一个PLL。
全局时钟资源需要通过原语(Primitives)调用,常见的时钟原语有:
IBUFG: Single-ended Input Global Clock Buffer
IBUFGDS: Differential Input Global Clock Buffer
BUFG: Global Clock Buffer
BUFGCE: Global Clock Buffer w/ Enable
DCM: DCM_ADV DCM_BASE
这些原语的使用在Language Templates都有示例,在user guide(v5对应为UG190)里也有详细说明。常用组合:
IBUFG / IBUFGDS + BUFG
最基本的时钟使用方法。当信号从全局时钟引脚输入时,无论是否为时钟信号,都必须使用IBUFG/IBUFGDS;反之,如果使用了IBUFG/IBUFGDS,则信号必须从全局时钟引脚输入,否则布局布线会报错。IBUFG/IBUFGDS的输入只与芯片的专用全局时钟输入引脚有物理连接,与普通的I/O和其他内部CLB没有物理连接,所以后面要加BUFG。LOGIC + BUFG
BUFG不仅可以驱动IBUFG的输出,还可以驱动普通信号(非时钟信号)的输出。当某个信号(时钟、使能、快速路径)的扇出非常大,要求抖动延迟最小时,可以使用BUFG驱动该信号,使该信号利用全局时钟资源。注意:普通I/O信号或片内信号进入BUFG到从BUFG输出,有大约10ns的固定时延,但是BUFG到片内所有单元的延时可以忽略为0ns。IBUFG / IBUFGDS + DCM + BUFG
更加灵活的控制时钟信号。通过DCM可以对时钟进行同步、移相、分频和倍频,而且可以使全局时钟的输出没有抖动延迟。使用全局时钟资源可以直接用原语例化,也可以使用IP核。仔细观察了一下IP核产生的源文件,发现 IP核生成的就是这3个原语的组合:
module DCM_100M(CLKIN_IN,RST_IN,CLKIN_IBUFG_OUT,CLK0_OUT,CLK2X_OUT,LOCKED_OUT);input CLKIN_IN;
input RST_IN;output CLKIN_IBUFG_OUT;output CLK0_OUT;output CLK2X_OUT;output LOCKED_OUT;wire CLKFB_IN;
wire CLKIN_IBUFG;wire CLK0_BUF;wire CLK2X_BUF;wire GND_BIT;wire [6:0] GND_BUS_7;wire [15:0] GND_BUS_16;assign GND_BIT = 0;
assign GND_BUS_7 = 7'b0000000;assign GND_BUS_16 = 16'b0000000000000000;assign CLKIN_IBUFG_OUT = CLKIN_IBUFG;assign CLK0_OUT = CLKFB_IN;IBUFG CLKIN_IBUFG_INST (.I(CLKIN_IN),.O(CLKIN_IBUFG));BUFG CLK0_BUFG_INST (.I(CLK0_BUF),.O(CLKFB_IN));BUFG CLK2X_BUFG_INST (.I(CLK2X_BUF),.O(CLK2X_OUT));DCM_ADV #( .CLK_FEEDBACK("1X"), .CLKDV_DIVIDE(2.0), .CLKFX_DIVIDE(1),.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2("FALSE"),.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT("NONE"),.DCM_AUTOCALIBRATION("TRUE"), .DCM_PERFORMANCE_MODE("MAX_SPEED"),.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), .DFS_FREQUENCY_MODE("LOW"),.DLL_FREQUENCY_MODE("LOW"), .DUTY_CYCLE_CORRECTION("TRUE"),.FACTORY_JF(16'hF0F0), .PHASE_SHIFT(0), .STARTUP_WAIT("FALSE"),.SIM_DEVICE("VIRTEX5") ) DCM_ADV_INST (.CLKFB(CLKFB_IN),.CLKIN(CLKIN_IBUFG),.DADDR(GND_BUS_7[6:0]),.DCLK(GND_BIT),.DEN(GND_BIT),.DI(GND_BUS_16[15:0]),.DWE(GND_BIT),.PSCLK(GND_BIT),.PSEN(GND_BIT),.PSINCDEC(GND_BIT),.RST(RST_IN),.CLKDV(),.CLKFX(),.CLKFX180(),.CLK0(CLK0_BUF),.CLK2X(CLK2X_BUF),.CLK2X180(),.CLK90(),.CLK180(),.CLK270(),.DO(),.DRDY(),.LOCKED(LOCKED_OUT),.PSDONE());endmodule时钟从CLKIN_IN输入,经过IBUFG,输出为CLKIN_IBUFG,然后输入到DCM_ADV,输出为CLK0_BUF和CLK2X_BUF,CLK0_BUF经过BUFG得到CLKFB_IN,一方面反馈到DCM的,另一方面也从CLK0_OUT输出;CLK2X_BUF则经过BUFG后直接输出为CLK2X_OUT。
LOGIC + DCM + BUFG
和前一种的区别在于DCM的输入是从内部输入还是外部输入。从外部输入则用IBUFG,保证时钟信号由芯片引脚输入;从内部输入则可以选择内部逻辑的任意信号,在FPGA内部是没有差分信号的,所有内部时钟信号都是单端信号。Google到一篇不错的博客:如何正确使用FPGA的时钟资源
2. 第二全局时钟资源
第二全局时钟资源属于长线资源,长度和驱动能力仅次于全局时钟资源,也可以驱动芯片内部的任何一个逻辑,抖动和延时仅次于全局时钟。在设计中,一般将高频率、高扇出的时钟使能信号以及高速路径上的关键信号指定为全局第二时钟信号。使用全局时钟资源并不占用逻辑资源,也不影响其他布线资源;第二时钟资源占用的是芯片内部的资源,占用部分逻辑资源,各个部分的布线会相互影响,所以建议在设计中逻辑占用资源不超过70%时使用。使用第二时钟资源:可以在约束编辑器中的专用约束Misc选项中,指定所选信号使用低抖动延迟资源“Low Skew”来指定,也可以在ucf文件中添加“USELOWSKEWLINES"约束命令。比如:
NET "s1" USELOWSKEWLINES;2. ISE时序分析器
单击Design Summary中的Static Timing就可以启动时序分析器(Timing Analyzer)。在综合、布局布线阶段ISE就会估算时延,给出大概的时延和所能达到的最大时钟频率,经过PAR后,在Static Timing中给出的是准确的时延,给出的时序报告可以帮助我们找到关键路径,然后针对其进行优化,提高系统的时钟频率。造成时序性能差的原因很多,主要分为3种:
1. 布局太差
一般和代码本身没有关系。解决方案:只能从软件自身的布局算法考虑(调整布局的努力程度)或者使用高端芯片2. 逻辑级数太多
逻辑级数越多,资源的利用率越高,但是对工作频率的影响也越大。解决方案:1.使用流水线技术;2.如果是多周期路径,添加多周期约束;3.良好的编码习惯,不要过多嵌套if-else,尽量使用case代替if语句。3. 信号扇出过高
高扇出会造成信号传输路径过长,从而降低时序性能。解决方案:1.逻辑复制;2.区域约束,想过逻辑放置在一起。4. 不要同时使用双边沿触发
FPGA的底层工艺都是单向的同步电路,所以本身不支持统一信号的爽边沿触发,ISE在实际处理的时候,会自动将该信号2倍频,然后利用第一个沿处理上升沿,第二个沿处理下降沿。这样在分析时序时,自动把约束升级为ucf文件中的两倍。5. Xilinx最优时序解决方案
I/O约束根据Xilinx器件的特点,控制信号置于器件的顶部或底部,且垂直布置;数据总线的I/O置于器件的左右两侧,且水平布置,这样可以最大程度的利用芯片底层结构。ISE实现工具
ISE中的工具具备不同的努力程度,直接使用最高级别的可以提高时序性能,但是会耗费很多时间,所以应该逐步调整努力程度。第一遍使用默认的参数选项,如果不满足再调整综合、映射、布局布线的参数