1、定点数据类型介绍
在 c++ 中采用浮点数据类型不仅能够很容易的进行算术运算,而且精度高,但是浮点运算在硬件上实现起来特别复杂,因此为了节省硬件资源很多硬件只支持定点运算。为了能够精确地建模和描述定点硬件,必须使用定点数据类型
SystemC 专门定义了有符号和无符号的定点数据类型,而且还允许设置定点数据类型的量化和溢出模式
SystemC 的四种基本定点数据类型为
sc_fixed
sc_ufixed
sc_fix
sc_ufix
sc_fixed 和 sc_ufixed 的参数是静态的,在程序中设定后不能再修改,而 sc_fix 和 sc_ufix 的参数是非静态的,其字长和整数部分的长度是变量,sc_fixed 和 sc_fix 是有符号的,而 sc_ufixed 和 sc_ufix 是无符号的,这里我们暂时只介绍 sc_fixed 和 sc_ufixed
sc_fixed<wl, iwl, q_mode, o_mode, n_bits> x;
sc_ufixed<wl, iwl, q_mode, o_mode, n_bits> y;
参数含义如下
wl: 总字长,表示一个定点数的总的比特数
iwl: 整数部分字长,即小数点左边的比特数
q_mode: 量化模式,当一个运算的结果的精度打与定点数所能表示的精度时就要根据量化模式将尾数进行取舍
o_mode: 溢出模式,当一个运算的结构大于定点数所能表示最大值时,就要根据溢出模式将数据进行处理
n_bits: 饱和比特数,该参数仅用于溢出模式,它定义了在特定具有饱和行为的溢出模式喜爱饱和比特的位数
也就是说 q_mode 处理的小数部分,o_mode 处理的是整数部分
字长 wl 是用于表示一个定点数的总的比特数,它必须是大于 0 的,整数部分长度 iwl 也称为整数字长,可以是正数、负数,也可以大于总字长,下面列出一些常见的情况
总字长 | 整数部分字长 | 内部表示 | 有符号数范围 | 无符号数范围 |
5 | 7 | xxxxx00. | [-64, 60] | [0, 124] |
5 | 5 | xxxxx. | [-16, 15] | [0, 31] |
5 | 3 | xxx.xx | [-4, 3.75] | [0, 7.75] |
5 | 0 | .xxxxx | [-0.5, 0.109375] | [0, 0.234375] |
5 | -2 | .ssxxxxx | [-0.125, 0.109375] | [0, 0.234375] |
1 | -1 | .sx | [-0.25, 0] | [0, 0.25] |
2、量化模式
量化模式 | 含义 |
SC_RND | 向正无穷舍入 |
SC_RND_ZERO | 向 0 舍入 |
SC_RND_MIN_INF | 向负无穷舍入 |
SC_RND_INF | 向无穷舍入 |
SC_RND_CONV | 收敛舍入 |
SC_TRN | 删除舍入 |
SC_TRN_ZERO | 向 0 删除舍入 |
2.1 SC_RND
SC_RND 就是对尾巴比特的最高位进行四舍五入,实际上相当于将要舍去的比特的最高位追加到要保留比特的最低位
// 小数部分两位
sc_fixed<4, 2> x = 1.25;
// 小数部分变成一位了,这个时候就要量化处理
sc_fixed<3, 2, SC_RND> y = x;
std::cout << y << std::endl;
x 的二进制表示为 01. 01
这个时候 y 的值是 1.5,对应二进制为 01. 10
// 小数部分两位
sc_fixed<4, 2> x = -1.25;
// 小数部分变成一位了,这个时候就要量化处理
sc_fixed<3, 2, SC_RND> y = x;
std::cout << y << std::endl;
在计算机中负数的二进制使用补码表示,那么 x 的二进制就是 10. 11
y 的值为 -1,也就是 11.0
2.2 SC_RND_ZERO
SC_RND_ZERO 对尾巴比特的处理如下,对于小于 0 的数,要把舍去的比特的最高位追加到要保留比特的最低位,对于大于 0 的数,直接将尾巴比特舍去
2.3 SC_RND_MIN_INF
SC_RND_MIN_INF 的量化方法是当被舍弃的位值大于 0.5q 时就进位,小于等于 0.5q 时就舍弃,其中 q 表示目标对象的最小量化单位,如果 y 的小数部分有两位,那么 q = 0.01 (二进制)或者 q = 0.25(十进制)
sc_fixed<5, 2> x = 1.875; // 01. 111
// q = 0.5,舍弃部分 0.011 = 0.375,0.5q = 0.25,也就是舍弃部分大于 0.5q,那么就进位
// 那么对应 y 就是 01.1 --> 10.0 --> -2
sc_fixed<3, 2, SC_RND_MIN_INF> y = x;
sc_fixed<5, 2> x = 1.625; // 01. 101
// q = 0.5,舍弃部分 0.001 = 0.125,0.5q = 0.25,也就是舍弃部分小于 0.5q,那么直接丢弃
// 那么对应 y 就是 01.1 --> 1.5
sc_fixed<3, 2, SC_RND_MIN_INF> y = x;
2.4 SC_RND_INF
SC_RND_IF 对尾巴比特的处理如下:对于小于 0 的数,直接将尾巴比特舍去,对于大于 0 的数,要把舍弃的比特追加到要保留比特的最低位,刚好和 SC_RND_ZERO 相反
2.5 SC_RND_CONV
SC_RND_CONV 对尾巴比特的处理如下,如果要保留的比特的最低位为 1,就向负无穷量化(将要舍弃的最高位追加到要保留的最低位),如果要保留的比特最低位为 0,那么就向正无穷量化(直接舍弃要舍弃的所有位)
2.6 SC_TRN
直接舍去尾巴比特
2.7 SC_TRN_ZERO
SC_TRN_ZERO 对尾巴比特的处理如下,如果尾巴比特的最高位为 1,那么将符号位加到要保留比特的最低位,否则直接删除所有尾巴比特
3、溢出模式
溢出模式 | 含义 |
SC_SAT | 饱和为最大最小值 |
SC_SAT_ZERO | 饱和为 0 |
SC_SAT_SYM | 对称饱和 |
SC_WRAP | 循环饱和 |
SC_WRAP_SM | 符号幅度循环饱和 |
在讨论溢出模式之前,我们将量化模式固定为 SC_TRN,表示直接舍去尾巴比特
3.1 SC_SAT
该溢出模式对运算结果的处理方式如下:当运算结果大于 Max 时,运算结果被饱和处理为 Max,当运算结果小于 Min 时,运算结果被饱和为 Min
sc_fixed<4, 4> x = -8;
sc_fixed<3, 3, SC_TRN, SC_SAT> y = x; // -4
sc_fixed<4, 4> x = 7;
sc_fixed<3, 3, SC_TRN, SC_SAT> y = x; // 3
3.2 SC_SAT_ZERO
该溢出模式对运算结果的处理方式为:当运算结果大于 Max 或者小于 Min 时,运算结果都被处理为 0
3.3 SC_SAT_SYM
该溢出模式对运算结果的处理方式如下:当运算结果大于 Max 时,运算结果被饱和处理为 Max,当运算结果小于 -Max 时,运算结果被饱和为 -Max(-Max = Min + 1)
3.4 SC_WRAP
该溢出模式与 n_bits 有关,可以分为 n_bits 等于 0 和 n_bits 大于 0 两种情况来讨论
n_bits 等于 0,也是缺省情况,溢出的情况下直接去掉最高位
// 0101
sc_fixed<4, 4> x = 5;
// 溢出,直接去掉最高位变成 101,也就是 -3
sc_fixed<3, 3, SC_TRN, SC_WRAP> y = x;
n_bits 不等于 0,暂时不讨论
3.5 SC_WRAP_SM
该溢出模式也还是与 n_bits 有关,可以分为 n_bits 等于 0 和 n_bits 大于 0 的两种情况
n_bits 等于 0 的情况,也是缺省情况,处理的过程为:将运算结果的多余的高位直接删除,用删除部分的最低位作为结果的符号位,如果符号位与原保留的最高位不同,则将运算结果所有的其他位复制并取反,如果符号位与原保留的最高位相同,则将运算结果所有的其他位复制即可
n_bits 大于 0 情况比较复杂,暂时不讨论
4、定点数据类型状态信息函数
函数 | 含义 |
is_neg | 查询定点对象的值是否是一个负数,如果是返回 true,否则返回 false |
is_zero | 查询定点对象的值是否是 0,如果是返回 true,否则返回 false |
overflow_flag | 如果上一次写到该定点对象时发生过溢出,就返回 true,否则返回 false |
quantization_flag | 如果上一次写到该定点对象时发生过量化,就返回 true,否则返回 false |
5、将定点数据类型转为字符串
定点数据类型还提供了 to_string(NumberRepresentation, Format) 方法将定点数据转换为字符串,它有两个参数,参数 NumberRepresentation 决定数据的表示方法,参数 Format 决定数据的格式
参数 NUmberRepresentation 的可能值如下
值 | 描述 | 前缀 |
SC_DEC | 十进制 | |
SC_BIN | 二进制,负数使用 2 的补码表示 | 0b |
SC_OCT | 八进制,负数使用 2 的补码表示 | 0o |
SC_HEX | 十六进制,负数使用 2 的补码表示 | 0x |
参数 Format 的可能值如下
值 | 含义 |
SC_F | 固定符号表示法 |
SC_E | 科学表示法 |
缺省为 SC_F