从零开始设计riscv cpu记录之五

发布时间:2026/7/11 2:24:56

从零开始设计riscv cpu记录之五 一、在测试mulhsu不通过其余的mul 、mulh、 mul都通过这是为什么指令含义mulh有符号 × 有符号取高 32 位mulhsu有符号 × 无符号取高 32 位mulhu无符号 × 无符号取高 32 位mul有符号/无符号 × 有符号/无符号取低 32 位二、对我来说是认知之外的原因三、ex.v中乘法的实现分成散步第一步先取到操作数的有符号格式wiresigned[DW-1:0]op1_signed$signed(op1_i);wiresigned[DW-1:0]op2_signed$signed(op2_i);第二步按照表格中规定的计算乘积比如mul无符号相乘就是op1_i * op2_i其他的方法也一样wire[DW*2-1:0]mul_resultop1_i*op2_i;wire[DW*2-1:0]mulh_resultop1_signed*op2_signed;wire[DW*2-1:0]mulhsu_resultop1_signed*op2_i第三步取32位高32位或低32位INST_MUL:begin reg_wdata_omul_result[31:0];end INST_MULH:begin reg_wdata_omulh_result[63:32];end INST_MULHSU:begin reg_wdata_omulhsu_result[63:32];end INST_MULHU:begin reg_wdata_omul_result[63:32];四、思路清晰感觉不会出错但是忽略了verilog的乘法规则五、mulhsu的错误原因mulhsu要求的是有符号数 × 无符号数但op1_signed * op2_i这种写法在 Verilog 里会被当成无符号 × 无符号来算。六、Verilog 的混合符号乘法规则Verilog 规定一个表达式里只要有一个操作数是无符号的整个表达式就按无符号运算处理。七、正确做法wire[DW*2-1:0]mulhsu_result$signed({{32{op1_i[31]}},op1_i})*$signed({32b0,op2_i});含义{{32{op1_i[31]}}, op1_i}把op1_i按有符号数符号扩展到 64 位。{32b0, op2_i}把op2_i按无符号数零扩展到 64 位。两个 64 位数相乘取高 32 位就是mulhsu的正确结果。八、改完之后测试结果PASS

相关新闻