警告
SpinalHDL 定点支持仅部分使用/测试,如果您发现任何错误,或者您认为缺少某些功能,请创建 Github issue。另外,请不要在代码中使用未归档的功能。
UFix/SFix
描述
UFix 和 SFix 类型对应于可用于定点算术的位向量。
声明
声明定点数的语法如下:
无符号定点小数
| 语法 | 位宽 | 分辨率 | 最大值 | 最小值 | 
|---|---|---|---|---|
| UFix(peak: ExpNumber, resolution: ExpNumber) | peak-resolution | 2^resolution | 2^peak-2^resolution | 0 | 
| UFix(peak: ExpNumber, width: BitCount) | width | 2^(peak-width) | 2^peak-2^(peak-width) | 0 | 
有符号定点小数
| 语法 | 位宽 | 分辨率 | 最大值 | 最小值 | 
|---|---|---|---|---|
| SFix(peak: ExpNumber, resolution: ExpNumber) | peak-resolution+1 | 2^resolution | 2^peak-2^resolution | -(2^peak) | 
| SFix(peak: ExpNumber, width: BitCount) | width | 2^(peak-width-1) | 2^peak-2^(peak-width-1) | -(2^peak) | 
格式
所选格式遵循使用 Q 表示法定义定点小数格式的常用方法。更多信息可以在 Q 数据格式的维基百科页面 上找到。
例如,Q8.2表示8+2位的定点数,其中8位用于自然部分,2位用于小数部分。如果定点数有符号,则多一位用于符号。
分辨率被定义为可以用该数字表示的最小的二的幂。
备注
为了使表示二次幂的数字不易出错,在 spinal.core``中有一个称为 ``ExpNumber 的数字类型,它用于定点类型构造函数。这种类型有一个方便的封装,采用 exp 函数的形式(在本页的代码示例中使用)。
示例
// Unsigned Fixed-Point
val UQ_8_2 = UFix(peak = 8 exp, resolution = -2 exp) // bit width = 8 - (-2) = 10 bits
val UQ_8_2 = UFix(8 exp, -2 exp)
val UQ_8_2 = UFix(peak = 8 exp, width = 10 bits)
val UQ_8_2 = UFix(8 exp, 10 bits)
// Signed Fixed-Point
val Q_8_2 = SFix(peak = 8 exp, resolution = -2 exp) // bit width = 8 - (-2) + 1 = 11 bits
val Q_8_2 = SFix(8 exp, -2 exp)
val Q_8_2 = SFix(peak = 8 exp, width = 11 bits)
val Q_8_2 = SFix(8 exp, 11 bits)
赋值
有效赋值
当没有位丢失时,对定点小数值的分配是有效的。任何位丢失都会导致错误。
如果源定点小数值太大,truncated 函数将允许您调整源数字的大小以匹配目标大小。
示例
val i16_m2 = SFix(16 exp, -2 exp)
val i16_0  = SFix(16 exp,  0 exp)
val i8_m2  = SFix( 8 exp, -2 exp)
val o16_m2 = SFix(16 exp, -2 exp)
val o16_m0 = SFix(16 exp,  0 exp)
val o14_m2 = SFix(14 exp, -2 exp)
o16_m2 := i16_m2            // OK
o16_m0 := i16_m2            // Not OK, Bit loss
o14_m2 := i16_m2            // Not OK, Bit loss
o16_m0 := i16_m2.truncated  // OK, as it is resized to match assignment target
o14_m2 := i16_m2.truncated  // OK, as it is resized to match assignment target
val o18_m2 = i16_m2.truncated(18 exp, -2 exp)
val o18_22b = i16_m2.truncated(18 exp, 22 bit)
来自 Scala 常量
当给 UFix 或 SFix 信号赋值时,Scala的 BigInt 或 Double 类型可以用作常量。
示例
val i4_m2 = SFix(4 exp, -2 exp)
i4_m2 := 1.25    // Will load 5 in i4_m2.raw
i4_m2 := 4       // Will load 16 in i4_m2.raw
原始值
可以使用 raw 属性读取或写入定点小数的整数表示形式。
示例
val UQ_8_2 = UFix(8 exp, 10 bits)
UQ_8_2.raw := 4        // Assign the value corresponding to 1.0
UQ_8_2.raw := U(17)    // Assign the value corresponding to 4.25
运算符
以下运算符可用于 UFix 类型:
算术运算
| 运算符 | 描述 | 返回值的分辨率 | 返回值的幅度 | 
|---|---|---|---|
| x + y | 加法 | Min(x.resolution, y.resolution) | Max(x.amplitude, y.amplitude) | 
| x - y | 减法 | Min(x.resolution, y.resolution) | Max(x.amplitude, y.amplitude) | 
| x * y | 乘法 | x.resolution * y.resolution) | x.amplitude * y.amplitude | 
| x >> y | 算术右移,y : Int | x.amplitude >> y | x.resolution >> y | 
| x << y | 算术左移,y : Int | x.amplitude << y | x.resolution << y | 
| x >>| y | 算术右移,y : Int | x.amplitude >> y | x.resolution | 
| x <<| y | 算术左移,y : Int | x.amplitude << y | x.resolution | 
比较运算
| 运算符 | 描述 | 返回类型 | 
|---|---|---|
| x === y | 等价性判断 | Bool | 
| x =/= y | 不等价判断运算 | Bool | 
| x > y | 大于 | Bool | 
| x >= y | 大于或等于 | Bool | 
| x < y | 小于 | Bool | 
| x >= y | 小于或等于 | Bool | 
类型转换
| 运算符 | 描述 | 返回类型 | 
|---|---|---|
| x.asBits | 二进制转换为 Bits | Bits(w(x) bits) | 
| x.asUInt | 二进制转换为 UInt | UInt(w(x) bits) | 
| x.asSInt | 二进制转换为SInt | SInt(w(x) bits) | 
| x.asBools | 转换为 Bool 数组 | Vec(Bool(),width(x)) | 
| x.toUInt | 返回对应的UInt(带截断) | UInt | 
| x.toSInt | 返回对应的SInt(带截断) | SInt | 
| x.toUFix | 返回对应的UFix | UFix | 
| x.toSFix | 返回对应的SFix | SFix | 
杂项
| 名称 | 返回类型 | 描述 | 
|---|---|---|
| x.maxValue | 返回可存储的最大值 | Double | 
| x.minValue | 返回可存储的最小值 | Double | 
| x.resolution | x.amplitude * y.amplitude | Double |