实验三ALU与ALU控制器设计.docx
《实验三ALU与ALU控制器设计.docx》由会员分享,可在线阅读,更多相关《实验三ALU与ALU控制器设计.docx(30页珍藏版)》请在冰豆网上搜索。
实验三ALU与ALU控制器设计
实验三ALU与ALU控制器设计
姓名:
葛鑫
学号:
091220033
邮箱:
xingenju@
一、实验目的
1、了解并掌握ALU的工作原理和ALU所要完成的算术运算与逻辑运算。
2、掌握ALU控制器的工作原理和作用。
二、实验设备
1、装有QuartusII的计算机一台。
2、AlteraDE2-70开发板一块。
三、实验任务
1、用VerilogHDL语言戒VHDL语言来编写,实现MIPS32位的ALU及ALU的控制器,使其能够支持基本的指令。
2、用VerilogHDL语言戒VHDL语言来编写,实现RAM32位的ALU及ALU的控制器,使其能够支持基本的指令。
四、实验原理与电路图
1、MIPS中ALU控制器的原理
在MIPS中,ALU可执行的功能与操作如下表,需要三位控制信号:
除运算结果result_final,ALU还输出信号zero,less,overflow,carry分别表示运算结果是否为0,两数比较是大还是小,是否有溢出,以及是否有进位,以用于某些判断指令。
为提高ALU的控制效率,ALU采用两级控制,即通过ALU控制器实现对ALU的控制,而不是直接控制ALU。
ALU控制逻辑图:
AluOp:
4位
1.最低位为控制加减法以及前导0还是前导1,有误无需额外译码
2.倒数第二位控制作有无符号判定,有无符号数判定大小逻辑不同(less标志)
3.两个有符号数比较,V异或S的结果为less
4.两个无符号数比较,C的结果为less
2、ARM中ALU控制器的原理
AluOp
AluCtr
指令
功能
0000
101
ADD
加法运算
0001
101
ADC
带进位的加法运算
0010
101
SUB
减法运算
0011
101
SBC
带进位的减法运算
0100
000
BIC
位清除指令
0101
001
AND
与操作
0110
010
ORR
或操作
0111
011
EOR
异或操作
1000
100
CMN
负数比较
1001
100
TST
位测试指令
1010
100
CMP
比较指令
1011
100
TEQ
相等测试指令
ADD:
若ADDr0,r1,r2,则r0=r1+r2;
ADC:
若ADCr0,r1,r2,则r0=r1+r2+C;
SUB:
若SUBr0,r1,r2,则r0=r1-r2;
SBC:
若SBCr0,r1,r2,则r0=r1+r2+C-1;
BIC:
A中值与B中值的反码进行与操作;
AND:
按位与操作;
ORR:
按位或操作;
EOR:
按位异或操作;
CMN:
A加B,若小于零则结果为1,不保存减的结果;
TST:
A和B进行按位与操作,全零则结果为1;
CMP:
A减B,若小于零则结果为1,不保存减的结果;
TEQ:
A和B进行按位异或操作,全零则结果为1。
五、实验步骤
(一)Ex1(MIPS的ALU及ALU控制器)
1、变量名列表
输出变量名
变量名类型
变量名含义说明
定义该变量的程序模块名
Operand_A
32位input
第一个操作数
mips_alu
Operand_B
32位input
第二个操作数
mips_alu
AluOp
4位input
控制变量
mips_alu
Result_final
32位output
输出结果
mips_alu
Carry
1位output
进位
mips_alu
Zero
1位output
判零
mips_alu
Overflow
1位output
判断溢出
mips_alu
Less
1位output
比较两数大小
mips_alu
result
32位reg数组
用于存放结果的临时变量
mips_alu
i
1位integer
用于计数的临时变量
mips_alu
count
32位reg
用于存放扩展位的临时变量
mips_alu
extendA,extendB
32位reg
用于存放扩展后数据的临时变量
mips_alu
tempA,tempB
32位reg
用于存放数据的临时变量
mips_alu
temp
33位reg
用于存放数据经过加法器运算后的临时变量
mips_alu
Carry_f
1位reg
用于存放数据经过加法器运算后的进位
mips_alu
Sign
1位reg
用于存放数据经过加法器运算后的符号位
mips_alu
2、代码
modulemips_alu(input[31:
0]Operand_A,
input[31:
0]Operand_B,
input[3:
0]AluOp,
outputreg[31:
0]Result_final,
outputregCarry,
outputregZero,
outputregOverflow,
outputregLess
);
reg[31:
0]result[6:
0];
always
begin
result[1]=Operand_A^Operand_B;
result[2]=Operand_A|Operand_B;
result[3]=~(Operand_A|Operand_B);
result[4]=Operand_A&Operand_B;
end
integeri;
reg[31:
0]count;
reg[31:
0]extendA,tempA;
always
begin
if(AluOp[0]==0)
begin
extendA=0;
end
else
begin
extendA={32{1'b1}};
end
tempA=(Operand_A^extendA);
count=32;
for(i=31;i>=0;i=i-1)
begin
if(tempA[31-i]==1)
begin
count=i;
end
end
result[0]=count;
end
reg[31:
0]extendB,tempB;
reg[32:
0]temp;
regCarry_f;
regSign;
always
begin
if(AluOp[0]==0)
begin
extendB=0;
end
else
begin
extendB={32{1'b1}};
end
tempB=(Operand_B^extendB);
temp=Operand_A+tempB+AluOp[0];
result[6]=temp[31:
0];
Carry_f=temp[32];
Carry=Carry_f^AluOp[0];
if(AluOp[0]==1&&temp==0)
Zero=1;
else
Zero=0;
if(Operand_A[31]==tempB[31]&&temp[31]!
=Operand_A[31])
Overflow=1;
else
Overflow=0;
Sign=temp[31];
if(AluOp[1]==1)
Less=Carry;
else
Less=Sign^Overflow;
if(Less==1)
result[5]={32{1'b1}};
else
result[5]=0;
end
reg[2:
0]AluCtr;
always
begin
AluCtr[2]=((~AluOp[3])&(~AluOp[1]))|((~AluOp[3])&AluOp[2]&AluOp[0]);
AluCtr[1]=((~AluOp[3])&(~AluOp[2])&(~AluOp[1]))
|((~AluOp[3])&AluOp[2]&AluOp[1]&AluOp[0])
|((~AluOp[2])&(~AluOp[1])&(~AluOp[0]));
AluCtr[0]=(AluOp[3]&(~AluOp[2])&(~AluOp[1]))|((~AluOp[3])&AluOp[2]&AluOp[0]);
end
always
begin
case(AluCtr)
3'b000:
Result_final=result[0];
3'b001:
Result_final=result[1];
3'b010:
Result_final=result[2];
3'b011:
Result_final=result[3];
3'b100:
Result_final=result[4];
3'b101:
Result_final=result[5];
3'b110:
Result_final=result[6];
endcase
end
endmodule
3、仿真结果:
功能仿真:
仿真结果说明:
AluOp
功能
Operand_A
Operand_B
Result_final
Carry
Zero
Overflow
Less
0000
加法
01100000000000000000000000000000
01100000000000000000000000000000
11000000000000000000000000000000
0
0
1
0
0001
有符号减法
00000000000000000000000000000010
00000000000000000000000000000101
111111*********11111111111111101
1
0
0
1
0010
前导零
00000000000000000000000000000000
00000000000000000000000000100000
0
0
0
0
0011
前导一
11100000000000000000000000000000
00000000000000000000000000000011
0
0
0
0
0100
与
00000000000000000000000000001010
00000000000000000000000000001100
00000000000000000000000000001000
0
0
0
0
0101
slt/slti
00000000000000000000000000000001
00000000000000000000000000000011
111111*********11111111111111111
1
0
0
1
0110
或
00000000000000000000000000001010
00000000000000000000000000001100
00000000000000000000000000001110
0
0
0
0
0111
sltu/sltiu
00000000000000000000000000000001
00000000000000000000000000000011
111111*********11111111111111111
1
0
0
1
1000
或非
00000000000000000000000000001010
00000000000000000000000000001100
11111111111111111111111111110001
0
0
0
0
1001
异或
00000000000000000000000000001010
00000000000000000000000000001100
00000000000000000000000000000110
1
0
0
1
(二)Ex2(ARM的ALU及ALU控制器)
1、变量名列表
输出变量名
变量名类型
变量名含义说明
定义该变量的程序模块名
Operand_A
32位input
第一个操作数
arm_alu
Operand_B
32位input
第二个操作数
arm_alu
AluOp
4位input
控制变量
arm_alu
C_before_move
1位input
标志位
arm_alu
ctr_LRAL
2位input
控制位
arm_alu
ctr_RRX
1位input
控制位
arm_alu
S
5位input
控制位
arm_alu
Result
32位output
输出结果
arm_alu
Carry
1位output
进位
arm_alu
Zero
1位output
判零
arm_alu
Overflow
1位output
判断溢出
arm_alu
Less
1位output
比较两数大小
arm_alu
2、代码
modulearm_alu(Operand_A,Operand_B,AluOp,Carry,Less,Zero,Overflow,Result,
ctr_LRAL,ctr_RRX,S,C_before_move);
input[31:
0]Operand_A;
input[31:
0]Operand_B;
input[3:
0]AluOp;
input[4:
0]S;
input[1:
0]ctr_LRAL;
inputctr_RRX;
inputC_before_move;
outputCarry,Less,Zero,Overflow;
output[31:
0]Result;
wireC_after_move;
wire[31:
0]Result_f;
wireCarry_f,Sign;
wire[2:
0]Control;
wire[31:
0]x0,x1,x2,x3,x4,x5;
wire[31:
0]A,B;
wire[31:
0]larger,out_move;
wireCin,inCarry0,inCarry1,inx4_01,inx4_11;
controlf_4to3(AluOp,Control);
larger1to32f_larger(AluOp[1],larger);
ARM_movef_move(Operand_B,S,ctr_LRAL,ctr_RRX,out_move,C_before_move,C_after_move);
assignA=Operand_A;
assignB=out_move^larger;
mux_2to1f_toCin(AluOp[1],C_after_move,AluOp[0],Cin);
alladdf_add(A,B,Cin,Result_f,Carry_f,Zero,Overflow,Sign);
assigninCarry0=Carry_f^AluOp[1];
assigninCarry1=C_after_move;
mux_2to1f_toCarry(inCarry0,inCarry1,ctr_RRX,Carry);
assignLess=Overflow^Sign;
assignx0=(~out_move)&Operand_A;
assignx1=Operand_A&out_move;
assignx2=Operand_A|out_move;
assignx3=Operand_A^out_move;
test_all0g1(x1,inx4_01);
test_all0g2(x1,inx4_11);
mux_4to1f_getx4(Less,inx4_01,Less,inx4_11,AluOp[1:
0],x4);
assignx5=Result_f;
mux32_6to1f_getResult(x0,x1,x2,x3,x4,x5,Control,Result);
endmodule
modulecontrol(ALUop,ALUctr);
input[3:
0]ALUop;
outputreg[2:
0]ALUctr;
always@(ALUop)
case(ALUop)
4'b0000:
ALUctr=3'b101;
4'b0001:
ALUctr=3'b101;
4'b0010:
ALUctr=3'b101;
4'b0011:
ALUctr=3'b101;
4'b0100:
ALUctr=3'b000;
4'b0101:
ALUctr=3'b001;
4'b0110:
ALUctr=3'b010;
4'b0111:
ALUctr=3'b011;
4'b1000:
ALUctr=3'b100;
4'b1001:
ALUctr=3'b100;
4'b1010:
ALUctr=3'b100;
4'b1011:
ALUctr=3'b100;
default:
ALUctr=3'b111;
endcase
endmodule
modulealladd(A,B,Cin,Result_f,Carry_f,Zero,Overflow,Sign);
input[31:
0]A;
input[31:
0]B;
inputCin;
output[31:
0]Result_f;
outputCarry_f,Zero,Overflow,Sign;
wire[31:
0]C;
addf0(A[0],B[0],Cin,Result_f[0],C[0]);
addf1(A[1],B[1],C[0],Result_f[1],C[1]);
addf2(A[2],B[2],C[1],Result_f[2],C[2]);
addf3(A[3],B[3],C[2],Result_f[3],C[3]);
addf4(A[4],B[4],C[3],Result_f[4],C[4]);
addf5(A[5],B[5],C[4],Result_f[5],C[5]);
addf6(A[6],B[6],C[5],Result_f[6],C[6]);
addf7(A[7],B[7],C[6],Result_f[7],C[7]);
addf8(A[8],B[8],C[7],Result_f[8],C[8]);
addf9(A[9],B[9],C[8],Result_f[9],C[9]);
addf10(A[10],B[10],C[9],Result_f[10],C[10]);
addf11(A[11],B[11],C[10],Result_f[11],C[11]);
addf12(A[12],B[12],C[11],Result_f[12],C[12]);
addf13(A[13],B[13],C[12],Result_f[13],C[13]);
addf14(A[14],B[14],C[13],Result_f[14],C[14]);
addf15(A[15],B[15],C[14],Result_f[15],C[15]);
addf16(A[16],B[16],C[15],Result_f[16],C[16]);
addf17(A[17],B[17],C[16],Result_f[17],C[17]);
addf18(A[18],B[18],C[17],Result_f[18],C[18]);
addf19(A[19],B[19],C[18],Result_f[19],C[19]);
addf20(A[20],B[20],C[19],Result_f[20],C[20]);
addf21(A[21],B[21],C[20],Result_f[21],C[21]);
addf22(A[22],B[22],C[21],Result_f[22],C[22]);
addf23(A[23],B[23],C[22],Result_f[23],C[23]);
addf24(A[24],B[24],C[23],Result_f[24],C[24]);
addf25(A[25],B[25],C[24],Result_f[25],C[25]);
addf26(A[26],B[26],C[25],Result_f[26],C[26]);
addf27(A[27],B[27],C[26],Result_f[27],C[27]);
addf28(A[28],B[28],C[27],Result_f[28],C[28]);
addf29(A[29],B[29],C[28],Result_f[29],C[29]);
addf30(A[30],B[30],C[29],Result_f[30],C[30]);
addf31(A[31],B[31],C[30],Result_f[31],C[31]);
assignCarry_f=C[31];
assignSign=Result_f[31];
assignOverflow=C[30]^C[31];
assignZero=~(Result_f[0]|Result_f[1]|Result_f[2]|Result_f[3]|
Result_f[4]|Result_f[5]|Result_f[6]|Result_f[7]|
Result_f[8]|Result_f[9]|Result_f[10]|Result_f[11]|