使用float建模定点行为
当许多算法都能依赖本地C数据类型的精度来编写时,对支持任意长度的整数及定点算法,大家就会抱有极大的期望,而硬件描述语言(HDL)如VHDL,走的也是同一条路。随着C/C++越来越多地被用于高级合成与验证工具(High-Level Synthesis and Verification tools),也证明了这种语言本质上有一个足以满足当前及未来程序需要的数据类型库。任意长度类型的支持,也可使数据类型的行为有一个统一的定义,而统一的语义则避免了人工实现上的一些限制。
算法C数据类型
算法C数据类型是一种基于类的C++库,其实现了任意长度的整数及定点类型,而这些可自由访问的类型有一系列好处,包括统一及良好定义的语义,还有媲美C/C++内置数据类型的运行时速度,对比SystemC中相应的类型,其运行速度也超过10倍以上。这些数据类型能用于任何符合C++或SystemC规范标准的程序中,并拥有高度可合成的语义。
语义
语义的统一性与一致性是避免在算法中,发生功能性错误的关键,以下的例子,也说明了这点:

众所周知,变量ActLength的范围为1至255,万一编译器的合成不知道其范围,就不能进行相应的优化,它的声明就会从int变为更严格的sc_uint<8>类型;虽然合成会得到更好的结果,但设计就仿真得不正确了。在经过一番调试之后,找到了问题的源头:在比较表达式k >= ActLength中,两个操作数变成了一个signed int与一个unsigned long long(为64位无符号整数,其是sc_uint类型的基类型)之间的比较。对此的解释是:C/C++整数提升规则指定了在进行比较之前,会把操作数int提升为一个unsigned long long,例如,如果k的值为 -1,在提升为unsigned long long之后,它会变成2^64 – 1。
像这样语义中的问题一般会非常难以察觉,且是与位宽相关的,例如,可能有人想扩大某个现有算法的位宽,只有看到结果时,才知道是行不通的;这个问题也可能是与特定平台相关的,例如,对1 << 32(两个操作数都是int类型,结果也是int类型)大家期望返回0,但在大多数平台(或编译器)上,它都会返回1(没有移位,只因为第二个操作数较低的五位被计算进来了);当第一个操作数是一个64位整数时,平台依赖性会表现得更加明显及频繁。主要的问题是C/C++标准没有指定在32位整数情况下移位值(第二个操作数)超出0至31范围、或在64位整数情况下移位值超出0至63范围时的行为。不幸的是,像sc_int、sc_uint这样的数据类型也不能为用户避免这类平台依赖性的问题。
算法C数据类型被设计用于提供统一且一致的语义,因此,它们是可预测的,例如,对有符号数混用一个无符号操作数仍会产生期望的结果;这些类型的长度不受限制,所以就不存在所谓的精度问题。所有的操作——包括移位和除法——都有完整且一致性的定义,混合不同的类型也能得到期望的结果,如,当x为一个C内置类型,而y是一个算法C类型时,表达式x+y和y+x均能返回相同的结果。
上一页 [1] [2] [3] 下一页 |