COP实现补码Booth乘法.docx
《COP实现补码Booth乘法.docx》由会员分享,可在线阅读,更多相关《COP实现补码Booth乘法.docx(16页珍藏版)》请在冰豆网上搜索。
COP实现补码Booth乘法
课程设计名称:
计算机组成原理课程设计
课程设计题目:
COP2000实现补码Booth乘法
第1章总体设计方案
1.1设计原理
课程设计内容:
利用COP2000的指令集编程实现两个7bit(含1bit符号位)补码相乘的功能,要求被乘数,乘数是7bit补码,乘积是13位补码。
实现任务的基本原理是Booth算法。
1.2设计思路
Booth补码一位乘的设计主要包括五个功能模块。
①初始化:
完成部分积,附加位,循环次数的初始化。
②求和:
根据YnYn+1的值选择部分积和[X]补、[-X]补或是0相加。
③右移:
完成部分积和乘数部分整体右移一位,其中部分积是算术右移。
④判断循环次数:
完成一次求和和右移操作后循环次数减一,最后一次只求和不进行右移操作。
⑤结果输出:
将部分积和乘数部分分别保存到内存中。
1.3设计环境
本次课程设计的环境是COP2000实验平台自带的集成开发环境,允许用户进行程序的编写、模拟运行、观察数据通路等操作。
COP2000实验平台对应的模型机为8位机,数据总线和地址总线均为8位。
它包括了一个标准CPU所具备的所有部件,这些部件包括:
运算器ALU、累加器A、工作寄存器W、左移门L、直通门D、右移门R、寄存器组R0~R3、程序计数器PC、地址寄存器MAR、堆栈寄存器ST、中断向量寄存器IA、输入端口IN、输出端口寄存器OUT、程序存储器EM、指令寄存器IR、微程序计数器uPC、微程序存储器uM等。
此次课设是使用COP2000的指令集编程,所使用的部分指令如下:
ADDA,R?
;将寄存器R?
中的值送到累加器A中
ADDA,MM;将存储器MM地址中的值送到累加器A中
ADDA,#II;将立即数II加到累加器中
SUBA,#II;从累加器A中减去立即数II加入累加器A中
ANDA,#II;累加器A“与”立即数II
ORA,#II;累加器A“或”立即数II
MOVA,R?
;将寄存器R?
的值送到累加器A中
MOVA,MM;将存储器MM地址中的值送到累加器A中
MOVA,#II;将立即数II送到累加器A中
MOVMM,A;将累加器A中的值送到存储器MM地址中
MOVR?
,#II;将立即数II送到寄存器R?
中
JZMM;若零标志位置1,跳转到MM地址
JMPMM;跳转到MM地址
IN;从输入端口读入数据到累加器A中
OUT;将累加器A中的数据输出到输出端口
RRA;累加器A右移
CPLA;累加器A取反,再存入累加器A中
第2章详细设计方案
2.1各功能模块详细设计方案
2.1.1总体设计方案
由于Booth补码一位乘里包含部分积,乘数的补码[Y]补,附加位Yn+1,被乘数的补码[X]补,被乘数的相反数的补码[-X]补,还有循环次数n。
用寄存器R0保存部分积,R1保存循环的次数,R2保存输入的被乘数,R3保存输入的乘数,存储器0F0H地址空间内中保存的是被乘数的补码[X]补,0F1H中保存的是被乘数相反数的补码[-X]补,0F2H中保存乘数的补码,0F3H中保存附加位Yn+1,最后的结果部分积保存在0E0H中,乘数部分保存在0E1H中。
由于被乘数和乘数都是包含符号位在内的7位补码,乘积是包含符号位在内的13位补码,其中前7位来自部分积的低7位,后6位来自乘数部分的前6位。
2.1.2初始化模块设计方案
初始化部分应该完成部分积和附加位Yn+1的初始化,即R0初始化为0,0F3H初始化为0,并且循环次数初始化为6,即R1被初始化为6(因为乘数和被乘数都是包含符号位在内的7位补码,因此循环次数为6)。
之后还应该完成被乘数和乘数的输入,分别将被乘数和乘数的补码存放到R2和R3中。
接着判断被乘数的正负,将被乘数的补码及其相反数的补码以双符号位的形式存放到0F0H和0F1H中(正数的双符号位是00,负数的双符号位是11,运算过程中采用双符号位是为了防止假溢出,其最高位才是真正的符号位),最后将乘数的补码存到0F2H中。
2.1.3求和模块设计方案
根据乘数部分的最低位Yn和附加位Yn+1的值来确定部分积和哪个数相加,
当YnYn+1是00时,部分积加0;YnYn+1是01,部分积加[X]补;YnYn+1是10时,部分积加[-X]补;YnYn+1是11,部分积加0。
判断YnYn+1的值的过程如下,先判断Yn的值,接着再判断附加位Yn+1,若部分积加0,则直接进入下一模块,即右移模块,否则,部分积加上[X]补或[-X]补再进入下一模块。
在求和过程中使用双符号位补码。
2.1.4右移模块设计方案
右移过程需将部分积和乘数部分整体右移一位,部分积的右移是算术右移,即要保留符号位,部分积的最低位应移到乘数部分的最高位,乘数部分的最低位应移到附加位部分,由于部分积、乘数、附加位是分开存放的,如果直接移位会导致最低位丢失数据。
因此应该先将乘数的最低位保存到附加位,再将乘数右移一位,之后将部分积最低位保存到乘数的最高位,再将部分积右移。
但由于部分积采用双符号位运算,部分积在移位之后要判断次高位是0还是1,若是0,说明原来的部分积是正数,应将部分积的最高位写成0,否则,说明部分积原来是负数,应将最高位写成1。
右移完之后接循环模块。
2.1.5判断循环次数模块设计方案
当求和和右移运行完成后,就完成了一次循环,这时循环次数应该减一,接着判断是否是最后一次循环,若不是最后一次循环,转去执行求和模块,再执行右移模块,若是最后一次循环,则只执行求和模块而不再右移,接着转输出模块。
2.1.6结果输出模块设计方案
要求结果是包含符号位在内的13位补码,对于部分积,先将后六位数保留再判断部分积的最高位的符号,若是1,将部分积的次高位写为1,若是0,将部分积的次高位写为0,这样就将部分积的后7位保留。
然后再将乘数部分的前六位保留,将部分积和乘数部分分别存到0E0H和0E1H中,并将结束输出。
2.2总体和各功能模块的流程图
2.2.1总控流程图
总控流程包括初始化、求和、右移、判断循环次数、输出五个模块。
总控流程如图2.1所示。
图2.1总控流程图
2.2.2初始化模块流程图
初始化部分包括部分积、附加位和循环次数的初始化并且要输入被乘数的补码和乘数的补码。
初始化流程图如图2.2所示。
图2.2初始化模块流程图
说明:
部分积,附加位和循环次数分别保存在R0、内存中的0F3H单元、R1中,[X]补存放在R2和0F0H(以双符号位的形式)中,[-X]补存放在0F1H(以双符号位的形式)中,[Y]补存放在R3和0F2H中。
X代表被乘数,Y代表乘数。
#00H->R0表示将立即数00H存放到R0中,M(0F3H)表示内存中的0F3H单元,#06H->R1表示将立即数06H存到R1中。
2.2.3求和模块流程图
求和模块要根据YnYn+1的值选择部分积和[X]补或[-X]补还是0相加。
具体求和模块流程图如图2.3所示。
图2.3求和模块流程图
说明:
Yn指的是乘数部分的最后一位,Yn+1指的是附加位,X代表被乘数。
2.2.4右移模块流程图
右移模块包括部分积和乘数部分的右移,在右移之前应先把乘数部分的最后一位移到附加位上,再将乘数部分右移,然后将部分积的最后一位存到乘数部分的最高位,再将部分积右移。
部分积右移完之后,判断部分积的次高位是0还1,再把部分积的最高位写成相应的数,这样,部分积保存的就是双符号数,避免运算的时候出现假溢出。
右移模块流程图如图2.4所示。
图2.4右移模块流程图
2.2.5判断循环次数模块流程图
当右移过程执行完后,进入判断循环次数模块,若循环次数不为0,则进入求和和右移模块,否则,进入求和模块,即最后一次不进行右移操作。
判断循环次数流程图如图2.5所示。
图2.5判断循环次数模块流程图
2.2.6输出模块流程图
输出模块输出最后13位补码的16进制表示。
部分积的后7位保存在0E0H中的后7位,乘数部分的前6位保存在0E1H中的后6位。
输出模块流程图如图2.6所示
图2.6输出模块流程图
说明:
因为在运算过程中部分积使用的是双符号位,而运算结果是单符号位,部分积最高位保存的是运算结果的真实符号,所以在得出运算结果后应该判断部分积最高位的值,然后将部分积的次高位置成相应的值,再保存部分积后7位的值从而得出单符号位的结果。
第3章程序调试过程与结果分析
3.1程序调试过程
1、在求和过程中,一开始使用的是单符号位运算,但在调试过程中发现,有时候会出现假溢出的现象导致结果出错,之后将部分积改为双符号位运算之后,结果不再出错,且部分积最高位才是结果真正的符号位。
2、在右移过程中,刚开始设计的时候想的不周到,直接将乘数部分右移一位,但这时会将乘数部分最后一位丢失,从而不知道右移之后附加位变成什么值。
之后将整个循环过程改为:
先判断乘数部分最后一位的值,将部分积改为相应的值,接着将乘数部分移位,再判断部分积最后一位的值,将乘数最高位改为相应的值,最后判断部分积次高位的值并将部分积最高位置成相应的值。
3、在输出结果时,疏忽题目的要求是生成13位补码,直接将部分积包括双符号位在内的8位补码存到0E0H中,解决方法是:
判断部分积最高位的值,将部分积次高位置成和最高位一样的值,然后将最高位置成0,这样部分积的有效部分只有7位存到0E0H中的后7位,乘数部分前6位保存到0E1H的后6位。
3.2结果分析
设[X]补=1010101,[Y]补=0010111;
1、初始化过程
R0初始化为00H,R1初始化为06H,R2里存的是[X]补(55H),R3里存的是[Y]补(17H)。
[X]补(双符号且值是D5H)存放到0F0H中,[-X]补(双符号且值是2BH)存放到0F1H中,[Y]补存放到0F2H中,附加位存放到0F3H中,0F3H初始化为0。
初始化结果如图3.1和3.2所示。
图3.1初始化结果
图3.2初始化结果
2、求和过程
①以第一次求和过程为例,先判断YnYn+1=10,取出[-X]补(双符号且值为2BH)到A中,准备进行求和操作,结果如图3.3所示。
图3.3取出[-X]补到A
②[-X]补和部分积相加结果为2BH,将新的部分积存入R0。
如图3.4所示。
图3.4部分积+[-X]补
3、右移过程
完成一次整体右移之后,部分积是15H,乘数是4BH,附加位为01H。
即R0是15H,0F2H为4BH,0F3H为01H如图3.5和3.6所示。
图3.5第一次右移之后的部分积结果
图3.6第一次右移之后乘数和附加位的结果
4、循环次数减一
R1由6变为5,结果如图3.7所示。
图3.7循环次数由6变为5
5、最后结果输出
部分积结果为70H,保存在0E0H中,乘积结果为23H,保存在0E1H中,结果如图3.8所示。
图3.8结果输出
参考资料
[1]唐朔飞.计算机组成原理(第2版)[M].北京:
高等教育出版社,2008
[2]COP2000实验指导
附录
MOVR0,#00000000B;部分积R0初始化为0
MOVA,#00000000B
MOV0F3H,A;附加位初始化为0
MOVR1,#00000110B;循环次数R1初始化为6
MOVA,#1010101B;输入被乘数[X]补的补码形式
MOVR2,A;被乘数补码存到R2中
ANDA,#1000000B;判断被乘数是正还是负数
JZM1;若被乘数是正数转M1
MOVA,R2;被乘数是负数
ADDA,#10000000B;将被乘数的补码写成双符号位补码
MOV0F0H,A;将被乘数的补码存到0F0H
CPLA
ADDA,#00000001B
MOV0F1H,A;求出被乘数的相反数的补码[-X]补存到0F1H
JMPM2
M1:
MOVA,R2
ADDA,#00000000B;将被乘数的补码写成双符号位补码
MOV0F0H,A;被乘数的补码存到0F0H
CPLA
ADDA,#00000001B
MOV0F1H,A;求出被乘数相反数的补码存到0F1H
JMPM2
M2:
MOVA,#0010111B;输入乘数的补码形式并保存在R3中
MOVR3,A
MOV0F2H,A;将乘数的补码存放到0F2H
S0:
MOVA,0F2H;将乘数的补码送到A中
ANDA,#0000001B;判断Yn是0还是1
JZS1;如果Yn=0转S1
MOVA,0F3H;如果Yn=1则接着判断附加位是0还是1
ANDA,#0000001B
JZS3;附加位是0转S3
S4:
MOVA,0F2H;将乘数的补码送到A中
ANDA,#0000001B;判断乘数最后一位是0还是1
JZS5;若是0转S5
MOVA,0F3H;若是1则将附加位变为1
ORA,#0000001B
MOV0F3H,A;将新的附加位存到0F3H
JMPLOOP
S3:
MOVA,0F1H;取出[-X]补送到A中
ADDA,R0;[-X]补+部分积
MOVR0,A;将新的部分积存到R0中
JMPS4
S5:
MOVA,0F3H
ANDA,#0000000B;将附加位置成0
MOV0F3H,A
JMPLOOP;无条件跳转到LOOP
S1:
MOVA,0F3H
ANDA,#0000001B;判断附加位是0还是1
JZS2;若附加位是0,转S2
MOVA,0F0H
ADDA,R0;若附加位是1,部分积+[X]补
MOVR0,A
JMPS4
S2:
JMPS4;直接跳转到S4
LOOP:
MOVA,0F2H
RRA
MOV0F2H,A;将乘数的补码右移一位存到0F2H
MOVA,R0
ANDA,#00000001B;取出部分积并判断部分积的最低位是0还是1
JZS6;若部分积的最低位是0转S6
MOVA,0F2H;若部分积最低位是1
ORA,#1000000B;将乘数的最高位置1
MOV0F2H,A
JMPLOOP1
S6:
MOVA,0F2H
ANDA,#0111111B
MOV0F2H,A;将乘数补码的最高位变成0存到0F2H
JMPLOOP1
LOOP1:
MOVA,R0
RRA
MOVR0,A;将部分积右移一位存到R0中
ANDA,#01000000B;判断部分积次高位的符号
JZS7;若部分积次高位是0转S7
MOVA,R0;若部分积次高位是1
ORA,#10000000B;将部分积最高位写为1并存到R0
MOVR0,A
JMPS8
S7:
MOVA,R0
ANDA,#01111111B;将部分积最高位写为0
MOVR0,A
JMPS8
S8:
MOVA,R1
SUBA,#0000001B;将循环次数减一
MOVR1,A
ORA,#0000000B;判断是否是最后一次循环
JZS9;若是最后一次循环转S9
JMPS0;否则转S0
S9:
MOVA,0F2H
ANDA,#0000001B;判断Yn的符号
JZS10;Yn=0转S10
MOVA,0F3H;若Yn=1
ANDA,#0000001B;判断附加位的符号
JZS11;若附加位=0转S11
JMPS12
S10:
MOVA,0F3H
ANDA,#0000001B;判断附加位最低位的符号
JZS12;若为0转S12
MOVA,0F0H
ADDA,R0;[X]补+部分积
MOVR0,A
JMPS12
S11:
MOVA,0F1H
ADDA,R0;[-X]补+部分积
MOVR0,A
JMPS12
S12:
MOVA,R0
ANDA,#10000000B;判断部分积的最高位的符号
JZM3;若部分积的最高位是0转M3
MOVA,R0
ANDA,#00111111B
ADDA,#1000000B;保留部分积的后7位且最高位为1
JMPM4
M3:
MOVA,R0
ANDA,#00111111B
ADDA,#0000000B;保留部分积的后7位且最高位为0
JMPM4
M4:
MOV0E0H,A;将最后的部分积的后7位存到0E0H
OUT
MOVA,0F2H
RRA
MOV0F2H,A
MOV0E1H,A;将最终的乘数部分前6位存到0E1H中,最终得到了13位补码
OUT
OVER:
JMPOVER