0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

探究比特对编码与比特对编码乘法器的设计

FPGA之家 来源:FPGA之家 作者:FPGA之家 2021-05-08 09:22 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

比特对编码与比特对编码乘法器的设计

今天一起看看比特对编码(有的也把它称为基4booth编码,名字不重要,主要是思想),可以解决上文中提到的问题

比特对编码原理

booth重编码的主要问题在于不能过滤掉010这样序列。故考虑将通过连续相邻两位进行编码,每次从低位向高位移动1位的方式(即booth比编码),变成连续相邻3位进行编码,每次从低位向高位移动2位的方式(比特对编码)。先讨论其原理。

一个数我们考虑从低位向高位对其进行编码,使其变成4进制(基4)的表示形式,每两位二进制表示一位的四进制数。

3(2'b11)比4少1,2(2'b10)比4少2。在4进制数中,2需要向前进位则需要减去2再向前进位;3需要向前进位则需要减去1再向前进位。

我们的比特对编码就是基于上述原理来的。

下面给出比特对编码规律,如下表和图所示,图为一个实例,是对1011_1111的编码,其表示-65。比特对编码结果为 -1 00-1,故其表示的十进制d为:

d=-4^3 -4^0= -65

db1c8f96-af27-11eb-bf61-12bb97331649.png

db4d6756-af27-11eb-bf61-12bb97331649.png

再举个例子,比如对0001_1001进行比特对编码,得到编码为:

+2-2+1

故其表示的十进制计算如下:

d=2*(4^2) -2*(4^1) +4^0

=32+8+1=41

其中的乘2与乘4都可以通过移位操作来实现,这就是为什么需要这么编码的原因。

可以看到,每相邻三位进行编码,其中的最低位mi-1 其实表示来自前面的进位。故当其为 001时,得到的编码为 +1(表示4),011时最低位1表示进位,故编码为1+1=+2。

从中可以得出,对于8位二进制数0101_0101,经过比特对编码后,得到的是 +1 +1 +1 +1,其表示的数为:

4^3 + 4^2 + 4^1 + 4^0 =

64+16+4+1=85

此时只需要进行3次加法运算,不会存在booth编码所存在的问题。

同时发现对于数据位宽非偶数的数,我们需要将其在最高位补填一位符号位,再进行比特对编码。

比特对编码(对乘数进行编码)乘法器,需要进行的加法次数为乘数位宽的一半。

比特对编码乘法器设计

设计思想概叙:定义位宽为DW_A+DW_B+2的product寄存器(DW_A为被乘数a的位宽,DW_B为乘数b的位宽)。当in_valid与in_ready同时为高时,将乘数b(位宽为b)加载到product的低DW_B位。然后在计算状态下(executing),将每次加法器的输出放到product的高位,并每个时钟周期将product右移2位。每个时钟周期,通过对

m={product[1:0],prd_r[1]}

(其中prd_r[1]为上一个时钟product的第二位)进行编码,得出本次操作是加1、加2,减1,减2,还是不用做加减法(编码为0)(代码中上述五种操作对应的标志信号分别为add_1,add_2,sub_1,sub_2,noneed_add)。并将加法结果每次存到product寄存器的高位。

这里有个巧妙的思想就是,每个时钟周期通过对product右移2位,再将其高DW_A位与a或者a*2进行相加或者相减操作,正好相当于每次product不动,把a或者a*2左移2位(乘以4)。这个思想源于《Verilog HDL 高级数字设计》中的精简寄存器时序乘法器设计。

注意,这里是有符号数乘法器,每次左移需要在高位补符号位,故左移不能简单的用 >> 描述(>>左移默认高位填0),具体描述见代码。

其中减法采用加上这个数的补码的方式;通过一个计数器(cnt)来指示什么时候结束运算;其中运算控制状态机采用《状态机的第四种描述方式》编写;条件选择多采用与或方式实现。

设计Verilog如下(dff_with_en为寄存器):

module radix4_mul #( parameter DW_A = 16, parameter DW_B = 8)( input clk, input rst_n, input in_valid, output in_ready, input flush, output o_valid, input o_ready, input [DW_A-1:0] a, input [DW_B-1:0] b, output [DW_A+DW_B-1:0] mul_res); //state machine for mulwire state;wire [$clog2((DW_B+1)/2):0] cnt;

wire exe_cnt_final = (cnt == (DW_B+1)/2); wire execute_en = in_valid&in_ready; localparam GET_DATA = 1'b0;localparam EXECUTING = 1'b1; wire curr_get_data = (state == GET_DATA);wire curr_executing = (state == EXECUTING); wire is_executing = curr_executing & (~exe_cnt_final);

wire nxt_get_data_en = (curr_executing & exe_cnt_final & o_ready) | flush;wire nxt_executing = curr_get_data & execute_en; wire nxt_state = (nxt_get_data_en & GET_DATA) | (nxt_executing & EXECUTING); wire tran_en = nxt_get_data_en | nxt_executing; dff_with_en #( .DW(1))dff_state( .clk (clk), .rst_n (rst_n), .enable (tran_en), .d_in (nxt_state), .q_out (state)); //cnt//wire [$clog2((DW_B+1)/2):0] cnt_nxt = curr_executing ? cnt+1 : 'h0; dff_with_en #( .DW($clog2((DW_B+1)/2)+1))dff_cnt( .clk (clk), .rst_n (rst_n), .enable (1'b1), .d_in (cnt_nxt), .q_out (cnt));

//get the awire [DW_A-1:0] a_d;wire [DW_A-1:0] nxt_a_d = nxt_executing ? a : a_d; dff_with_en #( .DW(DW_A))dff_a( .clk (clk), .rst_n (rst_n), .enable (1'b1), .d_in (nxt_a_d), .q_out (a_d));//radix 4 codingwire prd_r;wire [DW_A+DW_B+1:0] product;//wire [DW_B-1:0] b_shift;wire [2:0] m = is_executing ? {product[1:0],prd_r} : 3'b000; wire add_1 = (m == 3'b001) | (m == 3'b010);wire add_2 = (m == 3'b011);wire sub_1 = (m == 3'b110) | (m == 3'b101);wire sub_2 = (m == 3'b100); //wire [DW_A+DW_B+1:0] product; wire [DW_A+1:0] adder_op1 = ( {DW_A+2{add_1}}& { {2{a_d[DW_A-1]}},a_d} ) | ( {DW_A+2{add_2}}& { {1{a_d[DW_A-1]}},a_d,1'b0} ) | ( {DW_A+2{sub_1}}& (~{ {2{a_d[DW_A-1]}},a_d}) ) | ( {DW_A+2{sub_2}}& (~{ {1{a_d[DW_A-1]}},a_d,1'b0})); wire add_en = (add_1 | add_2 | sub_1 | sub_2)& is_executing;

wire noneed_add = is_executing & (~(add_1 | add_2 | sub_1 | sub_2)); wire [DW_A+1:0] adder_op2 = product[DW_A+DW_B+1:DW_B]; wire adder_cin = sub_1|sub_2; wire [DW_A+1:0] adder_res = adder_op1 + adder_op2 + adder_cin; wire [DW_A+DW_B+1:0] nxt_product = ({DW_A+DW_B+2{add_en}} &{{2{adder_res[DW_A+1]}},adder_res,product[DW_B-1:2]})| ({DW_A+DW_B+2{noneed_add}} & {{2{product[DW_A+DW_B+1]}},product[DW_A+DW_B+1:2]}) | ({DW_A+DW_B+2{o_valid}} & product) | ({DW_A+DW_B+2{nxt_executing}} & {{DW_A+2{1'b0}},b}); dff_with_en #( .DW(DW_A+DW_B+2))dff_product( .clk (clk), .rst_n (rst_n), .enable (1'b1),

.d_in (nxt_product), .q_out (product)); wire prd_nxt = curr_get_data ? 1'b0 : product[1]; dff_with_en #( .DW(1))dff_prd( .clk (clk), .rst_n (rst_n), .enable (1'b1), .d_in (prd_nxt), .q_out (prd_r));assign in_ready = curr_get_data;assign o_valid = exe_cnt_final;assign mul_res = product[DW_A+DW_B-1:0]; endmodule

如果乘数b位宽为奇数,请补一位符号位,变成偶数位宽,再输入。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5588

    浏览量

    129044
  • 计数器
    +关注

    关注

    32

    文章

    2306

    浏览量

    97564
  • 乘法器
    +关注

    关注

    9

    文章

    221

    浏览量

    38518

原文标题:比特对编码与比特对编码乘法器的设计

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    E203在基于wallace树+booth编码乘法器优化后的跑分结果

    优化思路 E203为了实现低功耗的要求,乘法器为基于booth编码和移位加法器结合的思路,优点是只需要一个加法器,而且该加法器还和除
    发表于 10-27 07:54

    E203V2长周期乘法器核心booth算法解读

    E203V2乘法器所在模块为e203_exu_alu_muldiv.v,其中包含乘法和除法两大块,这里仅对乘法模块进行解读。 乘法模块首先进行booth
    发表于 10-24 09:33

    蜂鸟E203乘法器的优化——基8的Booth编码+Wallace树

    考虑到蜂鸟原乘法器采用了基4的Booth编码,之后使用迭代的方法对每个周期使用加法器对部分积进行累加,结构如下: 从中考虑到两点优化: ① Booth编码的更改:(使用基8的Boot
    发表于 10-24 07:28

    Verilog实现使用Booth编码和Wallace树的定点补码乘法器原理

    周期乘法器乘法器,对于无符号乘法进行一位符号扩展后统一当作有符号数进行运算,因此需要17个迭代周期。为了改良乘法器性能,我们可以使用Booth编码
    发表于 10-23 08:01

    改进wallance树乘法器优化方法

    首先,根据之前分享的乘法器的优缺点,我们针对17周期的乘法器进行优化,为乘法设计的专用数据通路,为了保持e203的低功耗、低面积的优点、我们仍采用基4booth算法进行部分积生成,而对于原有的17
    发表于 10-23 06:37

    关于E203内核高性能乘法器优化(一)

    的一个部分积作为下个CSA的三个输入相加得到第二级两个部分积,按照这种操作一直进行,直到得到最终的两个部分积。 2.3Booth乘法器 Booth乘法器采用Booth算法对乘数进行编码,一次
    发表于 10-23 06:09

    蜂鸟乘法器设计分享

    蜂鸟的乘法器主体设计在ALU模块的子单元MDV模块中,MDV模块包括乘除法器逻辑设计,它只包含运算控制,但并不包含具体运算,它们都需要将部分积或者部分余数传入数据通路(dpath模块)中,从而实现
    发表于 10-22 08:21

    改进型乘法器结构设计

    的高32位。控制信号控制部分积产生和部分积压缩对操作数和部分积的处理,从而完成乘法器乘法运算。 译码模块对乘法指令进行译码,基4 Booth编码接收控制信号对被乘数和乘数进行符号扩
    发表于 10-22 07:51

    蜂鸟E203乘法器改进

    蜂鸟E203为了节约资源,乘法运算采用循环移位方式计算最终结果,这样的乘法器需要经过较多时钟周期来处理数据,导致处理数据效率较低。为了提高计算效率,这里分享一种基于流水线思想的乘法器,即采用多个
    发表于 10-22 07:28

    e203乘法运算结构及算法原理

    e203乘法部件结构 E203的乘法操作由一个17周期的乘法器实现。为了提升性能,该乘法器采用了基4Booth编码,将乘数分解为17个Bo
    发表于 10-22 06:43

    e203 ALU乘法运算结构及算法原理

    e203乘法部件结构 E203的乘法操作由一个17周期的乘法器实现。为了提升性能,该乘法器采用了基4Booth编码,将乘数分解为17个Bo
    发表于 10-22 06:12

    蜂鸟E203内核乘法器的优化

    乘法器的优化实现一般从两个方面入手。第一是减少生成的部分积数量,另外就是减少部分积累加的延时。 在开源的E203源码中,32*32乘法器是利用radix-4 booth编码产生部分积,每个周期做一次
    发表于 10-22 06:11

    优化boot4乘法器方法

    优化电路设计:在电路设计中,可以采用更快速的逻辑单元和存储器元件,优化关键路径和信号传输路线,从而降低延迟,缩短乘法器的运算周期。 固定位宽:Boot4乘法器可以处理不同位宽的数据,但是处理不同位宽
    发表于 10-21 12:13

    ADL5390 RF矢量乘法器技术手册

    ADL5390矢量乘法器由一对匹配的宽带可变增益放大器组成,二者输出相加,每个放大器具有单独的线性幅度增益控制。如果两个输入RF信号正交,则可以将该矢量乘法器配置为矢量调制器,或将增益控制引脚用作
    的头像 发表于 04-09 10:02 727次阅读
    ADL5390 RF矢量<b class='flag-5'>乘法器</b>技术手册

    ADA-28F00WG乘法器Marki

    ADA-28F00WG是一种高性能的模拟乘法器,能够将两个输入信号(电压或电流)进行乘法运算,并输出其结果。ADA-28F00WG乘法器采用高质量材料制造,并结合了最新的肖特基二极管和MMIC技术
    发表于 02-12 09:25