电子科大-系统结构实验-解决数据冒险
电子科大计算机操作系统实验报告级

电子科技大学实验报告学生姓名:郫县LBJ 学号:指导教师:温柔可爱的刘杰彦实验地点:主楼A2-413 实验时间:2017年4月22日上午一、实验室名称:计算机学院主楼机房二、实验项目名称:进程与资源管理实验分工:郫县LBJ 进程管理设计郫县小胖子资源管理设计郫县威斯布鲁克进程调度与时钟中断设计三、实验学时:2四、实验原理:此处的实验原理在指导书上非常丰富,因此不照搬过来,主要写出所要使用到知识点,具体实现过程中的原理分析见报告第八部分“实验步骤”处。
(一)总体设计系统总体架构如图1所示,最右边部分为进程与资源管理器,属于操作系统内核的功能。
要求能够设计与实现一个简单的进程与资源管理器,具有如下功能:完成进程创建、撤销和进程调度;完成多单元 (multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。
图1 系统总体结构(二) Test shell设计应具有的功能:1、从终端或者测试文件读取命令;2、将用户需求转换成调度内核函数(即调度进程和资源管理器);3、在终端或输出文件中显示结果:如当前运行的进程、错误信息等。
(三)进程管理设计1、进程状态与操作2、进程控制块结构PCB3、主要函数:创建进程、撤销进程(四)资源管理设计1、主要数据结构RCB2、请求资源3、释放资源(五)进程调度与时钟中断设计关键:使用基于优先级的抢占式调度策略,在同一优先级内使用时间片轮转算法。
参考课上ppt:五、实验目的:设计和实现进程与资源管理,并完成Test shell的编写,以建立系统的进程管理、调度、资源管理和分配的知识体系,从而加深对操作系统进程调度和资源管理功能的宏观理解和微观实现技术的掌握。
六、实验内容:设计与实现一个简单的进程与资源管理器,要求具有如下功能:完成进程创建、撤销和进程调度;完成多单元 (multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。
电子科技大学CPU设计:《单周期CPU的设计与实现》-实验指导书

电子科技大学计算机科学与工程学院单周期CPU的设计与实现实验指导书[计算机组成原理实验]张建2013-12-13目录前言 (1)1.1 实验内容 (2)1.2实验要求 (2)2. 实验环境 (3)2.1 硬件平台 (3)2.2 软件平台 (3)2.3 实验主要仪器设备连接框图 (4)3. 实验原理 (5)3.1 概述 (5)3.2 单周期CPU的总体电路 (5)3.3 MIPS指令格式 (6)3.4 数据路径设计 (7)3.4.1 下一条指令地址的选择 (7)3.4.2 ALU的输入端 (8)3.4.3寄存器堆的输入端 (8)4. 基本功能部件的设计与实现 (10)4.1 32位2选1选择器的设计与实现 (10)4.2 32位4选1选择器的设计与实现 (18)4.3 5位2选1选择器的设计与实现 (19)4.4 带有异步清零的32位D触发器的设计与实现 (19)4.5 移位器的设计 (20)4.6 32位加/减法器的设计与实现 (20)5.运算器(ALU)的设计与实现 (21)6.寄存器堆(Register File)的设计与实现 (24)7.控制器(Control Unit)的设计与实现 (27)8. CPU的封装 (30)9. 测试 (32)9.1 指令存储器及测试程序 (32)9.2 数据存储器及测试数据 (33)9.3 仿真测试 (33)9.4 下载到开发板验证 (35)附件: (39)BTN_Anti_Jitter模块 (39)Hex7seg_decode模块 (39)前言《计算机组成原理》是计算机科学专业的一门重要专业基础课。
在该课程中的理论学习中系统地阐述了计算机各组成部件的工作原理、逻辑实现和设计方法及将各部件连接成整机的方法,计算机硬件与底层软件的接口,培养了学生对计算机硬件系统的分析、开发与设计的基本技能能力。
本实验开设的目的是让学生通过设计一个单周期的CPU,加深对计算机各组成部件功能的理解和掌握,更好地理解计算机的基本工作原理,培养和锻炼学生掌握计算机硬件设计的基本方法和技能。
电子科技大学计算机操作系统—操作系统实验

附件1操作系统上机实验进程调度实验时间:16 机时实验验收时间:17~18周实验成绩:占总成绩的20%一、实验目的和要求1.目的进程是操作系统最重要的概念之一,进程调度又是操作系统核心的主要内容。
本实习要求学生独立地用高级语言编写和调试一个进程调度程序,模拟各种调度算法。
调度算法可任意选择或自行设计,例如,简单轮转法和优先数法等。
本实验可加深对于进程调度和各种调度算法的理解。
2.要求(1)设计一个有n(n≥8)个进程并行的进程调度程序。
每个进程由一个进程控制块(PCB)表示。
进程控制块通常应包含下述信息:进程名(或序号)、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等(要求包括4种基本状态:运行、就绪、阻塞、完成),PCB块的内容应根据调度算法的不同特点而增删。
(2)调度程序应包含3种或3种以上不同的调度算法,运行时可任意选一种,以利于各种算法的分析比较。
其中至少有一种为综合调度算法,并要求是自己设计的算法。
(3)系统应能直观、准确地动态显示(用动态的表或图)各进程状态和参数的变化情况,便于观察诸进程调度的动态显示过程。
(4)要求完成一个完整的软件系统,用户界面友好,操作简便,可采用菜单选择或图形用户界面(GUI)实现。
说明:在windows 环境下开发,也可用其它工具或软件实现进程调度过程的模拟。
要求画出至少一个综合调度算法的实现流程图。
二、调度算法1.算法本程序可选用来先服务(FCFS)算法、最短CPU运行期优先(SCBF)算法、最高优先权(HPF)算法、时间片轮转(RR)算法及多级反馈队列算法等对多个进程进行调度。
同时注意对自己设计的综合调度算法要认真分析其特点。
每个进程处于运行、就绪、等待、完成四种状态,并假定起始状态都是就绪状态。
为了便于处理,程序中进程的运行时间以时间片为单位计算。
各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。
进程控制块结构如下图所示:2.算法举例以两种典型算法为例说明实现的算法:⑴优先数法(动态优先数)系统中各进程的初始优先级与进程类型(前台或后台,交互或批处理,计算或I/O)有关。
电子科大高级计算机系统结构_系统性能评价

例1: 假设指令集中条件分支指令有两种不同设计方法:
(1) CPUA: 通过比较指令设置条件码, 然后测试条件码 进行分支;
(2) CPUB: 在分支指令中包括比较过程。
在两种CPU中, 条件分支指令都占用2个时钟周期, 所有其它指令占用1个时钟周期。
对于CPUA, 假设执行的指令中分支指令占20%; 由 于每个分支指令之前都需要有比较指令, 因此比较 指令也占20%。由于CPUA在分支时不需要比较, 因此假设它的时钟周期时间比CPUB快1.25倍。
程序控制: 15%、其他15% 假设: 程序控制类指令和其它指令与定点加法指
令的速度相同。
高级计算机结构
MIPS=
I/O的性能
(如I/O总线数目和带宽、磁盘通道的数目和带宽、 磁盘的性能(转速、寻道时间、扇区缓存容量等)
网络的性能
操作系统的性能
(系统调用/中断/进程切换/线程调度开销、存储映射/ 文件系统的缓冲区性能和吞吐量等。
编译器的性能 等
CPU按流水线方式工作, 编译器对CPU性能影响很大
高级计算机结构
高级计算机结构
第七章 系统性能评价
例2: DJS-130小型机, 产品说明书参数每秒50万次,即
MISP=0.5, 该参数为执行定点加法指令的速度。
定点加法指令速度为乘法和除法运算指令执行速
度的1/100。
— 计算等效指令速度: 应用统计, 各类指令出现的频率为: 加/减法: 50%、乘法: 15%、除法: 5%
较常采用排队论、随机过程、均值分析等方法
进行近似求解,比如流水线性能、多处理器系统 性能分析、软件可靠性静态评估等。
特点是理论严密, 对基础理论的掌握要求较高。 优点是节约人力/物力, 可应用于设计中的系统。
计算机组成原理实验指导书 电子科技大学

计算机专业核心硬件课程实验指导书电子科技大学计算机学院实验平台介绍一.硬件部分:1.核心适配板:主控芯片是XILINX公司的SPRTAN XC3S500E(50万逻辑门电路),它具有可编程接口(JTAG),通过并口与PC机相连,该芯片可以反复擦写。
2.实验箱上输入/输出接口:⑴按键开关:键按下为抵电平,弹起为高电平,实验箱上的序号是AN1,AN2。
用它可以形成脉冲信号。
(2个)⑵拨动开关:开关向上为高电平,向下为低电平,实验箱上的序号是K1~K12。
(12个)⑶发光二极管:分成红、绿、黄三种颜色。
高电平点亮,低电平熄灭。
实验箱上的序号是L1~L24。
(24个)(4)8段LED数码管:低电平点亮相应的段。
实验箱上的序号是LED1~LED4。
(4个)3. 用户接口部分二.软件部分:本实验系统的开发软件采用Xilinx公司的ISE集成开发环境。
其软件开发流程:1.创建工程*双击桌面“Xilinx ISE 7.1”;*选择“File” New Project”,屏上显示(图1);●填写“工程项目名”和文件存放路径。
*点击“下一步”,屏上显示(图2);●选择所使用芯片的类型、封装等信息;●选择综合工具(Synthesis Tool)(图1)(图2)2.设计输入*在(图3)对话框,输入文件名,同时选左框中的”Verilog Module”*输入Verilog HDL 的源程序代码(图3)3.约束(引脚绑定)*在“Process View”框中,点击“User Constraints”前的‘+’,双击“Assign Package Pins”*在“Design Browser”框中,选“I/O Pins”*在“Design Object List…”框中‘Loc’栏添入芯片的引脚序号,注意在引脚序号前加上字母p;4.综合在“Process View”框中,点击“Synthesize-XST”;5.实现在“Process View”框中,点击“Implement Design”;6.下载在“Process View”框中,点击“Configure Device(Impact)”;●选“Boundary-Scan Mode”●选“Automatically connect to cable….”(注意此时必须将实验目标板通过并口与PC相连,同时打开实验箱的电源!),屏上显示下图。
电子科技大学 计算机 学院 实验报告模板

for(j=1;j<=i;j++)
{
if(number(i,j)==1)
{
b[a]=(float)j/(float)i;
a++;
}
}
}
for(i=1;i<a;i++)
for(k=0;k<a-i;k++)
{
if(b[k]>b[k+1])
{
c=b[k];
b[k]=b[k+1];
b[k+1]=c;
}
}
for(i=0;i<a;i++)
除此之外,在进行临界测试时,由于0/1是单独输出的,所以当n=0是程序运行正常,但当n比较大时,由于数组b定义的长度为100,所以产生越界问题,而且当n较小时,数组b不能被完全利用,部分内存被浪费,所以可以改进为动态数组,来避免浪费内存和越界问题。
六.总结及心得体会:相对简单,但是写完程序才发现很多不完善的地方,有待改进。此外,C,C++基础不好,所以写程序比较困难,希望老师能循序渐进地改善我们的编程能力。
n阶法雷序列元素存储到数组b中,然后再利用冒泡排序将所有元素按升阶排列,得到n阶法雷序列
3.算法时间复杂度分析
存储操作的算法时间复杂度为 ,排序操作的算法时间复杂度为 ,所以总的算法时间复杂度为 (效率出奇得低)
4.核心程序
for(i=1;i<=m;i++)
{
for(j=1;j<=i;j++)
{
if(number(i,j)==1)
电子科技大学计算机学院
标准实验报告
电子科大-系统结构实验-补全流水线结构图

实验报告课程名称:计算机系统结构实验学院:计算机科学与工程学院专业:计算机科学与技术指导教师:好老师学生姓名:爱学习的小学生 6666666666666 实验成绩:日期:2017年5月5日电子科技大学实验报告一、实验项目名称:流水线代码分析二、实验室名称:主楼A2-412实验时间:2017年5月5日三、实验目的1. 熟悉代码中的模块名和接口信号,并理解其作用;2. 通过补全流水线的模块图,进一步熟悉代码中各模块的连接细节,加强对流水线CPU工作原理的掌握。
四、实验原理(一)V erilog HDL知识回顾(1)5种抽象的级别:系统级、算法级、RTL级、门级、开关级(2)功能:1. 可描述顺序执行或并行执行的程序结构;2. 用延迟表达式或事件表达式来明确地控制过程的启动时间;3. 通过命名的事件来触发其他过程里的激活行为或停止行为。
4.提供了条件(如if_else,case等)循环程序结构;5.提供了可带参数并且非零延续时间的任务(task)程序结构;6.提供了可定义新的操作符的函数(function)结构;7.提供了用于建立表达式的算术运算符、逻辑运算符、位运算符。
8.提供了一套完整的组合型原语(Primitive);(二)V erilog HDL的基本语法(三)流水线CPU原理图(四)I SE的使用(五)流水线CPU工作原理五、实验内容1. 列出代码中的模块名和接口信号,并写出他们的作用;2. 补全流水线的模块图:a)在现有图的基础上,在对应模块的输入输出接口处补全端口的名字;b)在现有图的基础上,补全未画出的模块和信号连线。
3. 对补全的流水线模块图作必要的文字说明,解释其工作原理。
六、实验器材(设备、元器件)ISE Design Suite 14.7集成开发环境,编程语言:Verilog HDL硬件描述语言七、实验步骤1.看懂老师给的CPU源代码;2.仔细对比各模块的形参,与最顶层模块中的实参,列出代码中的模块名和接口信号,并写出他们的作用;3.根据代码补充完善“流水线结构补充图”:a)在现有图的基础上,在对应模块的输入输出接口处补全端口的名字;b)在现有图的基础上,补全未画出的模块和信号连线。
2022年电子科技大学(沙河校区)软件工程专业《计算机系统结构》科目期末试卷A(有答案)

2022年电子科技大学(沙河校区)软件工程专业《计算机系统结构》科目期末试卷A(有答案)一、选择题1、在计算机系统设计中,比较好的方法是( )A.从上向下设计B.从下向上设计C.从两头向中间设计D.从中间开始向上、向下设计2、在计算机系统设计中,比较好的方法是()。
A.从上向下设计B.从下向上设计C.从两头向中间设计D.从中间开始向上、向下设计3、系列机软件应做到( )。
A.向前兼容,并向上兼容B.向后兼容,力争向上兼容C.向前兼容,并向下兼容D.向后兼容,力争向下兼容4、不同系列的机器之间,实现软件移植的途径不包括()。
A.用统一的高级语言B.用统一的汇编语言C.模拟D.仿真5、静态流水线是指( )A.只有一种功能的流水线B.功能不能改变的流水线C.同时只能完成一种功能的多功能流水线D.可同时执行多种功能的流水线6、以下说法中,不正确的是()。
软硬件功能是等效的,提高硬件功能的比例会A.提高解题速度B.提高硬件利用率C.提高硬件成本D.减少所需存储器用量7、设16个处理器编号分别为0,1,2,...,15用Cube,互联函数时,第10号处理机与第()号处理机相联。
A.11B.8C.14D.28、对机器语言程序员透明的是( )。
A.中断字B.主存地址寄存器C.通用寄存器D.条件码9、对汇编语言程序员透明的是()A.I/O方式中的DMA访问B.浮点数据表示C.访问方式保护D.程序性中断10、对系统程序员不透明的应当是( )。
A.Cache存贮器XB.系列机各档不同的数据通路宽度C.指令缓冲寄存器D.虚拟存贮器二、填空题11、评价虚拟存贮器所用替换算法的好坏,主要是看主存________率的高低,其次看算法是否易于实现,以及所需的辅助软硬件的多少。
12、消息寻径方式可以分为两大类:________和________13、寻径的基本原则是:________或________14、交叉访问存储器通常有两种交叉编址方式:________和________15、Cache存贮器对应用程序员是________的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告课程名称:计算机系统结构实验学院:计算机科学与工程学院专业:计算机科学与技术指导教师:好老师学生姓名:爱学习的小学生 20实验成绩:日期:2017年5月19日电子科技大学计算机学院实验中心电子科技大学实验报告一、实验项目名称:解决数据冒险二、实验室名称:主楼A2-412 实验时间:2017年5月19日三、实验目的在给出的流水线代码基础上,增加内部前推数据通路、暂停流水线数据通路和关闭写使能信号的数据通路,解决普通的数据冒险和load数据冒险,通过完成本次实验,更好地理解和掌握解决数据冒险的原理,学以致用,增强编写程序的能力。
四、实验原理(一)数据冒险的定义由于流水线上指令重叠执行,改变了原来串行执行的读/写操作数顺序,使得后面依赖前面指令结果的指令得不到准备好的数据,这样的现象叫做数据冒险(数据相关)。
回顾数据冒险的程序例子I1: add r1,r2,r3I2: sub r4,r1,r5I3: and r6,r7,r1I4: or r8,r1,r9I5: addi r10,r1,100I1下面有3条指令不能从寄存器r1读出正确的数据。
(二)数据冒险的解决方案1、暂停流水线如上图所示,暂停流水线到最初的指令执行完毕,可以解决数据冒险,但是会涉及到两个问题,即“如何检测出数据冒险”和“如何暂停流水线”。
如何检测数据冒险a.比较器;I1指令写目的寄存器rd,I2和I3的源操作数是寄存器rs1或rs2中的数据,I2、I3的rs1或rs2与I1的目的寄存器号rd相等时才有可能发生数据冒险。
b.操作码参与检测;由于指令格式中源寄存器号rs2与立即数部分重叠,而立即数是不会出现冒险的,因此,指令操作码必须要参与检测(区分是寄存器操作数还是立即数)。
c.WREG信号也应参与检测(实际上,WREG也是从操作码中得出的);如何暂停流水线暂停条件判断电路STALL的输入包括OPCODE,ID_rsl,ID_rs2,EXE_rd,EXE_WREG,MEM_rd和MEM_WREG。
输出为DEPEN。
封锁本条指令所产生的影响的方法是把DEPEN分别和译码器的输出Decoder_WZ,Decoder_WMEM和Decoder_WREG相与,再送到ID级和EXE级之间的流水线寄存器的输入端。
因为只有这些写信号才改变处理机或存储器的状态,因而我们不必去封锁其它诸如ALUOP或多路器的选择信号。
封锁其后续指令的方法是禁止向IR及PC写入新的数据,即把DEPEN接到IR和PC的写使能端WIR和WPC。
当这两个信号为0时,禁止向IR和PC写人数据。
2、内部前推技术数据相关本质:一条指令执行时要用到上面指令的计算结果,但这个结果尚未被写入寄存器堆。
而实质上,此时结果已经由ALU计算出来了,在流水线寄存器R和C中。
由此,我们可以在ALU的两个数据输入端各加一个多路器,使R和C中的数据能被直接送到ALU的输入端,这就是所谓的内部前推。
以下是检测数据相关的完整信号:EXE_A_DEPEN=(ID_rs1= =EXE_rd)(EXE_WREG= =1)(ID_rs1IsReg)EXE_B_DEPEN=(ID_rs2= =EXE_rd)(EXE_WREG= =1)(ID_rs2IsReg)+(ID_rd= =EXE_rd)(EXE_WREG= =1)(store)MEM_A_DEPEN=(ID_rs1= =MEM_rd)(MEM_WREG= =1)(ID_rs1IsReg)MEM_B_DEPEN=(ID_rs2= =MEM_rd)(MEM_WREG= =1)(ID_rs2IsReg)+(ID_rd= =MEM_rd)(MEM_WREG= =1)(store)ID_rs1IsReg=and+andi+or+ori+add+addi+sub+subi+load+storeID_rs2IsReg=and+or+add+sub(EXE_WREG= =1)表示EXE级的指令确实要更新寄存器,没被取消(ID_rs1IsReg)条件是为了确认是寄存器,而不是立即数EXE_rd表示EXE级的流水线目标寄存器rdDEPEN=A_DEPEN + B_DEPENA_DEPEN=EXE_A_DEPEN + MEM_A_DEPENB_DEPEN=EXE_B_DEPEN + MEM_B_DEPEN(三)load指令的处理——暂停与内部前推相结合ALU指令在EXE级结束后,结果就出现在流水线寄存器R中,后续指令可以通过内部前推电路来直接使用它。
但有一种情况是例外:load r1, 200(r2);add r3, r1, r4;load指令在EXE级结束后,还在忙着访问存储器。
在MEM级结束后,结果才出现在流水线寄存器D中,见下图。
这时,即使使用内部前推技术也无法消除load指令与它的下一条相关指令之间的第一个“气泡”。
我们的是由硬件负责检测与load指令的相关性。
为了保证操作结果的正确性,我们采用暂停流水线一个周期的方法。
第二个“气泡”用内部前推技术加以消除。
我们给出下面的用于实现load流水线暂停的控制信号的表达式。
这个信号是在ID级产生,并且使用与暂停ALU流水线类似的方法:LOADDEPEN=EXE_A_DEPEN+EXE_B_DEPENEXE_A_DEPEN=(ID_rs1= =EXE_rd)(EXE_SLD= =1)(ID_rs1IsReg)EXE_B_DEPEN=(ID_rs2= =EXE_rd)(EXE_SLD= =1)(ID_rs2IsReg)+(ID_rd= =EXE_rd)(EXE_SLD= =1)(store)ID_rs1IsReg=and+andi+or+ori+add+addi+sub+subi+load+storeID_rs2IsReg=and+or+add+sub其中, EXE_SLD= =1表示WB级的多路选择器选择中间寄存器D的值EXE_SLD,表示EXE级是load指令。
或者也可以把译出的load指令打入流水线寄存器,使用它而不是EXE_SLD。
五、实验内容在给出的流水线代码基础上,增加内部前推数据通路、暂停流水线数据通路和关闭写使能信号的数据通路以解决普通的数据冒险和load数据冒险。
六、实验器材(设备、元器件)ISE Design Suite 集成开发环境,编程语言:Verilog HDL硬件描述语言七、实验步骤(一)创建工程DataHazardAndForwarding(二)将原工程文件导入(三)在pipelinedcpu中添加下列变量:wire[1:0] idadepend,idbdepend;//id 级a、b dependwire[1:0] exeadepend,exebdepend;// exe级 a、b dependwire wpc;//写pc为了解决数据冒险,需要将depend的值保存下来,所以需要两个a、bdepend值wpc用于暂停流水线,从而实现load冒险时暂停指令留出以及写寄存器和写mem (四)为了实现数据通路,需要在下列模块的参数列表上增加一些参数增加后的代码如下pipepc prog_cnt (npc,clock,resetn,pc,wpc);//程序计数器PC//**********pipeir inst_reg (pc4,ins,clock,resetn,dpc4,inst,wpc);//IF级与ID级之间的寄存器,即指令寄存器IR//******pipeid id_stage (dpc4,inst,//指令译码ID级wrn,wdi,wwreg,clock,resetn,bpc,jpc,pcsource,dwreg,dm2reg,dwmem,daluc,daluimm,da,db,dimm,drn,dshift,djal,z,ern,mrn,ewreg,mwreg,idadepend,idbdepend,em2reg,wpc);pipedereg de_reg (dwreg,dm2reg,dwmem,daluc,daluimm,da,db,dimm,drn,dshift,djal,dpc4,clock,resetn,ewreg,em2reg,ewmem,ealuc,ealuimm,ea,eb,eimm,ern0,eshift,ejal,epc4,idadepend,idbdepend,exeadepend,exebdepend,pcsource);//ID级与EXE级之间的寄存器pipeexe exe_stage (ealuc,ealuimm,ea,eb,eimm,eshift,ern0,epc4,//指令执行EXE级ejal,ern,ealu,z,malu,wmo,exeadepend,exebdepend);(五)在id_stage的cu中添加判断冒险的代码,并计算出a_depend和b_depend的值,cu的完整代码如下module pipeidcu(rsrtequ,func,op,wreg,m2reg,wmem,aluc,regrt,aluimm,sext,pcsource,shift,jal,/*数据前推加入的参数*/exe_rd,mem_rd,exe_wreg,mem_wreg,idadepend,idbdepend,rs,rt,rd,exe_m2reg,wpc);input[4:0] exe_rd,mem_rd,rs,rt,rd;input exe_wreg,mem_wreg,exe_m2reg;output[1:0] idadepend,idbdepend;output wpc;//wreg 是否写寄存器//dm2reg为1时将存储器数据写入寄存器,否则将ALU结果写入寄存器//dwmem为1时写存储器,否则不写////daluimm为1时ALUb输入端使用立即数//dshift为1时ALUa输入端使用移位位数//djal为1时执行jal指令,否则不是input rsrtequ;input[5:0] func,op;output wreg,m2reg,wmem,regrt,aluimm,sext,shift,jal;output[4:0] aluc;output[1:0] pcsource;wire i_add,i_sub,i_mul,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_jr;//对指令进行译码wire i_addi,i_muli,i_andi,i_ori,i_xori,i_lw,i_sw,i_beq,i_bne,i_lui,i_j,i_jal;and(i_add,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0],~func[2],~func[1],func[0]);and(i_sub,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0],~func[2],func[1],~func[0]);and(i_mul,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0],~func[2],func[1],func[0]);and(i_and,~op[5],~op[4],~op[3],~op[2],~op[1],op[0],~func[2],~func[1],func[0]);and(i_or,~op[5],~op[4],~op[3],~op[2],~op[1],op[0],~func[2],func[1],~func[0]);and(i_xor,~op[5],~op[4],~op[3],~op[2],~op[1],op[0],func[2],~func[1],~func[0]);and(i_sra,~op[5],~op[4],~op[3],~op[2],op[1],~op[0],~func[2],~func[1],func[0]);and(i_srl,~op[5],~op[4],~op[3],~op[2],op[1],~op[0],~func[2],func[1],~func[0]);and(i_sll,~op[5],~op[4],~op[3],~op[2],op[1],~op[0],~func[2],func[1],func[0]);and(i_jr,~op[5],~op[4],~op[3],~op[2],op[1],~op[0],func[2],~func[1],~func[0]);and(i_addi,~op[5],~op[4],~op[3],op[2],~op[1],op[0]);and(i_muli,~op[5],~op[4],~op[3],op[2],op[1],op[0]);and(i_andi,~op[5],~op[4],op[3],~op[2],~op[1],op[0]);and(i_ori,~op[5],~op[4],op[3],~op[2],op[1],~op[0]);and(i_xori,~op[5],~op[4],op[3],op[2],~op[1],~op[0]);and(i_lw,~op[5],~op[4],op[3],op[2],~op[1],op[0]);and(i_sw,~op[5],~op[4],op[3],op[2],op[1],~op[0]);and(i_beq,~op[5],~op[4],op[3],op[2],op[1],op[0]);and(i_bne,~op[5],op[4],~op[3],~op[2],~op[1],~op[0]);and(i_lui,~op[5],op[4],~op[3],~op[2],~op[1],op[0]);and(i_j,~op[5],op[4],~op[3],~op[2],op[1],~op[0]);and(i_jal,~op[5],op[4],~op[3],~op[2],op[1],op[0]);wire i_rs=i_add|i_sub|i_mul|i_and|i_or|i_xor|i_jr|i_addi|i_muli|i_andi|i_ori|i_xori|i_lw|i_sw|i_beq|i_bne;wire i_rt=i_add|i_sub|i_mul|i_and|i_or|i_xor|i_sra|i_srl|i_sll|i_sw|i_beq|i_bne;////////////////////////////////////////////控制信号的生成/////////////////////////////////////////////////////////assign wreg=(i_add|i_sub|i_mul|i_and|i_or|i_xor|i_sll|//wreg为1时写寄存器堆中某一寄存器,否则不写i_srl|i_sra|i_addi|i_muli|i_andi|i_ori|i_xori|i_lw|i_lui|i_jal)& wpc ;assign regrt=i_addi|i_muli|i_andi|i_ori|i_xori|i_lw|i_lui;//regrt为1时目的寄存器是rt,否则为rdassign jal=i_jal;//为1时执行jal指令,否则不是assign m2reg=i_lw;//为1时将存储器数据写入寄存器,否则将ALU结果写入寄存器assign shift=i_sll|i_srl|i_sra;//为1时ALUa输入端使用移位位数assign aluimm=i_addi|i_muli|i_andi|i_ori|i_xori|i_lw|i_lui|i_sw;//为1时ALUb输入端使用立即数assign sext=i_addi|i_muli|i_lw|i_sw|i_beq|i_bne;//为1时符号拓展,否则零拓展assign aluc[4]=i_sra;//ALU的控制码assign aluc[3]=i_sub|i_or|i_ori|i_xor|i_xori| i_srl|i_sra|i_beq|i_bne;//ALU的控制码assign aluc[2]=i_sll|i_srl|i_sra|i_lui;//ALU的控制码assign aluc[1]=i_and|i_andi|i_or|i_ori|i_xor|i_xori|i_beq|i_bne;//ALU的控制码assign aluc[0]=i_mul|i_muli|i_xor|i_xori|i_sll|i_srl|i_sra|i_beq|i_bne;//ALU的控制码assign wmem=i_sw & wpc ;//为1时写存储器,否则不写//判断rs1是否为寄存器操作数assign rs1IsReg=i_and | i_andi | i_or | i_ori | i_add | i_addi | i_sub | i_lw | i_sw | i_sll | i_srl | i_sra;////判断rs2是否为寄存器操作数assign rs2IsReg=i_and | i_or | i_add | i_sub | i_sll | i_sra | i_srl;//计算exe级和mem级adependassign exe_a_depen=((rs==exe_rd)&(exe_wreg==1)&(rs1IsReg));assign mem_a_depen=((rs==mem_rd)&(mem_wreg==1)&(rs1IsReg));//计算exe级和mem级bdependAssign exe_b_depen=((rt==exe_rd)&(exe_wreg==1)&(rs2IsReg))|((rd==exe_rd)&(exe_wreg==1)&(i_sw));assign mem_b_depen=((rt==mem_rd)&(mem_wreg==1)&(rs2IsReg))|((rd==mem_rd)&(mem_wreg==1)&(i_sw));//计算adepend和bdependassign idadepend[0]= mem_a_depen;assign idadepend[1]=mem_a_depen | exe_a_depen ;assign idbdepend[0]=mem_b_depen | aluimm ;assign idbdepend[1]=mem_b_depen | exe_b_depen;//判断load指令冒险,如果是wpc=0,stall一个时钟周期assign wpc =~(((rs==exe_rd)&exe_m2reg &rs1IsReg )|((rt==exe_rd)&exe_m2reg &rs2IsReg) |((rd==exe_rd )&exe_wreg &i_sw)|((rd==mem_rd)&mem_wreg &i_sw));assign pcsource[1]=i_jr|i_j|i_jal;//选择下一条指令的地址,00选PC+4,01选转移地址,10选寄存器内地址,11选跳转地址assign pcsource[0]=i_beq&rsrtequ|i_bne&~rsrtequ|i_j|i_jal;endmodule(六)接着修改多路选择器,将以前的两路转化成四路module mux4x32(a0,a1,a2,a3,s,y);input[31:0] a0,a1,a2,a3;input[1:0] s;output[31:0] y;assign y=(s==2'b00)a0:(s==2'b01)a1:(s==2'b10)a2:a3;//四选一endmodule八、实验数据及结果分析(一)画出修改后的流水线图;(二)写出增加的多路选择器的选择信号逻辑函数增加的多路选择器信号逻辑函数如下://加上数据前推之后变成四选一的多路器mux4x32 alu_ina (ea,sa,malu,wmo,exe_a_depend,alua);mux4x32 alu_inb (eb,eimm,malu,wmo,exe_b_depend,alub);多路选择器的定义如下:module mux4x32(a0,a1,a2,a3,s,y);input[31:0] a0,a1,a2,a3;input[1:0] s;output[31:0] y;assign y=(s==2'b00)a0:(s==2'b01)a1:(s==2'b10)a2:a3;//四选一endmodule(三)流水线仿真结果,对仿真结果进行必要说明为了验证是否程序正确的完成了forwarding和数据冒险,下面将进行两组测试,并对测试结果进行详细分析解释测试一(非load指令数据冒险测试)首先不管是不是load指令,数据冒险都会用到数据前推,实验提供的代码中测试文件里面的例子就是一个很典型的数据冒险,下面直接用这组例子进行测试,代码如下//测试数据前推assign rom[6'h00]=32'h;//lui r1,0 0assign rom[6'h01]=32'h;//ori r4,r1,80 80assign rom[6'h02]=32'h00202124;//sub r8,r9,r4 fffassign rom[6'h03]=32'h;//addi r5,r0,4 4assign rom[6'h04]=32'h;//store r2,0x0(r4) 80assign rom[6'h05]=32'h;//load r9,0x0(r4) 80可以看到第二条指令和第三条指令关于r4冲突,如果没有解决数据冒险,sub指令时r8会写入0(r9=r4=0),解决数据冒险过后,应该等于-80。