计算机组成原理-运算器实验

更新时间:2024-06-23 14:06:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验一 运算器实验

计算机的一个最主要的功能就是处理各种算术和逻辑运算,这个功能要由 CPU 中的运算器来完成,运算器也称作算术逻辑部件 ALU。首先安排基本运算器实验,了解运算器的基本结构。

1.1实验目的

(1) 了解运算器的组成结构。 (2) 掌握运算器的工作原理。

1.2实验设备

PC机一台,Digilent Nexys 4TM开发板,Xilinx Vivado开发套件。

1.3实验原理

Digilent Nexys 4TM开发板的通用I/O设备电路图如图1.1所示:

开发板的通用I/O设备电路图

如上所示,Nexys4 DDR板 包括2个三色LED,16个滑动开关,6个按钮开关,16个单体LED和1个数字-8的七段显示器。为了防止粗心大意的短路(假如一个FPGA针脚分派到一个按钮开关或者滑动开关被粗心大意的定为输出时将发生短路)损害,按钮开关和滑动开关通过串联电阻连接到FPGA。5个按钮开关分派到1个“+”信号的配置是瞬时开关,在正常情况下,这些瞬时开关不用时产生低信号输出,被压时产生高信号输出。另一方面,“CPU RESET”红色按钮不用时产生高信号输出,被压时产生低信号输出。“CPU RESET”按钮常常在EDK(嵌入式开发套件)设计中用于重置进程,但你也可以把它当为常用按钮开关使用。滑动开关根据他们的位置产生固定的高或低信号输入。

16个单体高效LED通过330欧姆的电阻阳极连接到FPGA,所以当其各自I/O针脚应用到逻辑高电压时他们应该是打开的。不被用户访问的额外LED表示电源,FPGA编程状态和USB和以太网端口状态。

控制显示模块的七段显示器的原理图如图1.2所示:

图1.1Digilent Nexys 4

TM

图1.2七段显示器原理图

Nexys4 DDR板包含2个4位同阳极7段LED显示器,配置表现得像1个8位数字显示。8位数字的每一个由分派在一个“数字8”图案中的7段组成,每段嵌入1个LED。如图17所示,每段LED是单独发光,所以128种模式的任何一个可以通过使某些LED段发光和另外的不发光显示在一个数字上。这些128个可能的模式中,有10个对应的十进制数字是最有用的。 图1.3显示的是7段显示器共阳极电路节点图,每个数字前的7个LED的阳极一起连接到“共同阳极”电路节点,但阴极是分开的。共同阳极信号用作数字-8显示器的8个“位可用”输入信号。在整体4个显示器上的相似段的阴极连接到7个标有CA到CG的电路节点。比如,来自8位的8个“D”阴极分到一个单独的“CD”电路节点。7个阴极信号作为数字-8显示器的输入信号。此信号连接方案创建了多路复用的显示器,其阴极信号是所有数字共有的但是只有数字的段对应的阳极信号生效时他们才照亮。

为了照亮一个段,阳极应该驱动为高电平,阴极驱动为低电平。然而,自从Nexys4 DDR使用电阻去驱动当前足够的电平到共同阳极端,阳极可用被置反。所以当激活时,AN0..7和CA..G/DP信号驱动为低电平。

图1.37段显示器共阳极电路节点图

在这个显示器上,扫描显示控制器电路常常显示8位数字。这个电路在快于人眼能察觉的更新频率下重复持续的驱动每个数字阳极信号和相应的阴极模式信号。照亮每个数字仅有时间的八分之一,但在那个数字再次照亮前由于人眼不能察觉到那个数字变暗,所以那个数字一直被照亮了。如果更新,或“刷新”频率放缓在45Hz左右,就可以注意到显示器上数字的闪烁了。

4个数字的每一个发亮和持续发光,所有的8个数字每1到16ms驱动一次,因为更新频率大约在1KHz到60Hz之间。例如,在62.5Hz的刷新频率下,整个显示器每16ms刷新一下,每个数字在刷新周期的1/8或者2ms将发光。控制器在正确的图案下必须驱动阴极信号为低电平,而驱动对应的阳极信号为高电平。为了说明这个过程,假设AN0有效而CB和CC有效,“1”将显示在数字位置1

上。然后,假设AN1有效而CA,CB和CC有效,“7”将显示在数字位置2上。在无尽的自然演替中,假设AN0,CB和CC持续驱动4ms,然后AN1,CA,CB和CC持续驱动4ms,“71”将显示首2个数字上。一个4位数字控制器的时序图例子如图1.4所示。

图1.4 4位数字控制器的时序图

本次实验的原理图如图1.5所示:

1.5运算器实验原理图

1)内置一个32位num2作为运算器的一个输入;

2)将sw0~sw7输入到num1,经过符号扩展到32位后,作为运算器的另一个输入;

3)因为运算器支持“加、减、与、或、非”5种运算,需要3位(8个操作)。将sw15~sw13输入到op作为运算器的控制信号;

4)将计算32位结果s显示到显示器上,显示器由2个4位同阳极7段LED显示器,显示器显示的是十六进制,显示器中有reset信号和clk信号。

其中运算器模块的第一个输入变量为8位操作数num1,第二个输入为3位的操作码op,输出变量为32位的运算结果result。设置一个32位变量存储第二个常量操作数num2,该操作数固定为32’h00000001;高位补0扩展第一个8位操作数到32位,这个32位数用变量Sign_extend保存;最后根据op的不同进行相应的运算操作,将操作结果赋值到输出变量。具体的运算规则如下表所示:

表1.1运算规则

操作码op 000 001 010 011 100 其他 运算结果 result = Sign_extend + num2 result = Sign_extend - num2; result = Sign_extend &num2; Sign_extend | num2; ~Sign_extend 32'h00000000;

1.4实验步骤

1.创建项目,首先打开vivado,在vivado左上侧菜单栏点击File菜单,选择New Project,如下图所示:

点击Next,设置项目名称和相应的路径,如下图所示:

一直点击Next到Add Source界面,添加display模块的源代码文件,如下图所示:

点击Next,直到Default Part界面,参照下图进行选择:

点击Next,然后点击Finish完成项目创建。

2.将display模块代码封装成ip核。点击Project Settings菜单,弹出对话框如下图,按下图方式设置后点击Apply,然后点击OK。其中Category为IP盒所在的上级目录,当添加IP盒时需要在该目录下找到相应的IP盒。

设置成功后,点击Tools,选择Create and Package IP,一直点击next按键,选择IP核保存的路径,最后生成IP核。

生成后会弹出该IP核的详细情况页面,点击Review and Package选项,然后点击Package IP,IP核就封装完成。

3.创建calculate主模块,新建项目然后按照第1步将calculate模块的两个源文件加入到项目中,如下图所示:

创建项目完成后,可以看到display模块的代码缺失,如下图所示:

添加display模块的IP核。点击Project Settings然后点击IP,点击Add Repository将生成的display模块的IP核所在的目录添加到其中,默认的情况下,display模块的IP盒在该模块项目的文件夹下,只需要将display模块的项目添加到其中就能找到相应的IP盒,然后点击OK。

点击IP Catalog,找到所添加的display模块的IP核,双击该IP核就将其加入到项目中。

双击IP盒后会弹出界面如下图,点击OK,会产生生成IP的界面,点击Generate,IP盒就生成成功了,有些调用IP盒的函数名称和IP盒的名字不匹配,需要更改IP盒名称或调用函数名称为相同名称才会添加成功。

4.检查IP盒是否添加到了正确位置,如果添加到了正确位置,display模块将被IP盒取代,添加IP盒前后项目Source界面如下图所示:

点击Run Synthesis进行对项目源文件进行综合,检查项目是否有语法错误。如下图所示:

综合完成后项目右上角会有相应的提示,会显示Synthesis Complete,而且会弹出下一步需要进行操作的界面,如下图所示:

选择弹出框的Run Implementation然后点击OK,或者直接点击Cancel,然后选择左侧菜单栏Implementation菜单栏下的Run Implementation选项进行实施项目活动的设计合成网表,完成后会有如下图所示的提示:

点击OK,选择Layout菜单下的I/O Planning进行I/O端口的管脚绑定。

首先将所有的端口的电压改为3.3V(在IO std下选择LVCMOS33)。

其中clk所要绑定的管脚为E3,rst所要绑定的管脚为N17。绑定完成后需要关闭该Implemented Design界面,关闭时会弹出提示框询问是否保存已绑定的管件生成的约束文件,选择保存,该步骤完成。

5.点击Generate Bitstream,生成相应的比特流文件,生成成功后,将开发板连接到电脑USB接口,打开开关,然后点击Open target,选择开发板后,点击Program device,然后将比特流文件下载到开发板,根据不同的输入观察相应显示器显示的内容。

实验二 存储器实验

2.1实验目的

(1)掌握存储器在设计原理,并且自己设计一个大小合适的ROM。 (2)掌握存储器的存储和取数的过程,并将存储器的内容通过显示管显示出来。

2.2实验设备

PC机一台,Digilent Nexys 4TM开发板,Xilinx Vivado开发套件。

2.3实验原理

本次实验主要是模拟数据在存储器中的存取过程,先初始化ROM存储器中的内容,在通过开关选择相应的地址,将对应的存储器中内容读出来,并通过显示管显示。实验的原理图如下图2.1所示:

resetresetans[7:0]Ins[7:0]addra[7:0]Ins_Romdouta[31:0]displayseg[6:0]s[31:0]clkclkaclk

图2.1存储器原理图

这里我们使用到两个IP核,其中一个是ins_ROM核实系统自带的,通过该

IP核我们实现数据的存取,通过8位地址开关的选择,将ROM中对应的32位指令取出来并送往display。而display核是我们自己设计的IP核,通过display可以将ROM中取出的32位数据在数码管上显示出来。

存储容量是指存储器可以容纳的二进制信息量,用存储器中存储地址数与存储字位数的乘积表示。

2.4实验步骤

1.按照实验一步骤封装display模块的IP盒。 2.新建项目用于实现存储器功能

添加设计源文件。

3. 按照实验一步骤将display模块IP盒添加到项目中。

4. 在IP Catalog > Memories & Storage Elements > RAMs & ROMs> Block Memory Generator目录底下,找到系统自带的rom核并添加。

双击之后得到Basic一栏的基本属性:

Component Name命名为:Ins_Rom。Native、单端口、ROM不要ECC校验、最小面积算法。

接着设置Port A Option的基本属性

数据宽度32位,要256个数据,地址线8根。 接着设置option选项属性:

若有存储器初始化文件,这里指定文件的位置,文件为prgmip32.coe文件。这里我们会给出创建好的初始文件。点击OK就会得到相应的IP核。

现在我们可以看到我们已经成功调用了两个ip核

5. 接着我们按照实验一的步骤进行综合与实现以及管脚的约束。其中时钟信号clk和重置信号rst与实验一绑定管脚相同。管脚绑定之后按照实验一的步骤进行比特流的生成并将比特流文件下载到开发板上,观察结果。

实验三 控制器实验

控制器是计算机的核心部件,计算机的所有硬件都是在控制器的控制下,

完成程序规定的操作。控制器的基本功能就是把机器指令转换为按照一定时序控制机器各部件的工作信号,使各部件产生一系列动作,完成指令所规定的任务。

3.1 实验目的

(1)掌握单周期CPU控制器的工作原理及其设计方法。 (2)掌握各个控制信号的作用和生成过程。

3.2 实验设备

PC机一台,Digilent Nexys 4TM开发板,Xilinx Vivado开发套件。

3.3实验原理

控制器的基本任务是完成当前指令的翻译和执行,即将当前指令的功能

转换成可以控制的硬件逻辑部件工作的命令序列,完成数据传送和各种处理操作。本实验根据MIPS的31种类型的指令以及根据该指令结构所设计出的数据通路模拟其中控制单元生成控制信号的过程。其中MIPS的31条指令类型如表3.1所示:

表3.1 MIPS的31种指令 助记符 BIT # 31..26 R-类型 add addu sub op 000000 000000 000000 指 令 格 式 25..21 rs rs rs rs 20..16 rt rt rt rt 15..11 rd rd rd rd 10..6 shamt 5..0 func 示 例 示例含义 $1=$2+S3 $1=$2-S3 操作及解释 (rd)←(rs)+(rt); rs=$2,rt=$3,rd=$1 (rd)←(rs)+(rt); rs=$2,rt=$3,rd=$1,无符号数 (rd)←(rs)-(rt); rs=$2,rt=$3,rd=$1 00000 100000 add $1,$2,$3 00000 100010 sub $1,$2,$3 00000 100001 addu $1,$2,$3 $1=$2+S3 subu and or xor nor slt sltu sll srl sra sllv srlv srav jr I-类型 addi andi ori xori lui lw sw beq bne slti sltiu J-类型 j jal 000000 000000 000000 000000 000000 000000 000000 rs rs rs rs rs rs rs rt rt rt rt rt rt rt rt rt rt rt rt rt 00000 rt rt rt rt rt rt rt rt rt rt rt rt rt rd rd rd rd rd rd rd rd rd rd rd rd rd 00000 00000 100011 subu $1,$2,$3 $1=$2-S3 00000 100100 and $1,$2,$3 00000 100101 or $1,$2,$3 00000 100110 xor $1,$2,$3 00000 100111 nor $1,$2,$3 00000 101010 slt $1,$2,$3 00000 101011 sltu $1,$2,$3 shamt 000000 sll $1,$2,10 shamt 000010 srl $1,$2,10 shamt 000011 sra $1,$2,10 00000 000100 sllv $1,$2,$3 00000 000110 srlv $1,$2,$3 $1=$2&S3 $1=$2|S3 $1=$2^S3 (rd)←(rs)-(rt); rs=$2,rt=$3,rd=$1,无符号数 (rd)←(rs)&(rt); rs=$2,rt=$3,rd=$1 (rd)←(rs) | (rt); rs=$2,rt=$3,rd=$1 (rd)←(rs)^(rt); rs=$2,rt=$3,rd=$1 $1= ~($2 | S3) (rd)←~((rs) | (rt)); rs=$2,rt=$3,rd=$1 if($2<$3) $1=1 else if (rs< rt) rd=1 else rd=0;rs=$2,rt=$3, rd=$1 $1=0 if($2<$3) if (rs< rt) rd=1 else rd=0;rs=$2,rt=$3, rd=$1, $1=1 else 无符号数 $1=0 $1=$2<<10 $1=$2>>10 $1=$2>>10 $1=$2<<$3 $1=$2>>$3 (rd)←(rt)<>shamt, rt=$2, rd=$1, shamt=10, (逻辑右移) (rd)←(rt)>>shamt, rt=$2, rd=$1, shamt=10, (算术右移,注意符号位保留) (rd)←(rt)<<(rs), rs=$3,rt=$2,rd=$1 (rd)←(rt)>>(rs), rs=$3,rt=$2,rd=$1, (逻辑右移) (rd)←(rt)>>(rs), rs=$3,rt=$2,rd=$1, (算术右移,注意符号位保留) (PC)←(rs) (rt)←(rs)+(sign-extend)immediate,rt=$1,rs=$2 (rt)←(rs)+(sign-extend)immediate,rt=$1,rs=$2 (rt)←(rs)&(zero-extend)immediate,rt=$1,rs=$2 (rt)←(rs)|(zero-extend)immediate,rt=$1,rs=$2 000000 00000 000000 00000 000000 00000 000000 000000 000000 000000 op 001000 001100 001101 001110 rs rs rs rs rs rs rs rs rs rs 00000 000111 srav $1,$2,$3 $1=$2>>$3 00000 001000 jr $31 immediate immediate immediate immediate immediate immediate immediate offset offset offset offset immediate immediate addi $1,$2,10 $1=$2+10 addiu $1,$2,10 $1=$2+10 andi $1,$2,10 $1=$2&10 ori $1,$2,10 xori $1,$2,10 $1=$2|10 $1=$2^10 goto $31 addiu 001001 001111 00000 100011 101011 000100 000101 001010 001011 op 000010 000011 rs rs rs rs rs rs (rt)←(rs)^(zero-extend)immediate,rt=$1,rs=$2 (rt)←immediate<<16 & 0FFFF0000H,将16位lui $1,10 $1=10*65536 立即数放到目的寄存器高16位,目的寄存器的低16位填0 $1=Memory[ (rt)←Memory[(rs)+(sign_extend)offset], lw $1,10($2) $2+10] rt=$1,rs=$2 Memory[ Memory[(rs)+(sign_extend)offset]←(rt), sw $1,10($2) $2+10] =$1 rt=$1,rs=$2 if($1=$2) if ((rt)=(rs)) then (PC)←(PC)+4+( (Sign-Extend) beq $1,$2,40 goto PC+4+40 offset<<2), rs=$1, rt=$2 if($1≠$2) if ((rt)≠(rs)) then (PC)←(PC)+4+( bne $1,$2,40 goto PC+4+40 (Sign-Extend) offset<<2) , rs=$1, rt=$2 if($2<10) if ((rs)<(Sign-Extend)immediate) then (rt)←1; slti $1,$2,10 $1=1 else else (rt)←0, rs=$2, rt=$1 $1=0 if($2<10) if ((rs)<(Zero-Extend)immediate) then (rt)←1; sltiu $1,$2,10 $1=1 else else (rt)←0, rs=$2, rt=$1 $1=0 j 10000 jal 10000 goto 10000 $31=PC+4 goto 10000 (PC)←( (Zero-Extend) address<<2), address=10000/4 ($31)←(PC)+4; (PC)←( (Zero-Extend) address<<2), address=10000/4 address address address 由上表可知该指令主要分为三大类,分别为R-类型、I-类型和J-类型。每类指令对应的控制信号也不相同,根据这些指令所设计的数据通路如图3.1所示:

图3.1单周期CPU数据通路

本次实验是主要模拟指令生成控制信号的过程,由于控制单元生成的控制信号较多,本次实验只取其中的一部分信号组成16位控制信号以供输出,这十六位控制信号的作用如表3.2所示:

表3.2控制信号具体表示 信号名称 所在位置 含义 ALUSrc 0 需要进行立即数的32位扩展作为第二操作数 Sftmd 7 是R-类型的移位指令 RegWrite 1 需要写寄存器的指令 ALUOp 2-3 是R-类型或需要立即数作32位扩展的指令1位为1, beq、bne指令则0位为1 Jmp 9 是j指令 I_format 4 是I-类型指令 Branch 5 是beq指令 nBranch 6 是bne指令 信号名称 所在位置 含义 Jal 8 是jal指令 Sftm 10-12 移位指令所对应的具体移位控制信号 ALU_ctl 13-15 R-类型运算指令对应具体的运算,+、-、|、&等命令 本次实验根据输入指令从寄存器堆中选取相应的寄存器,然后读取该寄存器获得相应32位指令,取其高5位和低5位送入控制器单元,由控制单元进行译码,输出相应的控制信号。该控制器组成原理图如下图所示:

ALUSrcled[0]RegWriteLed[1]ALUOpLed[3:2]Led[4]Opcode[5:0]I_formatBranchsw[3:0][31:26]Led[5]寄存器堆ins[31:0][5:0]控制器led[15:0]nBranchLed[6]SftmdLed[7]Function_opcode[5:0]JalLed[8]JmpLed[9]SftmLed[12:10]ALU_ctlLed[15:13]

图3.2 控制器组成原理图

该控制器的寄存器堆中有16个寄存器,每一个寄存器都预先分配了一条指令信息,根据4位输入读取寄存器堆中相应的一个寄存器。控制器主要实现对输入的10位指令操作码的解析,生成16位控制信号,然后以led灯显示每条指令对应的控制信号。

3.4实验步骤

1.编写寄存器堆模块。该模块有4位输入和32位输出,首先将16种类型的16条指令写入寄存器堆的寄存器中,然后根据4位输入选择相应的寄存器,将寄存器中数据写入到输出变量中。开关输入数据、寄存器编号与指令的对应规则如下表所示:

表3.3寄存器堆模块约束

开关输入 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 寄存器编号 0 1 2 3 4 5 6 7 8 9 10 寄存器数据 00000000001000100001100000100000 00000000001000100001100000100001 00000000001000100001100000101010 00000000001000100001100000101011 00000000001000000000000000001000 00100000001000100001100000101010 00100100001000100001100000101010 00111100000000100001100000101010 10001100001000100001100000101010 10101100001000100001100000101010 00010000001000100001100000101010 含义 R-类型add R-类型addu R-类型slt R-类型sltu R-类型jr I-类型addi I-类型addiu I-类型lui I-类型lw I-类型sw I-类型beq 1011 1100 1101 1110 1111 11 12 13 14 15 00010100001000100001100000101010 00101000001000100001100000101010 00101100001000100001100000101010 00001000001000100001100000101010 00001100001000100001100000101010 I-类型bne I-类型slti I-类型addi J-类型j J-类型jal

2.将已经提供的控制器模块文件封装成IP核。

3.编写主模块,主模块有4位输入和16位输出,主模块首先调用寄存器堆模

块生成32位指令信号,然后调用控制器模块生成相应的控制信号,将这16位控制信号赋值到输出变量中。

4.依次按照图3.3的步骤综合项目源文件、实施活动的设计合成的网表。综合的目的是检查代码是否存在语法错误,生成网表后可以绑定相应的管脚。

图3.3

5.绑定输入输出变量对应的开发板的引脚,将输入变量对应的端口绑定到开关的低4位,将输出变量的对应端口绑定到LED灯对应的十六位,如原理图所示,并保存生成的约束文件。然后按照图3.3的第3步骤生成编码文件。

6.连接开发板,并打开开发板开关,将程序下载到开发板上,观察输入不同类型的指令对应的LED灯的明暗情况。

实验四 取指令并完成译码操作的实验

4.1实验目的

(1)掌握单周期CPU执行指令的过程。

(2)掌握指令译码和各个控制信号的作用和生成过程。

4.2实验设备

PC机一台,Digilent Nexys 4TM开发板,Xilinx Vivado开发套件。

4.3实验原理

计算机CPU执行指令的过程主要分为7个步骤:

(1)取指:根据程序计数器(PC)从内存中取指令,PC的值为该指令在内(2)计算PC的值:能自动计算PC的值以确定下一条指令的地址; (3) 译码:对指令操作码进行译码,以产生控制信号来控制指令进行相应(4)取操作数:根据指令字段的内容,选择从存储器读取数据或直接从寄存器取数;

(5)算术/逻辑运算:根据译码结果,进行算术/逻辑运算或者计算操作数的(6)结果写回:根据指令的要求对运算(处理)后的数据进行写回操作,(7)时钟控制:通过时钟信号控制指令操作的周期。

本次实验主要模拟CPU取指令和译码阶段。实验的原理图如图4.1所示: 地址;

如写存储器或写寄存器;

存中存放的地址;

的操作;

ALUSrcled[0]RegWriteLed[1]ALUOpLed[3:2]Led[4]I_formatBranchsw[7:0]addra[7:0]Ins_Rom[31:27]douta[31:0][5:0]Opcode[5:0]Led[5]控制器led[15:0]nBranchLed[6]SftmdLed[7]clkclkaFunction_opcode[5:0]JalLed[8]JmpLed[9]SftmLed[12:10]ALU_ctlLed[15:13]

图4.1取指令译码原理图

由外部输入的7位地址到ROM模块,ROM模块根据输入地址读取相应的32位数据,得到32位指令数据后由控制器进行译码生成相应的控制信号输出。

4.4实验步骤

1.添加ROM的IP核,并设计相应的输入输出端口和加载的指令文件。如图4.2所示:

图4.2ROM的IP核设计图

2.添加控制器模块的IP核。

3.编写主模块,主模块有8位地址输入位,1位时钟输入信号和16位输出信号,编写完成后,综合项目源文件,然后实施活动的设计合成的网表,对这9位输入和16位输出进行管脚绑定,开关的低8位对应8位输入地址,16位输出对应LED灯的16位,绑定完成后保存生成的约束文件,最后生成相应的编码文件。

4. 连接开发板,并打开开发板开关,将程序下载到开发板上,观察输入不同地址对应的LED灯的明暗情况。

本文来源:https://www.bwwdw.com/article/c723.html

Top