Bitlet: A bit-level sparsity-awared multiply-accumulate process element in HDL.
https://luhang-hpu.github.io/files/bitlet-MICRO21.pdf
https://github.com/Zhu-Zixuan/Bitlet-PE
https://github.com/Chen-gz233/Bitlet-CLike
io | 功能 |
---|---|
in_a |
矩阵A输入 |
in_b |
矩阵B输入 |
in_valid |
输入有效信号 |
in_d |
偏置数 |
dataOut |
输出矩阵 |
out_valid |
输出有效信号 |
reg_b
: 使用WS
模式,因此将weight矩阵保存在计算单元中
sign
矩阵 :将输入的两个矩阵对应位置元素做异或(^
)得到对应的符号位 :
amanti
: 输入A矩阵中的每一个元素去除符号位后的尾数
wmanti
: 输入B矩阵中的每一个元素去除符号位后的尾数
tip :在处理尾数的时候,输入数据必须符合IEEE754标准,对于负数采用补码形式。取尾数的时候,要使用取反+1的操作。
这个模块将输入的wmanti矩阵数据拆分成“0 或 1”
io | 功能 |
---|---|
wManti |
输入矩阵(64 * 8) 64(8*8)个元素,每个元素位宽是8 |
in_b |
输出矩阵 (8*64) 8行数据,每行64个Bool 类型元素 |
这里做了一个逆时针旋转90度的操作
我们的输入数据是$64*8bit$ 输出数据是$8 * 64bit$
这种操作的目的是将wmanti
中的数据按位提取,因为不同的位有不同的权重。因此得出sewo
中每行数据的权重不同。
在这个模块中,aManti
是之前取出符号位的矩阵A
。应该有64
个8
位宽数据,这里做简化只显示了0-7
个。
sign
是预处理后的数据,表示矩阵A
和矩阵B
中对应位置的元素符号位做异或^
操作,也就是对应位置相乘后的符号。
sewo
是shiftOrchestModule
模块将wmanti
处理后的数据,sewo
总过有8
组每组64
位。
上面提到sewo
中的8
组数据是根据不同的权重来分配的。在二进制乘法中的权重也就是数据位移操作。
sewo(0)
中第一组数据权重为0
,sewo(1)
中第一组数据权重为1
,以此类推。因此sewo(i)
在与aManti
做乘法时,就是将aManti
左移i
位,再补上符号位。这就是Bitlet
模块中最重要的计算方式,对应decoderRR_not_fixed
代码中的UIntShiftToSInt_int8
函数。
无符号数到有符号数的转换:
- 使用
UIntShiftToSInt_int8
函数,将无符号数右移并根据符号位扩展转为有符号数。
根据sewo
中的数据,从低位到高位每8
位取为window
滑窗。
根据window
在num_table
获取29位宽的数据(num_table_temp := num_table(window)
),将num_table
解码为10
组数据(ones
,two_x
,three_x
,four_x
)。
在这里ones
给滑窗中1
的稀疏情况分等级:
-
ones=0
时:滑窗window
中有0-1
个1
,不需要标注1
的位置(在滑窗的第几位); -
ones=1
时:滑窗window
中有2
个1
,two_x
用于标注滑窗window
中1
的位置; -
ones=2
时:滑窗window
中有3
个1
,three_x
用于标注滑窗window
中1
的位置; -
ones=2
时:滑窗window
中有4
个1
,four_x
用于标注滑窗window
中1
的位置; -
ones=3
时:滑窗中1
的个数>4
个,不用考虑稀疏性,直接计算。
根据UIntShiftToSInt_int8
函数,将io.sign
和io.aManti
位移后结合,转为31位有符号数保存在windowRegx_x
中,最后将这些有符号数相加。
累加和溢出处理:使用多个寄存器和 Mux
选择器实现累加操作。当多个累加结果需要输出时,使用 SpillOver
寄存器充当缓存队列。
输出结果:根据有效信号 valid_num
和溢出寄存器 SpillOver
的状态,选择最终的累加结果输出到 outNum
。
这个模块通过对输入数据向量RRregOut
的各个元素进行累加操作,计算出累加结果data
,并提供一个有效信号out_valid
。