CPU设计实战-简单算术操作指令的实现

目录

一 简单算术操作指令的介绍

 1.add、addu、sub、subu、slt、sltu 指令

2.addi、addiu、slti、sltiu 指令

3.clo、clz 指令​编辑

 4.multu、mult、mul 指令.​编辑

二 译码阶段的实现

三 执行阶段的实现

1.加减运算

2.比较运算

3.计数运算

4.乘法运算

5.溢出情况

6.写入特殊寄存器的指令


一 简单算术操作指令的介绍

简单算术操作指令-共有15条,具体包括: add、 addi、 addiu、 addu、 sub、 subu、 clo、
clz、 slt、 slti、 sltiu、 stu、 mul、 mult、 multu, 各指令的格式及作用说明如下。

 1.add、addu、sub、subu、slt、sltu 指令


主要是加减和比较运算,需要注意的是,都分为有符号和无符号两种类型,有符号即需要判断正负,而且加法和减法指令还需要判断是否有溢出(符号位异常即可认为有溢出,如正正相加得负,负负相减的正),如果溢出就不写回目的地址。

2.addi、addiu、slti、sltiu 指令

 对立即数进行加法和比较,也注意都区分有无符号,并且加法也需要考虑溢出情况。

3.clo、clz 指令

 这两个指令是进行计数运算的。

指令1作用为:rd<-counleadingzerosrs,对地址为rs的通用寄存器的值,从其最高位开始向最低位方向检查,直到遇到值为“1”的位,将该位之前“0”的个数保存到地址为rd的通用寄存器中,如果地址为rs的通用寄存器的所有位都为0(即0x0000000),那么将32保存到地址为rd的通用寄存器中。

指令2作用为: rd <- coun_ leading_ ones rs,对地址为rs的通用寄存器的值,从其最高位开始向最低位方向检查,直到遇到值为“0”的位,将该位之前“1”的个数保存到地址为rd的通用寄存器中,如果地址为rs 的通用寄存器的所有位都为1 (即OFFFFFF),那么将32保存到地址为rd的通用寄存器中。
 

 4.multu、mult、mul 指令
.

 这三条都是乘法指令,第一条做简单的有符号相乘,保存到通用寄存器中。后两条区分有无符号且将结果保存到特殊寄存器hilo中,低32位保存到lo中,高32位保存到hi中。

二 译码阶段的实现

这种R类型两个寄存器都要读且需要写回通用寄存器,故译码阶段的信号都赋值如下(除了op):

除了clz和clo有点特殊,rt寄存器没有用,只读了rs寄存器并且写回通用寄存器rd:

 此类型两个寄存器都要读但是不写回通用寄存器而是特殊寄存器,赋值如下:

 

 I型指令需要对立即数进行有符号扩展操作,只需要读第一个寄存器,写回通用寄存器rt:

三 执行阶段的实现

执行阶段才是重点,需要重点注意的点如下,在思考是要全面考虑多种情况:

1.加减运算

如何同时实现加减运算,可以通过补码的方式,对于需要减法的指令sub,subu,slt对操作数2加上补码(取反+1)否则保持原样。

这个时候sum的结果就可以同时实现加减法运算:

2.比较运算

比较运算分为有符号和无符号比较,主要实现计算操作数1是否小于操作数2,分以下几种情况讨论什么条件下操作数1小于操作数2:

有符号时:

1.一负一正,显然成立

2.都是正,减法结果为负时成立(看最高的符号位即可,使用上面说过的加减法操作即可)

3.都是负,减法结果为负时成立

无符号时直接使用<判断

 

3.计数运算

clz:从其最高位开始向最低位方向检查,直到遇到值为“1”的位,将该位之前“0”的个数保存到地址为rd的通用寄存器中,如果地址为rs的通用寄存器的所有位都为0(即0x0000000),那么将32保存到地址为rd的通用寄存器中。

 clo:从其最高位开始向最低位方向检查,直到遇到值为“0”的位,将该位之前“1”的个数保存到地址为rd的通用寄存器中,如果地址为rs 的通用寄存器的所有位都为1 (即OFFFFFF),那么将32保存到地址为rd的通用寄存器中。

4.乘法运算

我们来考虑乘法运算的几种情况:

1.正正为正,负负为正

2.一正一负为负

所以我们可以先取出乘数和被乘数的绝对值(即如果是负数就取其补码,正数不变),再根据他们的符号进行判断最终的符号。

先取出绝对值,主要是对负数的做补码:

然后根据两个乘法的符号判断最终的结果,用逻辑原来说如果符号位不同(考虑到异或0,即输出补码,如果相同即不变。

5.溢出情况

我们之前在指令中知道加减法都有溢出判断,如果溢出就不写回结果。

那么如何判断溢出呢,可以根据异常的符号来判断:

如果溢出就不写回目的寄存器,即对写回使能进行赋值:

6.写入特殊寄存器的指令

我们知道mult和multu指令是将乘法的结果写入特殊寄存器hilo的,那么还需要对最终的hilo的相关信号的输出进行赋值,hi写乘法结果高位,lo写低位:

以上,简单的算术操作实现就完成了,我们需要重点关注执行阶段的实现,要全面考虑相关指令的各种情况,争取可以统一他们的输出,从而简化代码,提高效率。

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值