FPGA输入输出信号的IOB约束方式
前言
笔者在做实验室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中。
尝试步骤
在ISE工具的Implement的property选项中,对-pr选项要选择For Inputs and Outputs选项;
修复跟输入相关的模块,对输入信号要做打拍处理,使用打拍后的数据进行内部的逻辑运算;
修改Implement的选项报错
修复后在Map阶段报错,报错具体位置在8b10b解码IP:
打开8b10b的IP网表进行分析:
其中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上。
解决方案
对于输入信号
对于输入信号而言,进来先打两拍,第一拍的数据别用,用第二拍的数据。
如果在ISE的Implement选项里可以选择For Input and Outputs
的选项的话,那后续可以不用管了,注意该选项是针对全局的设计的。如果像上文这种有个lvds接口无法放置到IOB中的话,需要考虑以下的做法。
1、使用Verilog的attribute语法
1 | (* IOB = "TRUE" *) reg [8:0] cpu_data_d1; |
2、在UCF文件里添加约束
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去查询。
结果
input、output、inout信号均正确约束到IOB中。