二、实验目的
1、了解运算器的数据传输通路;
2、验证运算器的组合功能;
3、掌握算术逻辑运算工作原理;
4、验证运算器8位加、减、与、直通功能;
5、按给定数据,完成几种指定的算术和逻辑运算。
三、实验环境
PC计算机
四、实验内容
1、参照图1.2所示,参加运算的两个8位数据分别为A[7..0]和B[7..0]。运算模式由S[3..0]的16种组合决定,而S[3..0]的值可由4位2进制计数器产生,也可由开关设置。此外,设M=0,选择算术运算,M=1为逻辑运算,CN为最低位的进位位;F[7..0]为输出结果;CO为运算后的进位标志,FZ为运算后的结果为零标志位。对设计的ALU181A进行仿真调试,并记录结果。
仿真:在软件环境下,验证电路的行为(与预期的一致性),
功能仿真:在设计输入之后,综合、布线之前的仿真。不考虑电路的逻辑和门电路的延时,这种考虑电路在理想状态下的行为和预期设计效果的一致性。
时序仿真:在综合、布局布线后,也即电路已映射到特定工艺环境后,考虑器件延时的情况下对布局布线后电路的仿真。
2、按要求撰写试验报告。
图1.2算术逻辑单元ALU实验原理图
五、实验步骤与实验结果
1、实验步骤
(1)设计ALU元件。
在Quartus II 环境下,基于ALU181的基本功能写出对应的HDL代码(参照附录2中 8位算术逻辑单元ALU的Verilog HDL程序),并将ALU181文件(见附录2)制作成一个可调用的原理图元件。参照采用Verilog HDL输入 系统设计操作流程,完成系统设计。
1)输入源程序,可直接复制附录2中的文本,打开Quartus II,选择File→New命令。在New窗口中的Design Files栏选择编译文件的语言类型,这里选择Verilog HDL File选项。然后在Verilog HDL文本编译窗口中输入附录2中的程序,完成仿真调试。
2)生成元件符号
方法:File--Create/Update--Create Symbol File for Current File,将本设计封装为一个元件符号(ALU181A.bsf),供以后在原理图编辑器下进行层次设计时调用。如图1.4所示。
图1.4 封装为一个元件符号
(2)采用原理图方式设计电路
选择图形输入方式。根据图1.2、图1.3输入实验电路图,从Quartus II的基本元件库中将各元件调入图形编辑窗口、连线,添加输入输出引脚。形成的原理图如图1.5所示。
图1.5 由ALU181A 形成的原理图文件
将所设计的原理图文件ALU181AA.bdf保存到原先建立的文件夹中,将当前文件设置成工程文件(设置为 顶层文件),方法:Project--Set as Top-Level Entity。以后的操作就都是对当前工程文件进行的。如图1.6所示。
图1.6 将ALU181AA.bdf设置为顶层文件
(3)器件选择。选择CycloneIV系列,在Devices中选择器件EP4CE22F17C8。编译,引脚锁定,再编译。引脚锁定后需要再次进行编译,才能将锁定信息确定下来,同时生成芯片编程/配置所需要的各种文件。
(4)芯片编程Programming。打开编程窗口。将配置文件ALU181AA.sof下载进KX-DN系列现代计算机组成原理系统中的FPGA中。
(5)选择核心模块、32位输出显示模块、32位输入显示模块。验证ALU的运算器的算术运算和逻辑运算功能。
引脚锁定
参照4CE22核心板引脚图及对应模块引脚图,进行引脚锁定。建议如下操作:
(1)数据线D[7..0]锁定到32位输入模块的2个输入按键,提供8位二进制数据,控制CLK、LDR0、LDR1、LDR2、LDR3,把输入的数据写入到R0至R3寄存器。
(2)ALU输出F[7..0]锁定到32位输出模块的2个显示数码管,观察运算结果。
(3)CO、FZ锁定到4CE22核心板的2个显示指示灯,以便观察。
(4)控制CLK1、IR[3..2]、IR[1..0],通过4选1选择器选择一个寄存器,写入到ALU输入端的锁存寄存器。
(5)控制S[3..0]、M、CN,让ALU进行某种运算。
所有端口分配完成后,再次编译
编译通过后,下载运行调试
验证ALU运算器的算术运算和逻辑运算功能,并记录实验数据。通过实验完成如下试验表,并将实验结果值与逻辑功能表所得的理论值进行比较。
2、实验结果
仿真图:
下图仿真了四种情况,并将四种情况单独分析:
第一种为A:00110000, B:11000000, CN:1, M:0, S:1000 根据图表可知实现F=A加AB加CN的功能。实际情况与仿真结果相同,F的值为00110001,仿真结果如下图。
第二种为A:10001100, B:01110000, CN:0, M:1, S:0111 根据图表可知实现F=A/B的功能。实际情况与仿真结果相同,F的值为10001100,仿真结果如下图。
第三种为A:10111000, B:00110110, CN:0, M:1, S:1011 根据图表可知实现F=AB的功能。实际情况与仿真结果相同,F的值为00110000,仿真结果如下图。
第四种为A:00001110 B:00011101, CN:1, M:0, S:1100 根据图表可知实现F=A加A加CN的功能。实际情况与仿真结果相同,F的值为00011101,仿真结果如下图。
ALU实验数据表
S3 S2 S1 S0 | A[7..0] | B[7..0] | 算术运算 M=0 | 逻辑运算(M=1) | |
CN=0(无进位) | CN=1(有进位) | ||||
0000 | 24 | 56 | F= 24 | F= 25 | F= DB |
0001 | 24 | 56 | F= 76 | F= 77 | F= 89 |
0010 | 01 | 03 | F= FD | F= FE | F= 02 |
0011 | 01 | 03 | F= 00 | F= FF | F= 00 |
0100 | 23 | 11 | F= 45 | F= 46 | F= FE |
0101 | 01 | 03 | F= 03 | F= 04 | F= FC |
0110 | 03 | 01 | F= 02 | F= 01 | F= 02 |
0111 | 8C | 70 | F= 8C | F= 8B | F= 8C |
1000 | 30 | C0 | F= 30 | F= 31 | F= C0 |
1001 | 04 | 02 | F= 06 | F= 07 | F= F9 |
1010 | 04 | 02 | F= FD | F= FE | F= 02 |
1011 | B8 | 36 | F= 31 | F= 30 | F= 31 |
1100 | E | 1D | F= 1C | F= 1D | F= 01 |
1101 | 04 | 02 | F= 0A | F= 0B | F= FD |
1110 | 23 | 11 | F= 12 | F= 13 | F= 33 |
1111 | 04 | 02 | F= 04 | F= 03 | F= 04 |
附件一、原理图
附件二:程序源代码
module alu (S, A, B, F, M, CN, CO, FZ);
input[3:0] S; //代表十六种操作
input[7:0] A,B; //输入数据位
input M, CN; //M=0=1分别做算术运算和逻辑运算
output[7:0] F;
output CO, FZ;
//wire[7:0] F;
//wire CO;
wire[8:0] A9, B9;
reg FZ;
reg[8:0] F9;
reg [7:0] F;
reg CO;
assign A9 = {1'b0, A} ; //这两句做了拼接八位相加会溢出将第九位置0
assign B9 = {1'b0, B} ;
always @(M or CN or A9 or B9 or S) begin
case (S)
4'b0000 : if (M==0) F9<=A9+CN ; else F9<=~A9 ;
4'b0001 : if (M==0) F9 <= (A9 |B9) + CN ; else F9<=~(A9 | B9) ;
4'b0010 : if (M==0) F9 <= (A9 |((~B9)&9'b011111111))+ CN; else F9<=(~A9) & B9 ;
4'b0011 : if (M==0) F9 <= 9'b011111111-CN; else F9<=9'b000000000;
4'b0100 : if (M==0) F9 <=A9+(A9 & ((~B9)&9'b011111111))+CN; else F9<=~(A9 & B9) ;
4'b0101 : if (M==0) F9<=(A9|B9)+(A9& ((~B9)&9'b011111111))+CN; else F9<= ~B9 ;
4'b0110 : if (M==0) F9 <= A9 - B9 - CN ; else F9<= A9 ^ B9 ;
4'b0111 : if (M==0) F9 <= (A9 & (((~B9)&9'b011111111))) - CN ; else F9<= A9 & (~B9) ;
4'b1000 : if (M==0) F9 <= A9 + (A9 & B9)+CN ; else F9<= (~A9) & B9 ;
4'b1001 : if (M==0) F9 <= A9 + B9 + CN ; else F9<= ~(A9 ^ B9) ;
4'b1010 : if (M==0) F9<=(A9&(((~B9)&9'b011111111)))+(A9&B9)+CN; else F9<= B9 ;
4'b1011 : if (M==0) F9 <= (A9 & B9) - CN ; else F9<=A9 & B9 ;
4'b1100 : if (M==0) F9 <= A9 + A9 + CN ; else F9<=9'b000000001 ;
4'b1101 : if (M==0) F9 <= (A9 | B9)+A9+CN; else F9<= A9 | (~B9) ;
4'b1110 : if (M==0) F9 <= (A9 | (((~B9)&9'b011111111)))+A9+CN; else F9<= A9 | B9 ;
4'b1111 : if (M==0) F9 <= A9 - CN ; else F9<= A9 ;
default : F9 <= 9'b000000000 ;
endcase
//if (A9 == B9) FZ <= 1'b0 ; else FZ <= 1'b1 ;
F <= F9[7:0] ;
if(F==8'b00000000) FZ <= 1'b1 ; else FZ <= 1'b0 ;
if(M==0) CO <= F9[8];
end
endmodule