微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > FPGA和CPLD > 可提高设计性能的HDL编程风格与技巧

可提高设计性能的HDL编程风格与技巧

时间:09-25 来源:互联网 点击:
通过熟悉器件架构,选择合适的硬件平台和硅片特性,并借助配置恰当且性能优良的实现工具,设计人员就能获得较高的设计性能。不过,在提高设计性能的众多方法中最容易被忽视的也许就是为目标器件编写高效的HDL代码。本文所讨论的编程风格与技巧可提高设计性能。  

使用复位对性能的影响  

很少有哪种系统级的选择能够像复位选择那样对性能、面积和功率产生如此重要的影响。一些系统架构师规定必须使用系统全局异步复位。采用赛灵思的FPGA架构,复位的使用和类型将对代码性能产生重要影响。  

在目前所有的赛灵思FPGA架构中,查找表(LUT)单元就像逻辑、ROM/RAM或移位寄存器(SRL或移位寄存器LUT)那样是可配置的。综合工具可以根据RTL代码推断出采用某一种结构。不过,为了将LUT用作移位寄存器,代码中不能描述复位功能,因为SRL本身没有复位功能。这也意味着具有复位功能的移位寄存器代码不能获得最佳实现(移位寄存器之间需要多个触发器和相关路径),而没有复位功能的代码则可以获得快速而紧凑的实现结果(使用SRL)。  

这两种情况对面积和功率的影响更明显一些,但对性能的影响不很明显。一般而言,采用触发器生成的移位寄存器不会成为设计中的关键路径,因为寄存器之间的时序路径通常没有足够的长度成为设计中最长的路径。而资源(触发器和布线)的额外消耗会对其它设计部分的布局和布线选择产生负面影响,因而可能导致更长的布线路径。  

专用乘法器和RAM模块

乘法器通常用于DSP设计。但由于赛灵思的FPGA架构中包含有乘法专用资源,因此在许多设计中都有乘法器的应用。这些乘法器除了执行乘法操作外,还提供其它功能。同样地,实际上不管哪种应用,每个FPGA设计都会用到大小不一的RAM。  

赛灵思FPGA包含几个RAM模块,在设计中可以用作RAM、ROM、大型LUT甚至通用逻辑。使用乘法器和RAM资源可获得更加紧凑、具有更高性能的设计,不过复位选择对性能既有正面的,也有负面的影响,具体取决于使用的复位类型。RAM和乘法器模块只包含同步复位,因此如果这些功能的代码用异步复位编写,那么这些模块中的寄存器就无法使用了。这对性能的影响是非常严重的。例如,Virtex-4器件的全管线式乘法器采用异步复位设计时,频率最高只能达到200MHz,而将代码改成同步复位后,性能可提高两倍以上,频率可达500MHz。  

要从两个方面看待与RAM有关的问题。与乘法器类似,Virtex-4块RAM具有可选的输出寄存器,使用它们可以减少RAM的时钟到输出时间,提高整体设计速度。但这些寄存器只提供同步复位,不提供异步复位,因此当代码中的寄存器采用异步复位描述时就无法使用这些寄存器。  

第二个问题来自RAM被用作LUT或通用逻辑时。有时基于面积和性能方面的考虑,将配置为ROM或通用逻辑的多个LUT压缩进单个块RAM是非常有益的。这可通过人工设定结构,或以自动方式将部分逻辑设计映射到未用的RAM存储区来实现。因为块RAM具有同步复位功能,因此当使用同步复位(或没有复位)时,无需改变已经定义好的设计功能就可实现通用逻辑的映射。但当采用异步复位描述时,这就不可能实现。  

通用逻辑

异步复位对通用逻辑结构也会产生影响。由于所有的赛灵思FPGA通用寄存器都具有将复位/置位编程为异步或同步的能力,因此设计人员可能认为使用异步复位没什么不妥。但这种假设通常是错误的。如果没有使用异步复位,那么置位/复位逻辑就可以被置为同步逻辑。这样一来,就可释放额外的资源用于逻辑优化。  

为了更好地理解异步复位如何影响优化结果,我们来看看以下一些不够理想的代码例子:  

VHDL例子#1  

process (CLK, RST)  

begin  

if (RST = '1') then  

Q <= '0';  

elsif (CLK'event and CLK = '1') then  

Q <= A or (B and C and D and E);  

end if;  

end process;  

Verilog例子#1  

always @(posedge CLK, posedge RST)  

if (RESET)  

Q <= 1'b0;  

else  

Q <= A | (B & C & D & E);  

为实现这些代码,综合工具只能为数据路径选择两个LUT,因为总共有5个信号与实现上述逻辑功能相关。上述代码的一种可能性的实现方案如图1所示。  

不过,如果采用同样的代码重新编写同步复位,则能进一步减少面积、提高性能,获得如下 修正过的代码。

VHDL 例子#2  

process (CLK)  

begin  

if (CLK'event and CLK = '1') then  

if (RST = '1') then  

Q <= '0';  

else  

Q <= A or (B and C and D and E);  

end if;  

end if;  

end process;  

Verilog 例子#2  

always @(posedge CLK)  

if (RESET)  

Q <= 1'b0;  

else  

Q <= A | (B&C&D&E);  

如今的综合工具在实现这种功能时具有了更大的灵活性。上述代码的一种可能性的实现方案如图2所示。  



图1:综合工具选用2个LUT。图2:更灵活的LUT接口。

在该实现中,综合工具能够确定无论何时只要A是有效高电平,则Q总是逻辑1。其中寄存器与复位/置位一起被配置为同步操作,因此可以将置位功能自由地用作同步数据路径的一部分。这样可以减少实现该功能所必需的逻辑数量,并能减少来自前面例子的D和E信号的数据路径延时。如果代码能以更利于实现的方式编写,那么逻辑部分还可以转移到复位侧。  

以下是对这些例子的补充:  

VHDL例子#3  

process (CLK, RST)  

begin  

if (RST = '1') then  

Q <= '0';  

elsif (CLK'event and CLK = '1') then  

Q <= (F or G or H) and (A or (B and C  

and D and E));  

end if;  

end process;  

Verilog 例子#3  

always @(posedge CLK, posedge RST)  

if (RESET)  

Q <= 1'b0;  

else  

Q <= (F|G|H) & (A | (B&C&D&E));  

现在总共有8个信号与逻辑功能相关,因此实现该功能至少需要3个LUT。以上代码的一种可能性的实现方案如图3所示。



图3:综合工具选用3个LUT。

如果采用同样的代码编写同步复位,则有:  

VHDL例子#4  

process (CLK)  

begin  

if (CLK'event and CLK = '1') then  

if (RST = '1') then  

Q <= '0';  

else  

Q <= (F or G or H) and (A or (B and C  

and D and E));  

end if;  

end if;  

end process;  

Verilog 例子#4  

always @(posedge CLK)  

if (RESET)  

Q <= 1'b0;  

else  

Q <= (F|G|H) & (A | (B&C&D&E));  

以上代码的一种可能性的实现方案如图4所示。其结果不仅是能够使用更少的LUT实现同样的逻辑功能,而且能够实现更快的设计,因为减少了实际创建该功能的每个信号的逻辑级数。  



图4:选用同步复位。

虽然这些例子非常简单,但它们能够很好地阐明我们的观点,即异步复位如何将所有的同步数据信号加载到寄存器的输入端,从而导致可能更多的逻辑级数以及不够完善的实现结果。一般而言,扇入逻辑功能的信号越多,同步复位/置位在减少逻辑资源或提高设计性能方面越有效。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top