RISC-V MCU中文社区

【分享】 蜂鸟E203乘法器代码注释

发表于 开源蜂鸟E203 2023-05-31 11:01:49
0
1445
0

团队名称:芯火

团队编号:CICC1181



// Use booth-4 algorithm to conduct the multiplication计算部分积

  /***

  wire [32:0] part_prdt_hi_r; //高位信息(即操作数相加后从dpath返回的信息)

  wire [32:0] part_prdt_lo_r;  //低位信息(即需要右移的信息,参见蜂鸟书中153页图右移1位下面的框)

  wire [32:0] part_prdt_hi_nxt; //更新后的高低位信息

  wire [32:0] part_prdt_lo_nxt;

 

  wire part_prdt_sft1_r;

  wire [2:0] booth_code = cycle_0th  ? {muldiv_i_rs1[1:0],1'b0} // cycle0低位补0,高位补符号位,取后三位作为编码

                        : cycle_16th ? {mul_rs1_sign,part_prdt_lo_r[0],part_prdt_sft1_r} //周期结束,根据Booth算法补符号位与最后的低位信息

                        : {part_prdt_lo_r[1:0],part_prdt_sft1_r}; //取后两位并补低位形成3boothcode

      //booth_code == 3'b000 =  0  参考booth算法编码表

      //booth_code == 3'b001 =  1

      //booth_code == 3'b010 =  1

      //booth_code == 3'b011 =  2

      //booth_code == 3'b100 = -2

      //booth_code == 3'b101 = -1

      //booth_code == 3'b110 = -1

      //booth_code == 3'b111 = -0

  wire booth_sel_zero = (booth_code == 3'b000) | (booth_code == 3'b111);

  wire booth_sel_two  = (booth_code == 3'b011) | (booth_code == 3'b100);

  wire booth_sel_one  = (~booth_sel_zero) & (~booth_sel_two);

  wire booth_sel_sub  = booth_code[2];  

 

  // 35 bits adder needed乘法中加减法操作数生成

  wire [`E203_MULDIV_ADDER_WIDTH-1:0] mul_exe_alu_res = muldiv_req_alu_res; //取出返回值也即高位数值

  wire [`E203_MULDIV_ADDER_WIDTH-1:0] mul_exe_alu_op2 =

      ({`E203_MULDIV_ADDER_WIDTH{booth_sel_zero}} & `E203_MULDIV_ADDER_WIDTH'b0)  //0*=0

    | ({`E203_MULDIV_ADDER_WIDTH{booth_sel_one }} & {mul_rs2_sign,mul_rs2_sign,mul_rs2_sign,muldiv_i_rs2}) //数字不变,仅符号拓展

    | ({`E203_MULDIV_ADDER_WIDTH{booth_sel_two }} & {mul_rs2_sign,mul_rs2_sign,muldiv_i_rs2,1'b0}) //2则左移一位,符号位不变

      ;

  wire [`E203_MULDIV_ADDER_WIDTH-1:0] mul_exe_alu_op1 =  //cycle0时,装入全0,后面填入乘数,参加蜂鸟书中153页部分积指向加法器的线路

       cycle_0th ? `E203_MULDIV_ADDER_WIDTH'b0 : {part_prdt_hi_r[32],part_prdt_hi_r[32],part_prdt_hi_r};  

  wire mul_exe_alu_add = (~booth_sel_sub);//dpath指示信号生成

  wire mul_exe_alu_sub = booth_sel_sub;

 

  wire mul_exe_alu_mul = cycle_0th  ? 1'b0 //周期结束信号

                        : cycle_16th ? 1'b1

                        : 1'b0;

 

  assign part_prdt_hi_nxt = mul_exe_alu_res[34:2]; //下一个部分积, 传入dpath保存

  assign part_prdt_lo_nxt = {mul_exe_alu_res[1:0], //同理,只不过每次右移两位

                         (cycle_0th ? {mul_rs1_sign,muldiv_i_rs1[31:2]} : part_prdt_lo_r[32:2])

                         };

  wire part_prdt_sft1_nxt = cycle_0th ? muldiv_i_rs1[1] : part_prdt_lo_r[1]; //muldiv_i_rs1=10,首先在后面补0,此时为100,这样muldiv_i_rs1[1]即为右移两位后的末位,part同理

 

  wire mul_exe_cnt_set = exec_cnt_set & i_op_mul; //控制最后一位的更新

  wire mul_exe_cnt_inc = exec_cnt_inc & i_op_mul;

 

  wire part_prdt_hi_ena = mul_exe_cnt_set | mul_exe_cnt_inc | state_exec_exit_ena;//使能信号,控制传入dpath进行更新,dpath会传回最新的乘积信息

  wire part_prdt_lo_ena = part_prdt_hi_ena;

 

  sirv_gnrl_dfflr #(1) part_prdt_sft1_dfflr (part_prdt_lo_ena, part_prdt_sft1_nxt, part_prdt_sft1_r, clk, rst_n);

 

    // This mul_res is not back2back case, so directly from the adder result  若不是back2back情况,可以直接取出,Booth编码运算后最终结果取[32:1]

  wire[`E203_XLEN-1:0] mul_res = i_mul ? part_prdt_lo_r[32:1] : mul_exe_alu_res[31:0];

 

喜欢0
用户评论
wxy111

wxy111 实名认证

懒的都不写签名

积分
问答
粉丝
关注
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板