前言

笔者在做实验室FPGA项目时,遇到输入输出信号相关的约束问题。在请教老师后,总结以下内容,供以后遇到类似问题时翻阅。

对于FPGA的输入信号,我们要以异步信号来看待,输入信号进来先打拍,使用打拍后的数据。第一次打拍的FF要约束到IOB中的IFF中,第二个FF就可以放到Slice中,这样每次布局布线不会因为FF的位置不同导致时序出问题,且解决了输入信号的异步问题;

对于FPGA的输出信号,我们也要打拍输出,确保扇出为1,将其放到IOB中的OFF中。这样OFF到PAD的路径延迟固定,每次布局布线不会因为FF位置不同导致时序出问题。

对于inout信号,当该信号作为输入信号时,我们需要对其打两拍进行使用;当需要向总线上放数据时,需注意要用三态的方式放置数据assign inout_data = sel ? dout : 'bz;,且要保证sel信号是reg类型。

问题描述

输入信号没有使用IOB约束,在ISE的IOB Properties中未见输入信号部署到IFF中。

img

尝试步骤

在ISE工具的Implement的property选项中,对-pr选项要选择For Inputs and Outputs选项;

img

修复跟输入相关的模块,对输入信号要做打拍处理,使用打拍后的数据进行内部的逻辑运算;

img

修改Implement的选项报错

修复后在Map阶段报错,报错具体位置在8b10b解码IP:

img

打开8b10b的IP网表进行分析:

img

其中rx为输入的多光谱数据线,猜测为8b10b的IP网表中对ff_c0和ff_d1有布局上的约束,ff_c0和ff_d1需要pack在一起,而如果使用输入IOB的话,ff_c0需要布局在IOB中,而ff_d1无法布局在IOB中,导致报错。

所以解决方案中不能使用Implement的property。

Inout信号的处理方式

要改变总线上的数据时,使用三态控制;

assign cpu_data = (rd_latchn == 1'b0) ? cpu_rdata_mux : 16'bz;

要使用总线上的数据时,直接打拍总线上的数据(cpu_data)使用;

增加上述约束后,查看ISE报告,cpu_data仍然是OFF,输入信号没有约束到IFF上。

img

解决方案

对于输入信号

对于输入信号而言,进来先打两拍,第一拍的数据别用,用第二拍的数据。

img

如果在ISE的Implement选项里可以选择For Input and Outputs的选项的话,那后续可以不用管了,注意该选项是针对全局的设计的。如果像上文这种有个lvds接口无法放置到IOB中的话,需要考虑以下的做法。

1、使用Verilog的attribute语法

img

img

1
(* IOB = "TRUE" *) reg [8:0] cpu_data_d1;

2、在UCF文件里添加约束

img

ISE工具默认会把接口上的数据放置到IOB内。如果默认的放置方式没有起作用的话,我们这里采用的是第二种做法。

对于输出信号

保证扇出为1,在ISE的Implement选项中设置-pr选项,使用I/O Register;或者使用verilog中attribute的方式或是UCF文件中添加约束的方式;

对于inout信号

把inout信号当输入使用时,注意打两拍再使用;

把inout信号当输出时,注意采用三态写法,且sel信号需要是reg类型;

assign cpu_data = (rd_latchn == 1'b0) ? cpu_rdata_mux : 16'bz;

对于inout信号,最好在UCF文件中显式的对io信号做IOB的约束;

1
INST "u_cpu_top/cpu_data_d1*" IOB=FORCE;

ps:PR之后的信号名可以到ISE中的FPGA Editor去查询。

img

结果

input、output、inout信号均正确约束到IOB中。

img

Reference

UG625