FPGA基础资源之IOB的应用

FPGA基础资源之IOB的应用

 

1.应用背景

在我们做时序约束时,有时候需要对FPGA驱动的外围器件进行input_delay/output_delay进行约束。不知道,大家有没有被以下这种类似的现象折磨过。你好不容易约束通过的工程,仅改动了个标点符号,或者其他不相关模块改动一丢丢。编译出来的工程时序就不过了。

碰到上述的现象,我觉得可能的原因有以下几种:1.时钟频率确实已经到极限了。2.器件的资源利用率已经达到瓶颈,软件已经尽力去优化了。

针对原因2,除了处理好跨时钟域等问题以外,我们通常会从整体上,去评估模块的布局是否合理,是否还有值得优化的空间。又或者针对关键的路径/模块,利用Pb_lock等技术,划分出某一区域,有限满足关键模块的布线等等手段。本文要介绍的IOB,针对外围器件input/output delay约束,有很好的提升效果。

 

2.什么是IOB

xilinx FPGA的基本资源一般包括可编程IO,IOB,CLB,BRAM,DCM,DSP等资源,某些器件还会集成一些特殊的硬核,例如GTMIG等。其中IOB就是input/output buffer。可编程IO的作用就是完成信号的采集和输出,引脚可以配置支持不同电气特性,上拉下拉或三态,差分或单端IOB与附近的idelayodelayilogicologic和可编程IO等资源,共同组成FPGAIO_Bank

 

 

 

 

3.IOB的应用以及注意事项

为了保证FPGA输入输出接口的时序,一般会要求将输入管脚首先打一拍再使用,输出接口也要打一拍再输出FPGA。这样做的目的是为了让这打一拍的寄存器约束到IOB上,从而使得每一次编译输入或者输出的时序不会发生改变。这是因为,IOB是位于IO附近的寄存器,是FPGA上距离IO最近的寄存器,并且位置固定。当你输入或者输出采用了IOB约束,那么就可以保证从IO到达寄存器或者从寄存器到达IO之间的走线延迟最短、最大限度保证时序满足要求,同时由于IO的位置是固定的,所以每一次编译都不会造成输入或者输出的时序发生改变。

       IOB的应用一般有两种,一种是在代码中添加约束,另一种可以在约束文件xdc中添加。

  • 在约束文件中加入下面约束:

set_property  IOB true [get_ports {port_name}]

  • 直接在代码中加约束,在寄存器前加入下面约束,需要注意的是,对于输入IOB约束,这里的寄存器是第一级寄存器,对于输出IOB约束,这里的寄存器是最后一级寄存器,且寄存器输出不能再作为组合逻辑输入。

(* IOB = "true" *) reg  O_data;

 

4.实例说明

下面的实例,分别对输入寄存器[3:0]reg_a,以及输出寄存器reg_c1进行IOB约束,停过对比并行的寄存器[3:0]reg_b和reg_d1,从而能发现他们之间的差异。

下面是映射到device的情况:

我们以输出的寄存器reg_c1和reg_d1为例,从下图能明显能看出,增加了IOB约束的reg_c1,是被映射到device靠近pad的Ologic里面的IOB寄存器中,而没添加IOB约束的输出寄存器reg_d1,是直接从某个CLB 中其中一个slice里的寄存器中。当逻辑代码改变,很有可能下一次编译,reg_d1映射的位置会发生改变,从而导致时序路径发生变化。

同样,输入的寄存器也是一个道理,这里就不展开论述了。

附代码:

module IOB_test(

    input [3:0]a,b,

    output c,d,

    input clk,

    input rst

    );

  //-------set input reg IOB -------  

(* IOB = "true" *)    reg [3:0]   reg_a;

    reg [3:0]   reg_b;

    always@(posedge clk)

    begin

        if(rst)

            begin

            reg_a   <= 4'd0;

            reg_b   <= 4'd0;

            end

       else

            begin

            reg_a   <= a;

            reg_b   <= b;

            end         

    end

    reg reg_c = 1'd0; 

    reg reg_d = 1'd0;

 always@(posedge clk)

 begin

    if(rst)

        begin

            reg_c <= 1'd0;

            reg_d <= 1'd0;  

        end

    else

        begin

        if ( reg_a == 4'd1 && reg_b == 4'd2 )

            begin

            reg_c <= reg_c +  1'd1;

            reg_d <= reg_d +  1'd1;

            end

        else

            ;

        end

 end

 //-------set output reg IOB -------

(* IOB = "true" *)  reg reg_c1 = 1'd0; 

    reg reg_d1 = 1'd0;

    always@(posedge clk)

    begin

        reg_c1 <= reg_c;

        reg_d1<= reg_d;

    end

        assign c = reg_c1;

        assign d = reg_d1;

endmodule

  • 18
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值