本文转载自:FPGA技术联盟微信公众号
例化(instantiation)和推译(inference)是在FPGA设计中使用元件的两种不同方法,每种方法都有其优、缺点。
元件例化直接在HDL中准确指定FPGA的库原语(primitive)或宏单元。这种方法的主要优点:一是它能完全控制所有元件特征和将要使用的FPGA资源,二是它可以使元件布局规划更加简单。例化主要用于不能被推译的复杂元件,例如 Xilinx MMCM 原语。Xilinx提供程序CoreGen对MMCM、DSP48 或 FIFO等这样的复杂元件进行例化。当综合工具无法直接推译出元件时,也需要使用直接例化。
元件推译与元件例化不同,它是指将 FPGA特定原语描述为 HDL中的逻辑电路的通用RTL程序,然后经综合工具自动转换得到。推译的优点,一是使代码易于在不同的FPGA结构之间移植,二是产生的代码更紧凑和更可读。这种方法的主要缺点是推译规则对于不同综合工具而言会有所不同。因此,同一个RTL程序可能被有的综合工具误认为存在综合错误,或者综合出来的电路不相同。Xilinx推荐用户尽可能使用推译方法。
推译寄存器
所有综合工具都能为 Xilinx的 FPGA 推译出寄存器,寄存器的时钟可以是上升沿有效或下降沿有效,也可以带有时钟使能,还可以带有同步复位端或异步复位端。推荐在 Verilog的always 块中使用非阻塞赋值(<=)用于寄存器推译。以下是几个推译寄存器的Verilog举例。
寄存器初始化
寄存器初始化的方法有许多种,下面举例-说明。
推译存储器
Xilinx的FPGA提供多种类型的嵌人式存储器,可以使用多种方法予以自动推译。
持续关注,后续将对它们进行更详细的说明。
推译移位寄存器型LUT(SRL)
Xilinx的FPGA中包含有专用的移位寄存器型LUT(SRL6或SRLI32)原语,便于实现移位寄存器。SRL原语相比通用移位寄存器来说,在使用时约束更多。前者没有复位,只能访向串行输出位。下面是自动推译SRL的一个举例。
推译IO~
顶层模块的端口如果不包含任何约束条件,则会被实现为具有默认特征的IO,这取决于具体的FPGA器件。对于Xilinx的FPGA来说,综合工具会自动推译出IBUF、OBUF、OBUFDS或其他最适合描述IO的原语。设计者可通过使用Verilog 类属( attribute)或UCF约束来指定端口特征。但要注意的是,Verilog类属与具体的综合工具有关,而UCF约束与具体的FPGA器件有关。以下是与IO有关的Verilog类属举例。
对于Synopsys Synplify软件:
xc_ padtype, xc_pullup, xc_slow, xc_fast, xc_loc, syn_useoff,
对于Xilinx XST软件:
(*IOSTANDARD = "iostandard_name”*)
(* SLOW ="ITRUEIFALSE}" *)
自动识别IOB寄存器
Xilinx FPGA中的每一个IO块含有存储单元,称之为IOB寄存器。
对于单倍数据速率或双数据速率( DDR)输出来说,可用的选项为输入寄存器和输出寄存器。使用 IOB寄存器可明显降低时钟到输入输出的数据时间,从而改善IO性能。
将寄存器放入IOB中(指使用IOB中的寄存器)并不一定可行,这么做需要遵循下面的一些规则:
1.要放入IOB的寄存器带有输出和三态使能端时,扇出必须为1;
2.具有较高扇出的寄存器将被复制,以减小寄存器扇出,改善延迟;
3.所有放人同一个IOB的寄存器必须共享时钟和复位信号。
设计者可以指定下面的UCF约束:
INST <寄存器实例名> IOB = TRUEIFALSE;
另一种方法是使用MAP" Pack I/O Registers into IOBs’属性,它适用于所有IO寄存器。在命令行MAP的选项是-pr {ilolb}。“i” 只适用于输人寄存器,“o” 只适用于输出寄存器、“b"既用于输人,又用于输出。
大多数情况下,推译IOB中的DDR寄存器需要对原语进行显式例化( explicit instantia-tion)。然而,下面的例子有时可能也会有效。
推译锁存器
锁存器可以从不完全的条件表达式中自动推译。例如当case或if语句没有覆查到所有可能的输人条件时,如果某个输出未被赋新值,则综合工具可能会自动识别出锁存器,以使得输出保持不变。Xilinx的XST软件将同时产生一个警告。锁存器推译如下所示。
在很多情况下,锁存器被无意推译出归因于设计者的编码风格不够好。有一种方法可以避免由不完全敏感信号列表推译出锁存器,即在always块中使用Verilog-2001隐式事件表达式列表@ (*)或@*。同时,要始终将默认的case 或最后的else语句赋值为“任意态”或其他默认值。
通常,推荐避免在FPGA设计中使用锁存器。持续关注,后续详细介绍了使用锁存器带来的有关问题及不同的解决办法。
三态缓冲器
下面这个例子说明如何推译出Xilinx FPGA中的三态输出缓冲器。
可以使用更复杂的表达式来推译三态缓冲器。然而,不建议将三态缓冲器和其他逻辑(如if和case语句)混合使用。以下是不被推荐的推译三态缓冲器的方法。
另一个建议是将推译出三态缓冲器的逻辑包含在设计的顶层。
持续关注,后续提供了更多在FPCA设计中使用三态缓冲器的例子。
推译复杂的算术运算块
建议不要试用推译复杂的算术运算块,例如乘法器和除法器。特殊的实现可能会有效,但它不太可能移植到不同的FPGA结构和综合工具上。Xilinx通过CoreGen实例程序支持可编程乘法器、除法器及其他算术运算核的产生。