《Universal Number Posit Arithmetic Generator on FPGA》(一)
A parameterized Verilog HDL is constructed for each unit which takes posit word size (N) and posit exponent size (ES), FP exponent size (E), where required, as its parameter and produces corresponding hardware. As, regime bits can reach up to last bit, RS bits (= Log2N) can accommodate its maximum absolute numerical value.
以下是针对参数化Posit数处理单元的Verilog HDL设计的中文分析:
Posit格式关键组成部分
- 符号位(Sign Bit):位于Posit字最高有效位(MSB)
- 调控域(Regime Field):由连续的1或0组成的可变长度字段,以相反比特终止
- 指数域(Exponent Field):固定ES比特(由参数决定,可选)
- 小数域(Fraction Field):调控域和指数域后的剩余比特
参数化设计挑战
- 动态调控域长度:调控域最多可占据 (N-1) 比特(符号位之后),需灵活编码机制
- 指数缩放:调控域贡献比例因子 (k),与ES比特指数结合实现动态范围
- 硬件效率:使用对数编码(RS = ( \lceil \log_2 N \rceil ))处理最大调控域长度
Verilog模块结构
module posit_decoder #(
parameter N = 16, // Posit字长
parameter ES = 2 // 指数域比特数
) (
input wire [N-1:0] posit_in, // 输入Posit数
output reg sign, // 符号位
output reg [($clog2(N)-1:0] regime_scale, // RS = log2(N) 比特
output reg [ES-1:0] exponent, // 指数域
output reg [N-1:0] fraction // 小数域(动态宽度)
);
// 符号位提取
always @(*) sign = posit_in[N-1];
// 调控域处理
wire [N-2:0] regime_bits = posit_in[N-2:0];
wire start_bit = regime_bits[N-2]; // 符号位后的首比特
reg [$clog2(N)-1:0] regime_length;
reg regime_sign; // 0表示k为负,1为正
// 查找调控域终止点
integer i;
reg found_termination;
always @(*) begin
regime_length = 0;
found_termination = 0;
for (i = 0; i < N-1; i = i+1) begin
if (!found_termination) begin
if (regime_bits[i] != start_bit) begin
regime_length = i;
found_termination = 1;
end
end
end
if (!found_termination) regime_length = N-1; // 全为相同比特
end
// 计算调控域比例因子k
always @(*) begin
regime_scale = start_bit ? (regime_length - 1) : (-regime_length);
regime_sign = start_bit;
end
// 指数域提取(ES>0时生效)
generate
if (ES > 0) begin
always @(*) begin
if (found_termination && (regime_length + ES < N-1)) begin
exponent = regime_bits[regime_length +: ES];
end else begin
exponent = 0; // 比特不足时补0
end
end
end else begin
always @(*) exponent = 0; // 无指数域
end
endgenerate
// 小数域提取(剩余比特)
always @(*) begin
if (found_termination) begin
fraction = regime_bits >> (regime_length + ES);
end else begin
fraction = 0; // 调控域占满时无小数
end
end
endmodule
关键设计决策解析
-
调控域长度检测:
- 通过循环逐比特检测终止点(相反比特)
- 若未找到终止点,调控域占据全部 (N-1) 比特
- 使用 ( \lceil \log_2 N \rceil ) 比特(RS)编码比例因子 (k),以支持最大长度 (N-1)
-
指数与小数处理:
- 指数域起始于调控域终止点后
- 小数域根据调控域和ES动态调整位置
-
参数化特性:
- N:控制所有字段的比特宽度
- ES:决定指数域的存在性与大小
- RS:自动计算 ( \lceil \log_2 N \rceil ),确保调控域比例因子的数值范围
示例配置
- 输入:16位Posit数(N=16,ES=2)
- 输出:
regime_scale
:4比特((\log_2(16)=4))exponent
:2比特fraction
:调控域和指数域后的剩余比特
设计优势
- 动态适应性:自动处理不同Posit配置(N和ES)
- 硬件效率:使用对数编码减少资源占用
- 可扩展性:通过参数轻松支持任意Posit格式
该设计通过参数化实现灵活的Posit数解码,在保持硬件效率的同时,兼容不同精度的数值表示需求。
在Posit解码器的Verilog设计中,调控域(Regime)的长度使用 ( \lceil \log_2 N \rceil ) 比特进行编码,主要基于以下原因:
1. 调控域长度的动态范围
Posit数的调控域由连续的1或0组成,其最大可能长度为 ( N-1 )(当所有位均为相同比特时)。为了表示从0到( N-1 )的所有整数,需要足够的比特位来覆盖这一范围。
- 数学原理:编码范围 ( 0 \sim M-1 ) 需要 ( \lceil \log_2 M \rceil ) 比特。
- 举例:
- 若 ( N=16 ),则最大调控域长度为15,需要 ( \lceil \log_2 16 \rceil = 4 ) 比特(可表示0~15)。
- 若 ( N=5 ),最大长度为4,需 ( \lceil \log_2 5 \rceil = 3 ) 比特(可表示0~7,覆盖需求)。
2. 硬件资源的优化
使用对数比特数能够最小化硬件开销:
- 避免浪费:若直接用 ( N ) 比特表示调控域长度,当 ( N ) 较大时(如64位Posit),会造成显著的资源浪费。
- 对数增长缓慢:( \lceil \log_2 N \rceil ) 的增长速度远低于线性(如 ( N=1024 ) 时仅需10比特),更适合硬件实现。
3. 符号处理的兼容性
调控域的比例因子 ( k ) 可以是正或负,具体由起始比特决定:
- 正调控域(连续1):( k = \text{regime_length} - 1 )。
- 负调控域(连续0):( k = -\text{regime_length} )。
- 比特数需求:
- 正调控域的最大值为 ( N-2 )(当调控域占满 ( N-1 ) 比特时,( k = (N-1) - 1 = N-2 ))。
- 负调控域的最小值为 ( - (N-1) )。
- 因此,需覆盖范围 ( -(N-1) \sim N-2 ),总跨度约为 ( 2N ),需 ( \lceil \log_2 (2N) \rceil = \lceil \log_2 N \rceil + 1 ) 比特。
- 设计权衡:
- 实际代码中
regime_scale
使用无符号数,但通过条件表达式处理符号,可能导致隐性符号扩展。 - 选择 ( \lceil \log_2 N \rceil ) 比特是权衡后的结果,确保覆盖最大绝对值 ( N-1 ),而符号通过额外逻辑处理。
- 实际代码中
4. Verilog的硬件友好特性
- 自动位宽计算:Verilog的
$clog2(N)
函数直接返回 ( \lceil \log_2 N \rceil ),简化代码。 - 对齐硬件结构:比特数通常选择2的幂次方(如3比特实际表示0~7),便于内存对齐和逻辑操作。
5. 示例验证
以 ( N=8 ) 为例:
- 最大调控域长度:7(需3比特)。
- 比例因子范围:
- 正调控域:( k = 7-1 = 6 )(二进制
110
)。 - 负调控域:( k = -7 )(二进制补码
1001
,需4比特)。
- 正调控域:( k = 7-1 = 6 )(二进制
- 矛盾点:3比特无法直接表示-7。
- 解决方案:
- 实际代码中
regime_scale
存储无符号的调控域长度(0~7),符号由regime_sign
单独表示。 - 最终的比例因子 ( k ) 通过组合
regime_scale
和regime_sign
计算,而非直接存储有符号数。
- 实际代码中
结论
使用 ( \lceil \log_2 N \rceil ) 比特编码调控域长度,是以下权衡的结果:
- 覆盖最大长度:确保能表示 ( 0 \sim N-1 ) 的所有可能长度。
- 硬件效率:避免线性增长的比特数,选择对数压缩。
- 符号分离处理:通过额外信号(如
regime_sign
)管理符号,而非直接存储有符号数。
这种设计在资源占用和功能完备性之间取得了平衡,是Posit硬件解码器的典型实现方式。
在Posit数字系统的硬件设计中,使用以2为底的对数(即⌈log₂N⌉)来确定regime部分的比特数,并非直接由Posit标准强制规定,而是基于对标准的理解和硬件优化的权衡选择。以下是详细分析:
1. Posit标准的核心要求
Posit标准(由John L. Gustafson提出)主要定义以下内容:
- Regime字段的语义:
- 由连续的1或0组成,以相反比特终止。
- 比例因子 (k) 的计算公式:
- 若起始位为1:(k = \text{regime长度} - 1)
- 若起始位为0:(k = -\text{regime长度})
- 动态范围和精度:
- 通过regime和指数(ES)的组合实现动态范围扩展。
- 小数域(fraction)提供精度。
标准未明确的部分:
- Regime长度的编码方式:标准未规定必须使用多少比特存储regime长度。
- 硬件实现细节:如比特数选择、符号处理等,属于实现者的自由裁量范围。
2. 设计选择:为何使用⌈log₂N⌉比特?
在Verilog设计中,选择⌈log₂N⌉比特编码regime长度,主要基于以下工程优化考虑:
(1) 覆盖最大可能的regime长度
- Regime的最大长度:在N位Posit数中,regime最多占据(N-1)位(符号位之后的所有位)。
- 数学需求:编码范围(0 \sim (N-1))需要的最小比特数为⌈log₂N⌉。
- 例如:(N=16)时,最大长度15需4比特((2^4=16 > 15))。
- 这是信息论中的基本要求,确保无信息丢失。
(2) 硬件资源优化
- 避免线性增长:若直接使用(N-1)比特存储regime长度,当(N)较大时(如64位Posit),会导致显著的硬件资源浪费。
- 对数压缩的优势:⌈log₂N⌉的增长速度远低于线性,例如:
- (N=32) → 5比特
- (N=64) → 6比特
- 这种压缩在FPGA或ASIC设计中能显著减少寄存器和组合逻辑的占用。
(3) 符号分离处理
- 比例因子(k)的符号:由regime的起始位(0或1)决定,而非直接编码在regime长度中。
- 硬件实现:
- 使用无符号数存储regime长度(⌈log₂N⌉比特)。
- 符号通过额外信号(如
regime_sign
)单独管理。 - 这种方式简化了算术逻辑,避免复杂的补码操作。
3. Posit标准的灵活性与实现自由度
Posit标准更关注数值表示的正确性,而非硬性规定实现细节。例如:
- 允许参数化:用户可自定义字长(N)和指数域大小(ES)。
- 实现多样性:不同的硬件设计可采用不同的regime编码策略,只要最终的比例因子(k)计算符合标准。
- 例如:某些设计可能选择额外的比特处理符号,但会增加资源占用。
4. 行业实践与事实标准
尽管Posit标准未强制要求,但⌈log₂N⌉比特编码已成为常见实践,原因包括:
- 广泛采用的优化:在学术论文和开源实现(如SoftPosit库)中,均使用类似方法。
- 工具链支持:Verilog的
$clog2(N)
函数直接支持对数计算,简化代码实现。 - 平衡性能与资源:在保证功能正确性的前提下,最小化硬件开销。
5. 验证示例
以(N=8)位Posit数为例:
- 最大regime长度:7(需3比特,因(⌈log₂8⌉=3))。
- 比例因子范围:
- 正调控域:(k = 7-1 = 6)(二进制
110
)。 - 负调控域:(k = -7)(需符号位+3比特补码
1001
)。
- 正调控域:(k = 7-1 = 6)(二进制
- 实际实现:
- 存储无符号regime长度(3比特),符号由
regime_sign
单独标识。 - 最终(k)通过组合两者计算,而非直接存储有符号数。
- 存储无符号regime长度(3比特),符号由
结论
使用⌈log₂N⌉比特编码regime长度,是对Posit标准的合理扩展与硬件优化,而非标准的直接规定。其合理性体现在:
- 覆盖最大需求:确保所有可能的regime长度均可表示。
- 资源高效:对数压缩显著减少硬件开销。
- 符合标准语义:最终的比例因子(k)计算严格遵循Posit定义。
这种设计在遵循标准核心要求的同时,充分发挥了硬件实现的灵活性,是工程实践中的典型优化策略。
算法分析:FP到Posit转换器流程
算法概述
该算法描述了将浮点数(FP)转换为Posit格式的过程。Posit是一种新兴的浮点数替代格式,旨在提供更高的精度和更高效的计算。以下是算法的主要步骤和关键点。
算法步骤
-
输入参数:
- N:FP和Posit的字长。
- E:FP的指数字段大小。
- BIAS:FP的指数偏置,计算公式为 ( \text{BIAS} = 2^{(E-1)} - 1 )。
- ES:Posit的指数字段大小。
-
输入操作数:
- IN:输入的浮点数。
-
FP数据提取:
- 提取浮点数的符号位 ( S_{FP} )、指数 ( E_{FP} )、尾数 ( M_{FP} ),并检测特殊值(零 ( Z_{FP} ) 和无穷大 ( INF_{FP} ))。
-
预归一化:
- 计算尾数 ( M_{FP} ) 的归一化左移量 ( \text{Lshift} )。
- 对尾数 ( M_{FP} ) 进行动态左移,调整指数 ( E_{FP} )。
-
Posit组件构造:
- 构造Posit的指数 ( E_O )、Regime值 ( R_O ) 和尾数 ( M_O )。
- 动态右移操作以适应Posit的Regime值。
-
最终输出:
- 结合符号位 ( S_{FP} ) 和处理后的尾数 ( REM ) 形成最终的Posit值。
- 处理特殊值(无穷大和零)。
关键点分析
-
FP数据提取:
- 符号位:( S_{FP} ) 从输入的最高位提取。
- 指数和尾数:分别从输入的相应位提取。
- 特殊值检测:检测零和无穷大,以便在后续步骤中特殊处理。
-
预归一化:
- 归一化左移:计算尾数的归一化左移量,确保尾数的最高有效位为1。
- 调整指数:根据左移量调整指数值。
-
Posit组件构造:
- 指数调整:根据Posit的指数字段大小 ( ES ) 调整指数。
- Regime值计算:动态计算Regime值 ( R_O ),这是Posit格式的一个重要特征,用于表示指数的扩展部分。
- 尾数处理:结合Regime值对尾数进行动态右移。
-
特殊值处理:
- 零和无穷大:在最终输出时,根据检测到的特殊值进行适当处理。
算法优势
- 高效转换:通过预归一化和动态位移操作,确保转换过程高效且精确。
- 灵活性:支持不同字长和指数大小的FP和Posit格式。
- 特殊值处理:能够正确处理零和无穷大等特殊值。
应用场景
- 高精度计算:适用于需要高精度和动态范围的科学计算和工程应用。
- 嵌入式系统:Posit格式的高效性和紧凑性使其适合嵌入式系统。
这段话详细描述了在Posit格式中构造指数和尾数部分的流程,重点在于如何根据FP格式的指数值动态生成Posit格式的Regime值和无符号指数。以下是关键步骤的分析:
Posit构造流程
-
指数值的处理
- 给定:一个带符号的指数值(Exp)。
- 目标:确定Posit的Regime值 ( R_O ) 和无符号指数 ( E_O )(大小为ES位)。
-
Regime值和指数的确定
- 最低有效位(LSB)处理:Exp的绝对值的最低有效位(LSB)的ES位用于确定 ( E_O ),而剩余的最高有效位(MSB)用于确定 ( R_O )。
- 指数为负且非零情况:
- 如果Exp是负数且Exp的绝对值的最低ES位非零,则 ( E_O ) 是Exp绝对值的这ES位的二进制补码(线19-20)。
- 这是因为 ( E_O ) 是无符号整数,所以需要通过调整负指数的表示来确保正确性。
- 其他情况:
- 如果Exp不是负数或Exp绝对值的最低ES位为零,则 ( E_O ) 直接取自Exp绝对值的最低ES位(线21-22)。
-
Regime值的处理
- 剩余最高有效位(MSB)处理:Exp绝对值的剩余MSB(即高于ES位的部分)用于确定 ( R_O )。
- 指数为负且最低ES位为零情况:如果Exp是负数且Exp绝对值的最低ES位为零,则 ( R_O ) 是Exp绝对值的剩余MSB(线23)。
- 其他情况:否则, ( R_O ) 是Exp绝对值的剩余MSB加1(线25-26)。
Posit格式的关键特性
- 动态Regime长度:Posit格式的Regime位长度在运行时变化,这允许它适应不同数值的大小,提高表示的灵活性和精度。
- 高效指数表示:通过将指数分为Regime和无符号指数两部分,Posit格式能够在有限的位数内表示更广泛的数值范围。
在Posit格式中的作用
- 灵活的表示:允许Posit格式根据数值的大小动态调整Regime位的长度,从而优化存储和计算效率。
- 广泛的数值范围:通过Regime和指数的组合,Posit能够在有限的位数内表示从非常小到非常大的数值。
这段话强调了Posit格式在构造指数和尾数时的灵活性和动态性,这也是Posit格式相比传统浮点格式的优势之一。
以下是这个Posit转换算法的一个计算案例:
输入参数
假设我们有以下输入参数:
- N = 32(FP和Posit的字长)
- E = 8(FP的指数字段大小)
- BIAS = 127(FP的指数偏置)
- ES = 4(Posit的指数字段大小)
输入浮点数(FP)为32位,表示为:
- IN = 0x3F800000(即FP表示的1.0)
FP数据提取
-
符号位 ( S_{FP} ):从IN的最高位提取。
- ( S_{FP} = IN[31] = 0 )(正数)
-
指数 ( E_{FP} ):从IN的第23位到第30位提取。
- ( E_{FP} = IN[30:23] = 0x7F = 127 )
-
尾数 ( M_{FP} ):从IN的第0位到第22位提取。
- ( M_{FP} = IN[22:0] = 0x000000 )
-
特殊值检测:
- ( Z_{FP} = !(IN[31:0] != 0) = 0 )(非零)
- ( INF_{FP} = (E_{FP} == 0xFF && M_{FP} == 0) = 0 )(非无穷大)
预归一化
-
计算尾数的归一化左移量 ( \text{Lshift} ):
- ( \text{Lshift} = \text{LOD of } M_{FP} )
- 由于 ( M_{FP} ) 全为0,无需左移。
-
动态左移尾数和调整指数:
- ( M_{FP}[31:0] = \text{Dynamic Left Shift of } {M_{FP}, E_{FP}'} )(无需左移)
- ( Exp = E_{FP} - BIAS - \text{Lshift} = 127 - 127 - 0 = 0 )
Posit组件构造
-
指数处理:
- ( ExpN = Exp = 0 )
- ( ExpN[3:0] = 0 )(最低4位)
- ( ExpN[7:4] = 0 )(最高4位)
-
确定 ( E_O ) 和 ( R_O ):
- ( Exp ) 为0,非负。
- ( E_O = ExpN[3:0] = 0 )
- ( R_O = ExpN[7:4] + 1 = 0 + 1 = 1 )
-
组合Posit各部分:
- ( REM = {N{Exp[E]}, Exp[E], E_O, M_{FP}[N-2:ES]} )
- ( REM = {32{0}, 0, 0, 0} )
- 动态右移 ( REM ) 由 ( R_O ) 决定,右移1位:
- ( REM = 0 )
-
最终输出:
- 结合 ( S_{FP} ) 和 ( REM ) 的最低31位:
- ( REM ) 的最低31位为0
- 最终Posit值为 ( 0 )
- 结合 ( S_{FP} ) 和 ( REM ) 的最低31位:
这个案例展示了将FP表示的1.0转换为Posit格式的过程,最终结果为0。这说明了Posit格式在处理特定数值时的动态调整特性。