xilinx原语介绍及仿真——IDDR

文章来源:数字站

IDDR的主要功能就是将输入的双沿信号转换为单沿信号输出给FPGA内部逻辑进行使用,IDDR位于通1中的ILOGICE部分,在讲解IDDR使用前,需要了解ILOGICE的结构及功能。

图1 7系列IO模块.JPG

ILOGICE

ILOGICE位于IOB旁边,ILOGICE块包含同步元件,用于在数据通过IOB进入FPGA时捕获数据。7系列芯片中ILOGICE可能是ILOGICE2(HP I/O bank)或ILOGICE3(HR I/O bank)。

对比图2、图3知,ILOGICE2和ILOGICE3唯一区别是ILOGICE3有零保持延迟元件(ZHOLD自动与内部时钟分配延迟相匹配,并且在使用时确保焊盘到焊盘的保持时间为零),ILOGICE3模块在输入上支持可选的静态未补偿零保持 (ZHOLD) 延迟线,以补偿时钟插入延迟。

图2 ILOGICE2 框图图片.JPG

图3 ILOGICE3框图.JPG

ZHOLD默认启用,除非时钟源是MMCM或PLL,或者在Xilinx设计约束 (XDC)中设置了IOBDELAY属性。

其他功能相同,所以本文将ILOGICE2和ILOGICE3统一称为ILOGICE。

注意ILOGICE不是基本元件,用户不能通过代码去对ILOGICE进行例化。但ILOGICE包含用户实例化的元件,例如布局和布线后的输入触发器 (IFD) 或输入DDR元件(IDDR)。

如图4所示,输入信号D,可以通过红色信号线进行传输,然后直接输出该模块,就是当FPGA没有调用IDDR、IFD这些原语时,FPGA外部信号通过管脚进入后,需要通过ILOGICE单元,但是又不使用IDDR这些功能器件,那就会通过红色路径直接穿过ILOGICE单元,到达FPGA内部逻辑。

图片图4 ILOGICE2 框图.JPG

当需要使用IDDR这些转换功能时,通过绿色的信号传输到下面器件的输入端D,这个器件可以配置为锁存器(latch)、触发器(FF)、双沿转单沿器件(DDR),而CE1是时钟使能信号,高电平有效,不连接时默认为高电平。

当不使用IDDR功能时,在使用IDDR原语后,只需要添加(IOB == “TRUE”)原语,就可以使用ILOGICE中的触发器(FF)的功能。这个触发器相比FPGA内部触发器更靠近FPGA管脚,使得建立时间余量更大,更有利于时序。

Q1和Q2是输出端口,S/R是复位、置位端口,在调用原语是可以对同步、异步触发进行设置。此框图中S/R的是一根线,但IDDR的原语将S和R分开为两个端口,使用时不能让S、R同时有效。

IDDR模式

IDDR的功能就是将双沿采样的数据转换为单沿数据传输给FPGA内部进行使用。FPGA内部的D触发器一般都是在时钟上升沿去采集输出数据,这种方式被称为SDR,与SDRAM传输数据类似。在SDRAM之后,为了提高数据传输速率,推出了DDR,在时钟的上升沿和下降沿都能传输数据,同样时钟频率下,速率可以提升一倍,这种传输数据的方式就是双沿传输,这种方式一般都只存在接口部分,内部电路采用双沿会比较麻烦,所以会转换为单沿进行处理,FPGA调用IDDR原语即可实现。

如图5是IDDR的原语框图,将图3中的控制信号引出。

图5 IDDR原语框图.JPG

IDDR原语的输入输出信号的含义如表1所示。

表1 IDDR原语的端口信号.JPG

IDDR 原语支持三种操作模式:OPPOSITE_EDGE模式、SAME_EDGE模式、SAME_EDGE_PIPELINED模式。

OPPOSITE_EDGE模式

如图6是该模式对应的时序图,C是时钟信号,CE是时钟使能信号,D是输入数据,有图可知D在C的上升沿和下降沿都有数据变化的,即双沿传输。

图6 OPPOSITE_EDGE模式下的IDDR时序.JPG

Q1和Q2是输出数据,Q1在时钟上升沿输出在时钟上升沿采集到的数据,而Q2在时钟下降沿数据发生变化,用于输出在时钟下降沿时采集到的数据,后续逻辑只需要在时钟上升沿同时采集Q1和Q2的数据进行拼接就可以得到D在上升沿和下降沿传输的数据了。

SAME_EDGE模式

如图7所示,输入信号与上个模式时序图一致,SAME_EDGE模式与OPPOSITE_EDGE模式的区别在于,SAME_EDGE模式的Q1和Q2只会在时钟C的上升沿输出数据。

图7 SAME_EDGE模式下的IDDR时序.JPG

图6中在第一个时钟上升沿之后,Q1输出采集到的D0A,由于此时还没有经过下降沿,Q1输出无效数据。在第一个下降沿,Q2采集D的数据,在第二个时钟上升沿之后,Q1输出采集第二个时钟上升沿采集的数据D2A,Q2输出第一个时钟下降沿采集的数据D1A。

上述两种方式都不是最常用的模式,最常用的数据采集模式是SAME_EDGE_PIPELINED模式,与SAME_EDGE模式类似,只是将Q1输出数据延迟一个时钟周期,让Q1和Q2的第一个数据至最后一个数据进行对齐,方便后续操作,代价是Q1输出数据延迟了一个时钟周期。

SAME_EDGE_PIPELINED模式

图8显示了使用SAME_EDGE_PIPELINED模式的IDDR的时序图,Q1和Q2同时提供给FPGA逻辑,更方便用户使用。

图8 SAME_EDGE_PIPELINED模式下的IDDR时序.JPG

IDDR原语

IDDR原语的几个参数如表2所示:

表2 IDDR原语的参数含义.JPG

一般把DDR_CLK_EDGE参数设置为SAME_EDGE_PIPELINED模式即可,其余参数可以不进行设置,保持默认即可。

在vivado中获取原语模板的方法如图9所示,在Tools选项卡下点击Language Templates。

图9 vivado获取原语模板.JPG

然后如图10所示操作,再搜索框搜索想要的原语模块名,此处为IDDR,然后选择对应器件下的对应原语,此处使用zynq7020,即A7。5处就是IDDR原语对应的例化模板,赋值到代码中使用即可。

图10 IDDR原语模板.JPG

通过下面一段代码SAME_EDGE_PIPELINED模式进行仿真,TestBetch文件也放在下面,在Vivado中创建工程进行仿真。

IDDR原语模板:

IDDR #(      .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE"                                       //    or "SAME_EDGE_PIPELINED"       .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1      .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1      .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"    ) IDDR_inst (      .Q1(Q1), // 1-bit output for positive edge of clock      .Q2(Q2), // 1-bit output for negative edge of clock      .C(C),   // 1-bit clock input      .CE(CE), // 1-bit clock enable input      .D(D),   // 1-bit DDR data input      .R(R),   // 1-bit reset      .S(S)    // 1-bit set   );

设计文件代码:

module iddr_ctrl(   input       clk      ,//系统时钟信号;   input       rst      ,//系统复位信号,高电平有效;
   input       clk_en   ,//时钟使能信号;   input       din      ,//输入数据;   output      dout1    ,//输出数据   output      dout2    );    reg         clk_en_r ;   //(* IOB = "TRUE" *)reg clk_en_r ;//将clk_en_r放在ILOGICE中;
   //将clk_en打拍,用于验证IOB原语是否有效;   always@(posedge clk)begin      clk_en_r <= clk_en;   end
   //例化IDDR原语   IDDR #(      .DDR_CLK_EDGE  ("SAME_EDGE_PIPELINED"  ),// "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"       .INIT_Q1       (1'b0                   ),// Initial value of Q1: 1'b0 or 1'b1      .INIT_Q2       (1'b0                   ),// Initial value of Q2: 1'b0 or 1'b1      .SRTYPE        ("SYNC"                 ) // Set/Reset type: "SYNC" or "ASYNC"    )    IDDR_inst (      .Q1   (dout1   ),// 1-bit output for positive edge of clock      .Q2   (dout2   ),// 1-bit output for negative edge of clock      .C    (clk     ),// 1-bit clock input      .CE   (clk_en_r),// 1-bit clock enable input      .D    (din     ),// 1-bit DDR data input      .R    (rst     ),// 1-bit reset      .S    (1'b0    ) // 1-bit set   );
endmodule

TestBench代码如下:

`timescale 1 ns/1 nsmodule test();    parameter  CYCLE    =   10      ;//系统时钟周期,单位ns,默认10ns;    parameter  RST_TIME  =   10      ;//系统复位持续时间,默认10个系统时钟周期;
    reg                      clk     ;//系统时钟,默认100MHz;    reg                      rst     ;//系统复位,默认高电平有效;    reg                         clk_en  ;    reg                         din     ;
    wire                        dout1   ;    wire                        dout2   ;
    iddr_ctrl  u_iddr_ctrl (        .clk    ( clk       ),        .rst    ( rst       ),        .clk_en ( clk_en    ),        .din    ( din       ),        .dout1  ( dout1     ),        .dout2  ( dout2     )    );
    //生成周期为CYCLE数值的系统时钟;    initial begin        clk = 1;        forever #(CYCLE/2) clk = ~clk;    end
    //生成复位信号;    initial begin        rst = 0;        #2;        rst = 1;//开始时复位10个时钟;        #(RST_TIME*CYCLE);        rst = 0;        repeat(120) @(posedge clk);        $stop;//停止仿真;    end
    initial begin        #1;        din = 1'b0;clk_en = 1'b0;        #(CYCLE*(10+RST_TIME));        clk_en = 1'b1;        #(CYCLE);        repeat(100)begin//产生100个双沿时钟数据。            #(CYCLE/2);            din = ({$random} % 2);            #(CYCLE/2);            din = ({$random} % 2);        end        #(CYCLE);        clk_en = 1'b0;    end

endmodule

仿真结果如图11所示,在时钟使能clk_en拉高后,输入信号din拉高后,在时钟的第二上升沿时,dout1和dout2同时输出高电平,后续波形也能与图8对应上,仿真通过。

图11 SAME_EDGE_PIPELINED模式仿真结果.JPG

将IDDR的模式进行修改,代码如下,对IDDR的OPPOSITE_EDGE模式进行仿真。

module iddr_ctrl(   input       clk      ,//系统时钟信号;   input       rst      ,//系统复位信号,高电平有效;
   input       clk_en   ,//时钟使能信号;   input       din      ,//输入数据;   output      dout1    ,//输出数据   output      dout2    );    reg         clk_en_r ;   //(* IOB = "TRUE" *)reg clk_en_r ;//将clk_en_r放在ILOGICE中;
   //将clk_en打拍,用于验证IOB原语是否有效;   always@(posedge clk)begin      clk_en_r <= clk_en;   end
   //例化IDDR原语   IDDR #(      .DDR_CLK_EDGE  ("OPPOSITE_EDGE"  ),// "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"       .INIT_Q1       (1'b0                   ),// Initial value of Q1: 1'b0 or 1'b1      .INIT_Q2       (1'b0                   ),// Initial value of Q2: 1'b0 or 1'b1      .SRTYPE        ("SYNC"                 ) // Set/Reset type: "SYNC" or "ASYNC"    )    IDDR_inst (      .Q1   (dout1   ),// 1-bit output for positive edge of clock      .Q2   (dout2   ),// 1-bit output for negative edge of clock      .C    (clk     ),// 1-bit clock input      .CE   (clk_en_r),// 1-bit clock enable input      .D    (din     ),// 1-bit DDR data input      .R    (rst     ),// 1-bit reset      .S    (1'b0    ) // 1-bit set   );
endmodule

仿真结果如图12所示,在din信号变化后,dout1在时钟上升沿输出采集到的数据,dout2在时钟下降沿输出在时钟下降沿采集到的数据,与时序图6对应,仿真通过。

图12 OPPOSITE_EDGE模式仿真结果.JPG

同样TestBetch文件不变,只需要将IDDR的模式变为SAME_EDGE模式,就可以对该模式进行仿真,对应代码如下。

module iddr_ctrl(   input       clk      ,//系统时钟信号;   input       rst      ,//系统复位信号,高电平有效;
   input       clk_en   ,//时钟使能信号;   input       din      ,//输入数据;   output      dout1    ,//输出数据   output      dout2    );    reg         clk_en_r ;   //(* IOB = "TRUE" *)reg clk_en_r ;//将clk_en_r放在ILOGICE中;
   //将clk_en打拍,用于验证IOB原语是否有效;   always@(posedge clk)begin      clk_en_r <= clk_en;   end
   //例化IDDR原语   IDDR #(      .DDR_CLK_EDGE  ("SAME_EDGE"  ),// "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"       .INIT_Q1       (1'b0                   ),// Initial value of Q1: 1'b0 or 1'b1      .INIT_Q2       (1'b0                   ),// Initial value of Q2: 1'b0 or 1'b1      .SRTYPE        ("SYNC"                 ) // Set/Reset type: "SYNC" or "ASYNC"    )    IDDR_inst (      .Q1   (dout1   ),// 1-bit output for positive edge of clock      .Q2   (dout2   ),// 1-bit output for negative edge of clock      .C    (clk     ),// 1-bit clock input      .CE   (clk_en_r),// 1-bit clock enable input      .D    (din     ),// 1-bit DDR data input      .R    (rst     ),// 1-bit reset      .S    (1'b0    ) // 1-bit set   );
endmodule

仿真结果如图13所示,在din信号变化后,dout1在时钟上升沿输出采集到的数据,dout2在时钟上升沿输出其在时钟下降沿采集到的数据,与时序图7对应,仿真通过。

图13 SAME_EDGE模式仿真结果.JPG

查看硬件走线

   上述仿真结束后,对工程进行综合、分配管脚、然后实现,在实现后,如图14所示,点击Open Implementation Design,然后选择Defaout Layout,放大查看走线。

图14 查看布局布线后线路.JPG

Vivado默认是将走线关闭的,点击图15中方框部分,就可以打开走线视图,查看更加详细的走线,以及小的结构单元。

图15 打开走线.JPG

       图16就是布局布线后的一个走线,图中Y143是din输入所在管脚,灰色部分就是IOB,经过白线先到IDDR,然后经过dout1输出FPGA。

图16 din到dout1的走线.JPG

       图17是将din所在管脚放大,din的管脚在IOB33,信号从金属管脚PAD进入芯片,然后经过了一个IBUF,通过I端口输出。由图也可以知道IOB可以实现管脚的上拉(PAD左边有类似波浪线的上拉电阻)和下拉,有IBUF、OBUF(IBUF左边那个)。

图17 IOB模块.JPG

上图中输出的信号经过一段距离传输,传输到图18所示的ILOGICE2的IDDR输入端口D了,由图18可知同一ILOGICE2(因为IDDR和IDELAYE2位置编号均为X1Y144)的IDDR和IDELAYE2分布在上下位置,此处没有使用IDELAYE2,信号就直接到达了IDDR。

图18 IDDR结构图.JPG

图18是din的信号走向,经过了IDDR,那如果不使用IDDR的信号,是否如之前所说,会直接经过IDDR上面的组合路径输出呢?

我们可以通过查看clk_en信号的流向得到答案,这个信号没有经过IDDR,对应走线如下图19所示,结果与前文分析一致,所以输入信号都需要经过ILOGICE,没有使用ILOGICE内部IDDR、寄存器功能的信号,通过顶部组合逻辑电路输出。

图19 clk_en信号流向.JPG

最后图20是一个输出信号的管脚信号走向,目的是确定IOB单元内IBUF对面的就是OBUF结构,IBUF和OBUF是vivado自动对输入输出信号添加的。

图20 输出信号走向.JPG

ILOGICE的寄存器(IFD)使用

前文讲了如果不使用ILOGICE的IDDR功能,可以将通过使用原语,将ILOGICE配置成触发器,这个触发器相比FPGA内部逻辑的触发器,更靠近FPGA管脚,使接口信号更有利于满足建立时间要求。

clk_en信号没有使用IDDR功能,那么此处在clk_en进入FPGA后,使用触发器打一拍后,先不做任何限制(去掉第10行代码注释,11行代码注释掉),然后对工程进行综合,去查看布线后的走线图,寄存器分布位置。

在vivado综合编译之后,如图21是clk_en走线图,信号从端口输入,然后经过ILOGICE的组合逻辑部分,然后进入到FPGA内部CLB的一个D触发器中。图片

图21 clk_en信号走线.JPG

经图21中三个部分放大,如图22所示,比较平常的结果。

图22 将图21的IOB、ILOGICE、D触发器放大图片.JPG

如果在clk_en_r定义处添加IOB原语(将上述代码第10行注释,第11行注释取消),在vivado综合编译之后,走线如图23所示,clk_en信号在经过ILOGICE时,并没有像图21一样,从组合逻辑部分直接输出,而是经过了下面部分。图片

图23 clk_en信号的走线图.JPG

将图23中ILOGICE部分进行放大,如图24所示,clk_en_r触发器就位于ILOGICE中IDDR位置,只是目前的功能是D触发器。

图24 放大clk_en信号的ILOGICE.JPG

对上述代码进行仿真,查看clk_en是否被延迟一个时钟周期,仿真结果如图25所示,clk_en_r相对clk_en延迟一个时钟周期,仿真正确。

图片图片图25 仿真截图.JPG

很明显图23中clk_en从PAD到clk_en_r触发器的路径,相比图21中的路径会短很多,并且走线都是固定的,clk_en_r的位置也是固定的,不能进行随意更换,在ADC采集数据时,可以将触发器放入ILOGICE减小延时。

总结本文就几点:

第一:了解ILOGICE的结构及功能,能够实现IDDR和触发器功能。

第二:熟悉IDDR的三种模式,常用的是SAME_EDGE_PIPELINED模式,并对三种模式依次仿真,通过查看走线图,更加详细了解IOB和ILOGICE的结构。

第三:通过使用原语,将触发器放入ILOGICE中,减少从FPGA管脚到触发器的路径。

最后需要此工程文件的用户,在公众号后台回复“IDDR”(不包括引号)即可,工程里只有一个设计文件,因为三个文件只需要修改IDDR的工作模式即可,IDDR会在千兆网接口中使用。

最新文章

最新文章