news 2026/5/1 8:46:34

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/4/28 0:40:17

Java毕设项目推荐-基于Vue+SpringBoot的餐厅信息管理系统基于java的餐厅信息管理系统设计【附源码+文档,调试定制服务】

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

作者头像 李华
网站建设 2026/5/1 7:24:00

通用汽车推出原生Apple Music应用并支持空间音频

现在&#xff0c;通用汽车为其车主带来了一个好消息&#xff1a;从今天开始&#xff0c;特定凯迪拉克车型将推出全新的Apple Music应用。通用汽车表示&#xff0c;新的原生Apple Music应用将从周一开始向"特定的2025年及更新款凯迪拉克和雪佛兰车型"推出。我们仍在等…

作者头像 李华
网站建设 2026/5/1 7:28:53

Java毕设项目推荐-基于java+springboot的推荐算法的图书推荐系统基于java的畅销图书推荐系统【附源码+文档,调试定制服务】

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

作者头像 李华
网站建设 2026/4/26 11:52:17

Java毕设项目推荐-基于javaweb的宠物托管系统基于Spring Boot的宠物托管服务系统服务预约、监控宠物状况、与服务提供者沟通【附源码+文档,调试定制服务】

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

作者头像 李华
网站建设 2026/5/1 8:37:04

停止将AI拟人化:这样做的危害性分析

在让AI模型显得越来越令人印象深刻的竞赛中&#xff0c;科技公司采用了戏剧化的语言表达方式。他们不断地像谈论人类一样谈论AI。不仅讨论AI的"思考"或"规划"——这些词语本身就充满争议——现在他们还讨论AI模型的"灵魂"&#xff0c;以及模型如…

作者头像 李华
网站建设 2026/5/1 7:23:57

对称二叉树(tree_c)(信息学奥赛一本通- P1368)

【题目描述】如果二叉树的左右子树的结构是对称的&#xff0c;即两棵子树皆为空&#xff0c;或者皆不空&#xff0c;则称该二叉树是对称的。编程判断给定的二叉树是否对称.例&#xff1a;如下图中的二叉树T1是对称的&#xff0c;T2是不对称的。二叉树用顺序结构给出&#xff0c…

作者头像 李华