Bonky Zhu
If someone is able to show me that what I think or do is not right, I will happily change, for I seek the truth, by which no one was ever truly harmed. It is the person who continues in his self-deception and ignorance who is harmed.

计算机组成 – 计算方法

计算机组成 - 数字

定点表示和浮点表示

定点表示

一般来说对于纯小数和纯整数,他们的小数点是固定的:

浮点表示

  • 上溢:阶码 > 最大阶码
  • 下溢:阶码 < 最小阶码 (按机器零处理)

规格化形式

基数不同,浮点数的规格化形式不同

  • r=2:尾数最高位为 1
  • r=4:尾数最高 2 位不全为 0
  • r=8:尾数最高 3 位不全为 0

机器零

有两种情况:

  • 当浮点数尾数为 0 时,不论其阶码为何值按机器零处理
  • 当浮点数阶码等于或小于它所表示的最小数 时,不论尾数为何值,按机器零处理

IEEE 754 标准

注意只要这个数非0,那么他的尾数一定最高位为1

有一些特殊的值:

定点数运算

移位运算

算术移位

算术移位是有符号的移位。符号位不变,其他的按照以下规则进行移位。

硬件实现

逻辑移位

逻辑移位是无符号的移位。往哪移移动的末端加0,首段直接丢弃。

  • 逻辑左移:低位添 0, 高位移丢
  • 逻辑右移:高位添 0, 低位移丢

加减法

利用补码进行运算,连同符号位一起相加,符号位产生的进位自然丢掉。

溢出判断

一位符号位判溢出

如果最高有效位的进位与符号位的进位不同,这说明溢出,否则就是无溢出。

两位符号位判溢出

硬件结构

上面那个 A 是 ACC,累加器(寄存器),存放被加数或者被减数,下面那个X 是一个任意寄存器,存放减数和加数。Gs 判断是否为减法运算,用来控制控制求补逻辑。

乘法

笔算乘法的改进

我们可以这么改进一般笔算乘法。一开始部分积为0,

  1. 上面得到的部分积 + 被乘数A * 乘数没有被乘的最后一位
  2. 把得到的结果右移一位,得新的部分积。

重复上面步骤,得到结果后还需要右移一位。这个实际上把乘法转换为加法和移位运算。下面是改进后的算法的竖式计算过程:

上图所示,第一步由于乘数最后为1,初始的部分积为1,所以我们进行 A *1+0=0.1101,然后得到的结果右移 0.0110,乘数的倒数第二位为 1,所以 A*1+0.0110=1.0011,第三步同理 A*0+0.1001=0.1001,第四步 A*1+0.0100=1.0001,最后再右移一位为 0.1000 (注意乘数左边那部分黑色字体,其实是部分积右移移出的那一位到了乘数的左边)

所以上面最后的结果就是黑色的那一些 0.10001111

原码乘法

  • 乘积的符号位单独处理:
  • 数值部分为绝对值相乘:,和上面的笔算乘法的改进相同。


Q 是存乘数的,其中最后一位 n 来决定是否把 X 送入加法器,如果 n 是 1,则控制器将 X 送入加法器,否则把 0 送入加法器或者直接移位,不进行运算。然后把运算后的结果送入 A 中,然后进行右移,A 被移出的位送入 Q 中。(因为控制门有计数器,所以不会一直右移)

补码乘法

有以下两种情况:

  • 被乘数任意,乘数为正:与原码乘相似,但加和移位按补码规则运算,乘积的符号自然形成。
  • 被乘数任意,乘数为负:乘数 [y]补 ,去掉符号位,操作同上,最后加[–x]补 ,校正。这么做的原因如下:

Booth 算法

上面那种方法的话缺点就是太复杂了,导致硬件如果设计的话会特别复杂。然后就提出了 Booth 算法,被乘数、乘数符号可以位任意任意值。上面的算法我们可以总结为

我们发现我们可以改成以下形式

 

所以我们可以有:

Booth 算法递推公式如下:

当 y 的当前位和后一位相等时,直接移位,如果当前位为1,下一位为0,则加上 x 的补码,如果当前位为0,下一位为1,则加上 -x 的补码

下面是一个例题:在计算过程中,首先需要求出x,y,-x 的补码。可以发现第一步是10,所以我们就加上 -x 的补码,再进行算术右移(即负数则补1,否则补0),第二步是 01,所以加上 x 的补码

硬件结构如下:

除法

恢复余数法

基本算法是:每次减去除数,即加上-y 的补码,然后如果是负数就上商0(在商的最后加上0),接着加上 y 的补码(恢复余数),如果是正数就就加上商1。

然后在进行逻辑左移(商也要左移)。最后,商里面为商,被除数里面为余数。

不恢复余数法

恢复余数法可以总结为以下:如果余数大于0,先左移,再减去 y,如果小于0的话,则恢复余数,恢复余数后再左移(相当于乘2),再减。那么我们可以总结为:

硬件配置如下:

补码的除法

其实呢和不恢复余数法也差不多,只需要修改下符号的判断(是否能减),方法如下:

即我得到的余数(减完之后的那个数)和减去的那个数如果符号相同,那么就给个1,否则给0

补码除法和原码除法的比较

补码除不需要管符号位,然后他们的第一步操作有点区别,其他都一样。

浮点数运算

对阶

第一步,求阶差。第二步,根据小阶向大阶对齐(因为要右移,即使丢了也是很小的,即丢失精度)

下面这是一个例子:

规范化

可以发现,上面的没有进行规格化:

  • 原码:不论正数、负数,第一数位为1
  • 补码,反码:符号位和第一数位不同,如 1.100 是不可行的,1.000 是规格化的数

规范化的方法为左规和右规:

  • 左规:尾数左移一位,阶码减 1,直到数符和第一数位不同为止(当第一位为0的时候使用左规)
  • 右规:当尾数溢出时(出现 01.××…×或 10. ××…×时),需右规。尾数右移一位,阶码加 1。

舍入

在对阶和右规过程中,可能出现尾数末位丢失引起误差,需考虑舍入

  • 0 舍 1 入法:此方法类似于十进制的四舍五入法,即在尾数右移时,被移去的最高数值位为 0, 则舍去。被移去的最高数值位为 1, 则在尾数未尾加 1 这样做可能使尾数又溢出,此时需要再做一次右规。
  • 恒置 1 法:尾数右移时,不论丟掉的最高数值位是一还是零,都使右移后的尾数末位恒置一。

浮点乘除运算

其实差不多,和前面整数的乘法除法思路一样:

运算器的组成与结构

加法器

一位加法器

其实只要把真值表画出就可以知道公示了,然后 C 代表的是进位

串行加法器

把多个一位加法器拼在一起就是串行的进位加法器,其中的进位链是串行的:

并行加法器

我们可以得到进位的表达式如下

于是我们可以得到并行进位加法器如下:

分组并行进位

组内并行,组间串行的进位链:

组内并行,组间并行的进位链:

可以发现只和 C0 有关,和前面几个状态都没关。可以得到进位芯片如下:

上面的芯片输入 G 和 P 输出的为 D 和 T ,和其它位的所有进位。

ALU 算术逻辑单元

以 SN74181 为例:

由于S0~S3 有16种状态组合,因此 74181 有 16 种算术运算功能和 16 种逻辑运算功能。

控制端M用来控制作算术运算还是逻辑运算:M=0 时,为算术运算,M=1时,为逻辑运算。

可以多个组成一个十六位的 ALU(下图的 74182 是一个先行进位发生器):

定点运算器

运算器的内部总线结构

单总线结构:

计算R0+R1→R0的步骤如下:

(1) R0→A (2) R1→B    (3) ALU(A+B)→R0


双总线结构:

计算R0+R1→R0的步骤如下:

(1) R0通过总线1→ALU  (2) R1通过总线2→ALU (3) ALU(A+B)→缓冲器T(直接给R0的话可能会覆盖总线上内容)    (4) T→R0


三总线结构:

(1)R0通过总线1→ALU   (2)R1经过总线2送ALU  (3)ALU(A+B)通过总线3送到R0中


浮点运算器

浮点运算器(floating point unit,FPU)的基本结构如下图。 浮点运算可用两个松散连接的定点运算器部件来实现,即阶码部件EU和尾数部件MU。

 

Share

You may also like...

发表评论