介绍
在 FPGA中,每个 I/O 端口在逻辑阵列(logic fabric)上都有自己的小区域。这个区域称为 IOB (输入 / Output Block(Input / Output Block)),包含支持此 I/O 端口功能所需的一切: 确保 I/O 引脚上正确电压和电流的模拟电路,以及一些特殊的逻辑单元(logic elements)。
需要指出的是,“IOB”这个术语属于 AMD (以前称为 Xilinx)使用的术语。每 FPGA 供应商使用的术语都不同。
IOB中几乎总是有 IOB 寄存器。这些寄存器是直接连接到 I/O 端口的引脚的触发器(flip-flops)。
当引脚是输入端口时,某些触发器旨在使用: 这些触发器的 D 输入接 I/O 端口的引脚。因此,此类触发器执行来自外部世界的信号的采样(sampling)。
其他触发器作为输出端口(output port)专用于引脚。这些触发器的 Q 输出连接到引脚。
IOBs 的结构因 FPGA 而异。有的 IOBs 结构复杂,功能丰富,有的 IOBs 结构简单。通常, IOB 寄存器是更大的逻辑单元(例如 SERDES)的一部分。因此,即使在描述 IOB的文档绘图中没有明确描述触发器, FPGA的 I/O 引脚仍然有可能具有 IOB 寄存器。
为什么使用 IOB 寄存器
使用 IOB 寄存器的主要动机是时序(timing): 由于这些寄存器与 I/O 端口的引脚接近,因此以这种方式实现的 clock-to-output 是无与伦比的。同样对于输入端口, IOB 寄存器最有可能实现所需的时序。
但即使很容易满足时序要求(timing requirements),也有充分的理由坚持使用 IOB 寄存器: 可重复性。否则, I/O 端口的引脚和触发器之间的时延(delay)对于 FPGA 项目的每个实现(implementation)都是不同的。这是因为工具每次都可以将触发器放在不同的位置。它们也可以更改布线时延(routing delay),只要实现了时序约束(timing constraints)。只要电路板设计正确并且与外部组件的接口经过适当规划,这不是问题。但是,当确实存在此类问题时,从一个实现到另一个时延(delay)的差异可能会造成混淆: 有什么地方不行,你在设计上修了点东西,然后问题好像就解决了。但真正有所不同的是 I/O 时序某处的细微变化。
IOB 寄存器的使用保证了在 FPGA的逻辑的开发过程中与外部元器件的电气接口不会被无意的改变。这使得在发生问题时更容易隔离问题。
请求 IOB 寄存器
可能需要明确告诉 FPGA 工具使用 IOB 寄存器。综合工具(synthesizer)通常负责执行此操作,因此这种综合属性(synthesis attribute)可以与 Vivado一起使用:
(* IOB = "TRUE" *) input the_input,
也可以在 XDC 文件中执行相同的操作:
set_property IOB true [get_ports the_input]
另一个选项是将综合属性添加到连接到输入的寄存器:
(* IOB = "TRUE" *) reg the_input_samp;
请注意, XDC 文件中的属性(attribute)可能还不够: 通常,综合工具需要复制寄存器,以便将触发器放入 IOB。当触发器的输出(output)也被 FPGA中的常规逻辑使用时,这是相关的。原因是 IOB 内部的触发器的输出只能用于端口。因此需要另一个触发器(flip-flop)来生产相同的输出,因此它可以用于逻辑阵列。在这种情况下通常需要综合属性(如上所示)。
使用 Quartus,可以将此类命令添加到 QSF 文件中:
set_instance_assignment -name FAST_INPUT_REGISTER ON -to the_input set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to the_output
每个工具都有略微不同的方法来实现这一点。
时序约束
是否有任何理由为使用 IOB 寄存器的端口编写时序约束 ?毕竟 IOB 寄存器只有一个可能的定位。是否可以得出时序将始终相同的结论,无论有无时序约束?
因此,即使在使用 IOB 寄存器时,编写时序约束也主要有两个很好的理由。
第一个原因是确保使用 IOB 寄存器: 有时,逻辑设计的更改可能会无意中阻止对所有或部分端口使用 IOBs 。发生这种情况时,工具很少抱怨。相反,不在 IOB 内部的触发器被静默使用。一个时序约束(timing constraint)可以防止这种情况: 如果时序约束只有在所有相关的触发器都在自己的 IOBs里面才能实现,那么这些触发器的驱逐就不会悄无声息了: 时序约束将因此失败。
第二个原因是这些工具可能会故意在 I/O 端口的引脚和 IOB 寄存器之间插入一个时延(尽管并非所有 FPGAs 都支持此功能)。此时延的目的是相对于 thold 改进时序(请参见 Quartus的示例)。使用时序约束可以防止这种不希望的操作,只有在没有这个额外的时延的情况下才能实现。
set_max_delay通常与时序约束搭配使用,以确保 IOB 寄存器的一致使用。如果 FPGA 工具和命令都支持“datapath_only”选项(或类似功能),那就更加方便了。
结论
应尽可能使用IOB 寄存器。 FPGA 工具可能不会主动这样做,因此可能需要付出一点努力才能实现这一目标。这种努力的回报不仅是最佳的时序,而且还包括可重复的 I/O 端口行为。