资源描述
个人收集整理 勿做商业用途
计算机组成原理
实验报告
学 院:____ 电信学院_ ____
专 业:_计算机科学与技术____
学 号:___2110505108________
班 级:___计算机15_________
姓 名:_____张玲玲__________
时 间:__ 2013年1月3日 __
一、 实验目的
(1)掌握基本的算术运算和逻辑运算的运算规则和实现方法;
(2)掌握基本运算器的信息传送通路;
(3)掌握运算器的工作原理,设计并实现具有定点、浮点运算功能的模块。
二、 实验内容
设计一个基本的算术逻辑运算模块,包括:
①算术运算模块,主要包括定点运算:加减乘除运算及浮点运算(浮点运算依照IEEE754标准);
②逻辑运算模块,主要包括与、或、非、异或和各种移位运算等;
注: 运算器模块框图:运算器(ALU)通常有两个数据输入端(opr1和opr2),一个数据输出端(result),运算模式控制信号(code)和标志位( cin , flag)等。下图为运算器的逻辑框图:
图2-1 运算器
运算器包含加法器(含用先行进位的构成的加法器,如4位一组构成16位)、减法器、乘法器、与门、或门、非门、异或门和移位器等及浮点运算模块;运算器模块中也可以加入寄存器组.
本实验中设计的运算器操作数可以分别为8/16/32位字长((32位字长运算可以只进行仿真分析)
③ 定点乘法:
已知X=-0。1010,Y=0。0011,求 X*Y=?
利用原码乘法的方法,设计VHDL程序,完成乘法的运算并描述其算法及电路图;
三、 实验原理
在计算机内实现原码乘法时,要做以下方面的改进工作。由于在运算器内通常只能完成对两数的求乘操作,则可以每求得一个相加数,就同时完成与上一次部分积相加的操作。其次是在手工计算时,各加数逐位左移,最终相加数为相乘二位数的两倍,而在计算机中,加法器的位数一般与乘法器的位数相同,而不是寄存器位数的两倍。这实际上也可以用另外的办法解决.手工计算时,各加数是逐位左移,但很容易发现,在求本次部分积之和时,前一部分积的最低一位是不再与任何数值相加的。这就意味着,若采用每求得一次部分积之后使其右移一位,则可以只用N位的加法器就能实现两个N位的数相乘j!显而易见,若前一次部分积已经右移一位,就可以用其高位部分加上被乘数或加零的方法求得本次部分积。最后一点是,手工计算时,乘数每一位的值是0还是1都直接看得见,而在计算机内,采用放乘数的寄存器的每一位直接决定本次相加数是被乘数还是零是很不方便的,若均采用该寄存器的最低一位来执行这种判别就简便了。为此,只要每求一次部分积就使放乘数的寄存器执行一次右移操作即可以了。若移位时,使其最高数值位接收加法器最低位的输出,则完成乘法运算后,该寄存器中保存的是乘积的低位部分。计算机内求乘积的符号,很容易用求相乘二数符号的半加和(异或值)实现。个人收集整理,勿做商业用途
原码一位乘法的规则:
⑴判断参加运算的操作数是否合格;
⑵令乘数的最低位为判断位,若为“1",加被乘数,若为“0”,不加被乘数(加0);
⑶累加后的部分积以及乘数右移一位
⑷重复n次⑵和⑶ ;
⑸符号位单独处理,同号为正,异号为负。
通常,乘法运算需要3个寄存器。被乘数存放在B寄存器中;乘数存放在C寄存器中;A寄存器用来存放部分积与最后乘积的高位部分,它的初值为0。运算结束后寄存器C中不再保留乘数,改为存放乘积的低位部分.
例:已知:X=0。1101,Y=-0。1011,求:X×Y。
|X|=00.1101→B,|Y|=。1011→C,0→A
原码一位乘法示例
A C 说明
00。0000 1011
+|X| 00.1101 C4=1,+|X|
00。1101
→ 00.0110 1101 部分积右移一位
+|X| 00。1101 C4=1,+|X|
01。0011
→ 00。1001 1110 部分积右移一位
+0 00。0000 C4=0,+0
00.1001
→ 00。0100 1111 部分积右移一位
+|X| 00.1101 C4=1,+|X|
01。0001
→ 00。1000 1111 部分积右移一位
∵PS=XS⊕YS=0⊕1=1
∴X*Y=-0。10001111
原码一位乘法流程图
这里为了简便,我编写了无符号数原码的乘法运算,不考虑符号位。即实现了两个四位数相乘,结果放入一个八位数中。
四、 实验源代码
library ieee;
use ieee.std_logic_1164。all;
use ieee。std_logic_unsigned.all;
use ieee.std_logic_arith。all;
entity ALU is
port(
set:in std_logic;—- 运算控制信号
code:in std_logic_vector(3 downto 0);-- 操作码
cin:in std_logic;—- 低位向高位的进位或者借位信号
opr1:in std_logic_vector(7 downto 0);-— 第一操作数
opr2:in std_logic_vector(7 downto 0);-— 第二操作数
result:out std_logic_vector(7 downto 0);-— 运算结果
flag:out std_logic——运算结果标志位flag
);
end ALU;
architecture behav of ALU is
signal a:std_logic_vector(7 downto 0);
signal b:std_logic_vector(7 downto 0);
signal c:std_logic_vector(7 downto 0);
shared variable y,x:std_logic_vector(7 downto 0);
begin
process(b,c,temp1,set,code,cin,opr1,opr2)
variable i: integer;
begin
a<="00000000";
b〈=”00000000”;
C<=”00000000”;
x:="00000000";
temp:=”00000000";
temp1〈="00000000";
result<="00000000”;
flag<='0';
if set=’1'then
case code is
when"0000”=>——”+"
a(0)<=opr1(0) and opr2(0);b(0)〈=opr1(0) xor opr2(0);--产生本地进位和传递条件
a(1)<=opr1(1) and opr2(1);b(1)<=opr1(1) xor opr2(1);
a(2)<=opr1(2) and opr2(2);b(2)<=opr1(2) xor opr2(2);
a(3)〈=opr1(3) and opr2(3);b(3)〈=opr1(3) xor opr2(3);
a(4)<=opr1(4) and opr2(4);b(4)<=opr1(4) xor opr2(4);
a(5)〈=opr1(5) and opr2(5);b(5)<=opr1(5) xor opr2(5);
a(6)〈=opr1(6) and opr2(6);b(6)<=opr1(6) xor opr2(6);
a(7)〈=opr1(7) and opr2(7);b(7)<=opr1(7) xor opr2(7);
—-每四位一组,组内先行进位加法,组间串行进位加法.
result(0)<=b(0) xor cin;
c(0)<=a(0) or (b(0) and cin);
result(1)〈=b(1) xor c(0);
c(1)<=a(1) or (b(1) and a(0)) or (b(1)and b(0)and cin);
result(2)〈=b(2) xor c(1);
c(2)<=a(2) or (b(2) and a(1)) or (b(2)and b(1)and a(0)) or (b(2)and b(1)and b(0)and cin);
result(3)<=b(3) xor c(2);
c(3)<=a(3) or (b(3) and a(2)) or (b(3)and b(2)and a(1)) or (b(3)and b(2)and b(1)and a(0)) or (b(3)and b(2)and b(1)and b(0)and cin);
result(4)<=b(4) xor c(3);
c(4)<=a(4) or (b(4) and c(3));
result(5)〈=b(5) xor c(4);
c(5)<=a(5) or (b(5) and a(4)) or (b(5)and b(4)and c(3));
result(6)<=b(6) xor c(5);
c(6)<=a(6) or (b(6) and a(5)) or (b(6)and b(5)and a(4)) or (b(6)and b(5)and b(4)and c(3));
result(7)<=b(7) xor c(6);
flag〈=a(7) or (b(7) and a(6)) or (b(7)and b(6)and a(5)) or (b(7)and b(6)and b(5)and a(4)) or (b(7)and b(6)and b(5)and b(4)and c(3));
when”0001”=>--”+1"
result(0)〈=not opr1(0);
result(1)<=opr1(1) xor opr1(0);
result(2)〈=opr1(2) xor (opr1(1) and opr1(0));
result(3)〈=opr1(3) xor (opr1(2) and opr1(1) and opr1(0));
result(4)<=opr1(4) xor (opr1(3) and opr1(2) and opr1(1) and opr1(0));
result(5)<=opr1(5) xor (opr1(4) and opr1(3) and opr1(2) and opr1(1) and opr1(0));
result(6)〈=opr1(6) xor (opr1(5) and opr1(4) and opr1(3) and opr1(2) and opr1(1) and opr1(0));
result(7)<=opr1(7) xor (opr1(6) and opr1(5) and opr1(4) and opr1(3) and opr1(2) and opr1(1) and opr1(0));
flag〈=opr1(7) and opr1(6) and opr1(5) and opr1(4) and opr1(3) and opr1(2) and opr1(0);
when”0010"=>—-"-"
a(0)〈=opr1(0) and (not opr2(0));b(0)<=opr1(0) xor (not opr2(0));
a(1)〈=opr1(1) and (not opr2(1));b(1)〈=opr1(1) xor (not opr2(1));
a(2)〈=opr1(2) and (not opr2(2));b(2)〈=opr1(2) xor (not opr2(2));
a(3)〈=opr1(3) and (not opr2(3));b(3)〈=opr1(3) xor (not opr2(3));
a(4)<=opr1(4) and (not opr2(4));b(4)<=opr1(4) xor (not opr2(4));
a(5)<=opr1(5) and (not opr2(5));b(5)<=opr1(5) xor (not opr2(5));
a(6)〈=opr1(6) and (not opr2(6));b(6)<=opr1(6) xor (not opr2(6));
a(7)〈=opr1(7) and (not opr2(7));b(7)〈=opr1(7) xor (not opr2(7));
result(0)<=b(0) xor (not cin);
c(0)〈=a(0) or (b(0) and (not cin));
result(1)〈=b(1) xor c(0);
c(1)〈=a(1) or (b(1) and a(0)) or (b(1)and b(0)and (not cin));
result(2)〈=b(2) xor c(1);
c(2)〈=a(2) or (b(2) and a(1)) or (b(2)and b(1)and a(0)) or (b(2)and b(1)and b(0)and (not cin));
result(3)<=b(3) xor c(2);
c(3)〈=a(3) or (b(3) and a(2)) or (b(3)and b(2)and a(1)) or (b(3)and b(2)and b(1)and a(0)) or (b(3)and b(2)and b(1)and b(0)and (not cin));
result(4)<=b(4) xor c(3);
c(4)<=a(4) or (b(4) and c(3));
result(5)〈=b(5) xor c(4);
c(5)〈=a(5) or (b(5) and a(4)) or (b(5)and b(4)and c(3));
result(6)〈=b(6) xor c(5);
c(6)<=a(6) or (b(6) and a(5)) or (b(6)and b(5)and a(4)) or (b(6)and b(5)and b(4)and c(3));
result(7)<=b(7) xor c(6);
c(7)〈=a(7) or (b(7) and a(6)) or (b(7)and b(6)and a(5)) or (b(7)and b(6)and b(5)and a(4)) or (b(7)and b(6)and b(5)and b(4)and c(3));
flag〈=not c(7);
when"0011"=〉—-"-1"
result(0)<=not opr1(0);
result(1)〈=opr1(1)xor(not opr1(0));
result(2)〈=opr1(2)xor(not (opr1(1)or opr1(0)));
result(3)〈=opr1(3)xor(not (opr1(2)or opr1(1)or opr1(0)));
result(4)〈=opr1(4)xor(not (opr1(3)or opr1(2)or opr1(1)or opr1(0)));
result(5)〈=opr1(5)xor(not (opr1(4)or opr1(3)or opr1(2)or opr1(1)or opr1(0)));
result(6)<=opr1(6)xor(not (opr1(5)or opr1(4)or opr1(3)or opr1(2)or opr1(1)or opr1(0)));
result(7)<=opr1(7)xor(not (opr1(6)or opr1(5)or opr1(4)or opr1(3)or opr1(2)or opr1(1)or opr1(0)));
flag<=not(opr1(7)or opr1(6)or opr1(5)or opr1(4)or opr1(3)or opr1(2)or opr1(1)or opr1(0));
when”0100"=>-—”*”操作数为4位,结果为8位,无符号数原码乘法
--c〈=opr1(3 downto 0)*opr2(3 downto 0);
x(0):=’0'; x(1):='0’; x(2):='0'; x(3):=’0’;
x(4):=opr1(0); x(5):=opr1(1); x(6):=opr1(2); x(7):=opr1(3);
y(0):=opr2(0); y(1):=opr2(1); y(2):=opr2(2); y(3):=opr2(3);
y(4):=’0’; y(5):=’0’; y(6):='0’; y(7):=’0’;
i:=0;
while (i<4) loop
if(y(0)=’1') then y:=x+y;
else y:=y;
end if;
y(0):=y(1); y(1):=y(2); y(2):=y(3); y(3):=y(4);
y(4):=y(5); y(5):=y(6); y(6):=y(7); y(7):='0’;
--y(7 downto 0)<=y1(7 downto 0);
i:=i+1;
end loop;
--y(7)<=opr1(7) xor opr2(7);
result<=y;
if((opr1>15) or (opr2〉15)) then flag<='1';
end if;
when"0101”=>——传送数据
result〈=opr1(7 downto 0);
when"0110”=〉——”and”
result(0)〈=opr1(0)and opr2(0);
result(1)〈=opr1(1)and opr2(1);
result(2)<=opr1(2)and opr2(2);
result(3)<=opr1(3)and opr2(3);
result(4)〈=opr1(4)and opr2(4);
result(5)〈=opr1(5)and opr2(5);
result(6)〈=opr1(6)and opr2(6);
result(7)〈=opr1(7)and opr2(7);
when"0111"=〉--"or”
result(0)〈=opr1(0)or opr2(0);
result(1)<=opr1(1)or opr2(1);
result(2)<=opr1(2)or opr2(2);
result(3)<=opr1(3)or opr2(3);
result(4)<=opr1(4)or opr2(4);
result(5)〈=opr1(5)or opr2(5);
result(6)<=opr1(6)or opr2(6);
result(7)<=opr1(7)or opr2(7);
when”1000”=>—-”not”
result(0)〈=not opr1(0);
result(1)<=not opr1(1);
result(2)<=not opr1(2);
result(3)〈=not opr1(3);
result(4)〈=not opr1(4);
result(5)〈=not opr1(5);
result(6)〈=not opr1(6);
result(7)<=not opr1(7);
when"1001"=>--"xor”
result(0)<=opr1(0)xor opr2(0);
result(1)〈=opr1(1)xor opr2(1);
result(2)<=opr1(2)xor opr2(2);
result(3)<=opr1(3)xor opr2(3);
result(4)〈=opr1(4)xor opr2(4);
result(5)〈=opr1(5)xor opr2(5);
result(6)<=opr1(6)xor opr2(6);
result(7)〈=opr1(7)xor opr2(7);
when”1010"=>—-”SAL"
case opr2 is
when ”00000000"=〉result<=opr1;
when "00000001”=>result(0)<=opr1(0);
result(7 downto 1)〈=opr1(6 downto 0);
when "00000010”=>result(0)<=opr1(0);
result(1)<=opr1(0);
result(7 downto 2)<=opr1(5 downto 0);
when "00000011”=〉result(0)<=opr1(0);
result(1)〈=opr1(0);
result(2)<=opr1(0);
result(7 downto 3)〈=opr1(4 downto 0);
when ”00000100"=〉result(0)<=opr1(0);
result(1)〈=opr1(0);
result(2)<=opr1(0);
result(3)〈=opr1(0);
result(7 downto 4)〈=opr1(3 downto 0);
when ”00000101”=>result(0)〈=opr1(0);
result(1)〈=opr1(0);
result(2)〈=opr1(0);
result(3)<=opr1(0);
result(4)<=opr1(0);
result(7 downto 5)〈=opr1(2 downto 0);
when ”00000110"=>result(0)〈=opr1(0);
result(1)<=opr1(0);
result(2)〈=opr1(0);
result(3)<=opr1(0);
result(4)〈=opr1(0);
result(5)〈=opr1(0);
result(7 downto 6)〈=opr1(1 downto 0);
when "00000111”=〉result(0)<=opr1(0);
result(1)〈=opr1(0);
result(2)<=opr1(0);
result(3)〈=opr1(0);
result(4)<=opr1(0);
result(5)〈=opr1(0);
result(6)<=opr1(0);
result(7)〈=opr1(0);
when others=>result〈=”00000000";
flag<='1’;-—error
end case;
when”1011"=〉——”SAR”
case opr2 is
when "00000000”=>result<=opr1;
when ”00000001”=>result(7)〈=opr1(7);
result(6 downto 0)〈=opr1(7 downto 1);
when ”00000010"=〉result(7)<=opr1(7);
result(6)〈=opr1(7);
result(5 downto 0)〈=opr1(7 downto 2);
when "00000011"=〉result(7)〈=opr1(7);
result(6)〈=opr1(7);
result(5)<=opr1(7);
result(4 downto 0)〈=opr1(7 downto 3);
when "00000100"=〉result(3 downto 0)〈=opr1(7 downto 4);
result(4)〈=opr1(7);
result(5)〈=opr1(7);
result(6)〈=opr1(7);
result(7)〈=opr1(7);
when "00000101"=>result(7)〈=opr1(7);
result(6)〈=opr1(7);
result(5)〈=opr1(7);
result(4)<=opr1(7);
result(3)〈=opr1(7);
result(2 downto 0)〈=opr1(7 downto 5);
when ”00000110”=〉result(7)〈=opr1(7);
result(6)<=opr1(7);
result(5)〈=opr1(7);
result(4)<=opr1(7);
result(3)〈=opr1(7);
result(2)<=opr1(7);
result(1 downto 0)<=opr1(7 downto 6);
when "00000111”=〉result(7)〈=opr1(7);
result(6)〈=opr1(7);
result(5)〈=opr1(7);
result(4)〈=opr1(7);
result(3)〈=opr1(7);
result(2)〈=opr1(7);
result(1)<=opr1(7);
result(0)〈=opr1(7);
when others=〉result<=”00000000";
flag<='1';
end case;
when"1100”=>—-”SLL”
case opr2 is
when "00000000”=〉result<=opr1;
when "00000001”=〉result(0)〈=’0’;
result(7 downto 1)〈=opr1(6 downto 0);
when "00000010"=〉result(1 downto 0)〈=”00";
result(7 downto 2)<=opr1(5 downto 0);
when "00000011”=>result(2 downto 0)<=”000”;
result(7 downto 3)〈=opr1(4 downto 0);
when "00000100”=〉result(3 downto 0)〈=”0000";
result(7 downto 4)〈=opr1(3 downto 0);
when "00000101"=〉result(4 downto 0)<="00000";
result(7 downto 5)<=opr1(2 downto 0);
when ”00000110”=>result(5 downto 0)<=”000000";
result(7 downto 6)〈=opr1(1 downto 0);
when
展开阅读全文