越来越多的关键应用都对精确性和计算延迟时间有严格的要求。FPGA的灵活性和性能使得它们广泛应用在工业、科学、军事以及其他的许多应用场合中,来计算复杂的数学问题或者传递函数,有许多算法,比如CORDIC算法,可以用来做为超越函数的计算处理模块。
CORDIC算法可以用来实现正弦、余弦、乘法、除法、平方根等超越函数,因此,把CORDIC算法和基本的数学模块结合起来来计算传递函数,可以得到较为精确的结果。但是,对于复杂的传递函数来说,获得精确结果的代价是花费更多的设计和验证的时间。
对于复杂的传递函数,除了在FPGA中实现精确的函数功能外,还有许多更为有效的处理方法。一个例子就是用FPGA来监控铂电阻温度计(PRT),并把铂电阻温度计的电阻值转换为温度。这个转换一般会使用Callendar-Van Dusen方程,这个方程可以用来确定0℃~660℃之间的温度值,方程如下:
其中R0是0℃时的电阻值,a和b是和PRT相关的系数,t表示温度。事实上,我们是想通过电阻值来转换得到温度值,因此,我们需要重新整理方程,把温度值作为方程的结果。大部分使用PRT的系统会设计一个电路来测量PRT的电阻值,而在FPGA中使用一个重新整理过的,比之前复杂得多的方程来计算温度值,方程如下:
在FPGA中实现这样一个方程,即使是一个经验丰富的FPGA工程师也会感到气馁。通过测试,把电阻值和温度值的对应关系绘图如下:
如果仔细研究,会发现这是一个非线性的曲线。
为了减少设计以及验证的工作,保证项目进度,许多工程师会寻找其它不同的方式来实现这个函数。其中一个方式是利用查找表来保存图表中曲线上的一些点,在这些点之间可以采用线性插值的方式,这个方法可能可以满足需求,但要依赖于精确度的要求以及查找表中能存储的点的个数。但这种方法会引入一个线性插值函数,这个函数通常会包括一个无二次幂限制(non-power-of-two)的除法,这会带来计算的复杂度。
现在的FPGA器件,比如Xilinx Spartan-6、7-系列Atrix、Kintex以及Virtex等FPGA器件中都会包含更多地传统意义上的查找表和触发器。同时也包含内置的DSP slices,Block RAM和一些分散的RAM单元,还有一些象PCIe、以太网端点、高速串行连接等先进的硬IP核,用这些器件可以轻松地实现传递函数。
多项式近似法可以充分利用FPGA器件中丰富的DSP和RAM资源, 使用这项技术,首先要把数学函数用图表来表达,可以用MATLAB或者Excel等数学工具来遍历输入值的范围,然后就可以得到一个多项式趋势线,这样,就可以在FPGA中实现这个方程,而不需要使用电路逻辑直接实现复杂的数序函数,这种趋势线近似方程也可以满足精度的要求。
大部分用来生成多项式趋势线的数学工具都支持选择多项式的介数或者项数,介数越大,精确度就越高,但在FPGA中就需要实现更多的项数。用这种方法通过Microsoft Excel来分析PRT曲线,可以获得下面的4介多项式:
一个多项式方程可能不能满足传递函数全部输入范围的精度要求,那么只需要产生更多的多项式方程,通过产生许多多项式常数来覆盖输入范围,一旦输入的值超出了特定的边界,只需要加载一组新的常数值就可以了。上述方法依然是有效的。
假设,我们需要把操作范围扩展到300 ℃,原来的方法就不能满足设计要求了,采用刚刚提到的分段的方法,可以通过绘制269℃ 到300℃之间的趋势线来解决这个问题,这样可以得到另一个多项式方程,该方程可以满足这个输出范围的精度要求。简言之,分段的实现方法在输入值没有超出268℃对应的预定值范围时,采用的是第一组多项式常数,而当输入值超出了268℃对应的预定值范围时,就采用第二组常数来保证精度要求。
尽管设计团队使用了内嵌微处理器的片上系统,比如内嵌ARM Cortex-A9 MPCore的Xilinx Zynq可编程SoC器件,但实现传递函数还是具有较大的挑战,首先,通过处理器执行软件来实现传递函数所花的时间要远远大于通过可编程逻辑实现传递函数的运行时间,这样就会使系统响应变慢,事实上,上面提到的传递函数的计算就是一个比较典型的例子,它的数据处理应该通过Zynq SoC器件的可编程逻辑去实现。