news 2026/3/3 18:59:21

tinyriscv执行模块讲解3(除法运算2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tinyriscv执行模块讲解3(除法运算2)

写在前面

  • 前面执行模块对于除法计算只做流水线控制和参数传递,具体的除法计算由DIV除法模块来完成。该模块作者使用试商法实现,所以在开始前先了解下试商法怎么进行除法计算。
    有VIP的同学可以看一下这篇文章,可能会讲解得更加详细:https://blog.csdn.net/m0_71078397/article/details/126610918

  • 试商法是一种用于除法运算的算法,特别适用于硬件实现(如FPGA、CPU等)。它的核心思想是通过试探和修正的方式逐位确定商的值。

  • 基本公式:
    被除数 ÷ 除数 = 商 … 余数

  • 基本思想:从最高位开始,每次确定商的一位。
    1、猜测当前位的商值
    2、用猜测值乘以除数
    3、比较乘积与被除数(或当前余数)
    4、根据比较结果调整商值

  • 十进制举例(100 / 7):

  • 二进制举例(100 / 7):

    call in:作者为什么说除法至少需要33个时钟周期。这里试商法对于32位数的除法而言需要迭代处理32次,即每一位都需要迭代一次。

1、RISC-V32位除法指令

DIV:有符号除法(商) DIVU:无符号除法(商) REM:有符号取余(余数) REMU:无符号取余(余数)

2、除法模块接口定义

input wire clk,input wire rst,// from exinput wire[`REG_BUS]dividend_i,// 被除数input wire[`REG_BUS]divisor_i,// 除数input wire start_i,// 开始信号,运算期间这个信号需要一直保持有效input wire[2:0]op_i,// 具体是哪一条指令input wire[`REG_ADDR_BUS]reg_waddr_i,// 运算结束后需要写的寄存器// to exoutput reg[`REG_BUS]result_o,// 除法结果,高32位是余数,低32位是商output reg ready_o,// 运算结束信号output reg busy_o,// 正在运算信号output reg[`REG_ADDR_BUS]reg_waddr_o// 运算结束后需要写的寄存器

该模块只和执行模块交换数据,所以接口只用定义与执行模块数据交换即可。

3、除法器状态机状态定义

// 状态定义localparam STATE_IDLE=4'b0001;//空闲localparam STATE_START=4'b0010;//开始localparam STATE_CALC=4'b0100;//计算中localparam STATE_END=4'b1000;//结束

4、中间运算变量

reg[`REG_BUS]dividend_r;//被除数reg[`REG_BUS]divisor_r;//除数reg[2:0]op_r;//指令reg[3:0]state;//状态机状态reg[31:0]count;reg[`REG_BUS]div_result;//除法结果reg[`REG_BUS]div_remain;//除法结果余数reg[`REG_BUS]minuend;//余数reg invert_result;//结果的补码形式wire op_div=(op_r==`INST_DIV);wire op_divu=(op_r==`INST_DIVU);wire op_rem=(op_r==`INST_REM);wire op_remu=(op_r==`INST_REMU);

5、试商法除法的核心计算部分

wire[31:0]dividend_invert=(-dividend_r);//等价于dividend_invert = ~dividend_r + 32'b1wire[31:0]divisor_invert=(-divisor_r);//取二进制补码wire minuend_ge_divisor=minuend>=divisor_r;//比较部分余数 minuend 是否大于等于除数 divisor_rwire[31:0]minuend_sub_res=minuend-divisor_r;//wire[31:0]div_result_tmp=minuend_ge_divisor?({div_result[30:0],1'b1}): ({div_result[30:0], 1'b0});//若部分余数大于等于除数,则余数更新为余数减除数的差值,否则余数不变wire[31:0]minuend_tmp=minuend_ge_divisor?minuend_sub_res[30:0]:minuend[30:0];

div_result_tmp:在余数大于等于除数时,在对应位上商1,否则商0。

6、除法状态机

1. 复位

if(rst==`RESET_EN)begin state<=STATE_IDLE;ready_o<=`DIV_RESULT_NOT_READY;//除法结果是否完成result_o<=`ZERO_WORD;//存储最终的除法结果(商或余数)div_result<=`ZERO_WORD;//存储计算过程中的商div_remain<=`ZERO_WORD;op_r<=3'h0;reg_waddr_o<=`ZERO_WORD;//除法结果-写地址dividend_r<=`ZERO_WORD;divisor_r<=`ZERO_WORD;minuend<=`ZERO_WORD;//存储当前的部分余数(被减数)invert_result<=1'b0;// 结果取反标志busy_o<=`FALSE;//除法器是否正在工作count<=`ZERO_WORD;//控制32次迭代的计数器end

2. 空闲状态

STATE_IDLE:beginif(start_i==`DIV_START)begin op_r<=op_i;dividend_r<=dividend_i;divisor_r<=divisor_i;reg_waddr_o<=reg_waddr_i;state<=STATE_START;busy_o<=`TRUE;endelsebegin op_r<=3'h0;reg_waddr_o<=`ZERO_WORD;dividend_r<=`ZERO_WORD;divisor_r<=`ZERO_WORD;ready_o<=`DIV_RESULT_NOT_READY;result_o<=`ZERO_WORD;busy_o<=`FALSE;end end

当接收到开始信号时,将参与运算的变量进行初始化,并对外发出“忙”信号(busy_o),后将状态机状态切换位开始状态。
3、开始状态

STATE_START:beginif(start_i==`DIV_START)begin// 除数为0if(divisor_r==`ZERO_WORD)beginif(op_div|op_divu)begin result_o<=32'hffffffff;//若指令为除法运算则返回全1--无限大endelsebegin result_o<=dividend_r;//若为取余数运算则返回取余本身end ready_o<=`DIV_RESULT_READY;//完成计算state<=STATE_IDLE;busy_o<=`FALSE;// 除数不为0endelsebegin busy_o<=`TRUE;count<=32'h40000000;//计数器初始化--第31位为1,右移32位后为0state<=STATE_CALC;//状态机切换为计算div_result<=`ZERO_WORD;div_remain<=`ZERO_WORD;// DIV和REM这两条指令是有符号数运算指令if(op_div|op_rem)begin// 被除数求补码if(dividend_r[31]==1'b1)begin//被除数为负数时取二进制补码dividend_r<=dividend_invert;minuend<=dividend_invert[31];endelsebegin minuend<=dividend_r[31];end// 除数求补码if(divisor_r[31]==1'b1)begin divisor_r<=divisor_invert;end endelsebegin minuend<=dividend_r[31];end// 运算结束后是否要对结果取补码if((op_div&&(dividend_r[31]^divisor_r[31]==1'b1))//异或运算,若除数与被除数符号不同则为1,标记结果符号为负号||(op_rem&&(dividend_r[31]==1'b1)))begin invert_result<=1'b1;endelsebegin invert_result<=1'b0;end end endelsebegin state<=STATE_IDLE;result_o<=`ZERO_WORD;ready_o<=`DIV_RESULT_NOT_READY;busy_o<=`FALSE;end end

执行操作:
1、处理除数为0的情况(除法计算返回全1,取余运算返回本身)。
2、除数不为0,初始化迭代计数器(count <= 32’h40000000),将状态切换为计算状态。
3、对于操作数中存在负数情况时,对其取补码。
4、判断运算结果的符号,并标记(invert_result )。

4、计算状态

STATE_CALC:beginif(start_i==`DIV_START)begin dividend_r<={dividend_r[30:0],1'b0};//被除数左移一位div_result<=div_result_tmp;//保存运算中间结果count<={1'b0,count[31:1]};//计数器右移if(|count)begin minuend<={minuend_tmp[30:0],dividend_r[30]};endelsebegin state<=STATE_END;if(minuend_ge_divisor)begin div_remain<=minuend_sub_res;endelsebegin div_remain<=minuend;end end endelsebegin state<=STATE_IDLE;result_o<=`ZERO_WORD;ready_o<=`DIV_RESULT_NOT_READY;busy_o<=`FALSE;end end

结合计算部分迭代32次,完成计算。
5、完成状态

STATE_END:beginif(start_i==`DIV_START)begin ready_o<=`DIV_RESULT_READY;state<=STATE_IDLE;busy_o<=`FALSE;if(op_div|op_divu)beginif(invert_result)begin result_o<=(-div_result);endelsebegin result_o<=div_result;end endelsebeginif(invert_result)begin result_o<=(-div_remain);endelsebegin result_o<=div_remain;end end endelsebegin state<=STATE_IDLE;result_o<=`ZERO_WORD;ready_o<=`DIV_RESULT_NOT_READY;busy_o<=`FALSE;end end

结合符号标记(invert_result)和指令为结果输出赋值,并向执行模块发送完成信号。

https://gitee.com/liangkangnan/tinyriscv

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/27 12:57:29

显卡驱动彻底清理指南:3步用DDU解决残留问题

当你的游戏帧数莫名下降、新驱动安装失败或系统频繁蓝屏时&#xff0c;很可能是因为显卡驱动残留文件在作祟。Display Driver Uninstaller&#xff08;DDU&#xff09;作为专业的驱动清理工具&#xff0c;能够彻底解决这些系统性能问题&#xff0c;实现真正的显卡优化。 【免费…

作者头像 李华
网站建设 2026/2/27 20:14:17

Java毕设项目推荐-基于JavaWeb的心聘求职平台的设计与实现求职就业平台设计与实现【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/2 2:41:46

XUnity自动翻译插件:零基础入门到实战精通指南

XUnity自动翻译插件&#xff1a;零基础入门到实战精通指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator Unity游戏玩家们&#xff0c;你是否曾因语言障碍而错过精彩的外文游戏&#xff1f;XUnity Auto …

作者头像 李华
网站建设 2026/2/28 22:33:33

OBS直播优化全攻略:从新手到专家的配置进阶之路

OBS直播优化全攻略&#xff1a;从新手到专家的配置进阶之路 【免费下载链接】obs-studio 项目地址: https://gitcode.com/gh_mirrors/obs/obs-studio 你是不是经常遇到这样的困扰&#xff1f;直播画面卡顿、音频有杂音、场景切换不流畅...别担心&#xff0c;今天我将带…

作者头像 李华
网站建设 2026/2/26 19:13:34

面试问题预测:LobeChat模拟真实考场

面试问题预测&#xff1a;LobeChat模拟真实考场 在技术岗位的求职战场上&#xff0c;一场高质量的面试往往决定了职业发展的走向。然而&#xff0c;大多数候选人在准备过程中仍依赖刷题网站和静态问答库——这些工具虽然能帮助记忆知识点&#xff0c;却无法还原真实面试中那种层…

作者头像 李华