标准文案大全实验报告课程名称:计算机系统结构实验学院:计算机科学与工程学院专业:计算机科学与技术指导教师:好老师学生姓名:爱学习的大哥哥2014666666666实验成绩:日期:2017年5月26日1/9电子科技大学计算机学院实验中心电子科技大学实验报告一、实验项目名称:解决控制冒险二、实验室名称:主楼A2-412实验时间:2017年5月26日三、实验目的在给出的流水线代码基础上,增加ID级关闭写使能信号,以解决不正确分支指令的影响。通过完成这次实验,加深对控制冒险现象的产生和消除控制冒险的原理的理解,提高编程和测试的能力。四、实验原理(一)转移相关问题转移指令改变程序顺序执行的特性。由于是流水线操作,在转移发生之前,若干条转移指令的后续指令已被取到流水线处理机中。这就是所谓的转移相关问题(branchhazard),有时也称之为控制相关问题(controlhazard)。回顾我们前面介绍的处理转移相关问题的4种技术:以上任何一种方法都会使硬件固定,编译时会根据硬件机制和转移行为对代码进行调度,以获取最佳性能。(二)消除无条件转移指令的后一条指令影响每条指令在ID时判断在当前在EXE阶段的操作码暂存器的值是否是无条件转移指令:如果是,那么不使能当前在ID阶段的那条指令的WZ、WMEM和WREG的信号,这样这条2/9指令的执行就对程序的逻辑没有影响。(三)条件转移指令条件转移指令的实现思想与无条件转移指令有所类似,但不完全相同。首先对于条件转移指令本身来说,需要判断Z标志是否能用。若Z标志还没有准备好,则要暂停流水线一个时钟周期。这一点和判断数据相关极为相似。但由于转移指令只可能改变PC而不改变其它状态,因此用不着封锁WZ,WMEM,WREG(对转移指令来讲,这些信号原本就为0)。因为如果处在译码级的是条件转移指令,而且处在EXE级的是ALU类型的指令(就要写Z标志到流水线寄存器Z了),则要等到ALU指令写完Z后,再判断转移与否,为此要暂停一个周期(或者如前所述,插入一条nop指令)。对于条件转移指令的下一条指令的处理办法与无条件指令不同。因为条件转移的下一条指令有可能执行也有可能不执行,需要在对无条件转移指令的处理策略上进行扩展:条件转移的下一条指令在ID时判断在当前在EXE阶段的操作码暂存器的值是否是条件转移指令并且判断是否转移成功(Z的值没变),如果发现成功,那么不使能当前在ID阶段的那条指令的WZ、WMEM和WREG的信号,这条指令的执行就对程序的逻辑没有影响(与无条件处理方式相同);如果发现转移不成功,说明本条指令为有效指令,使能当前在ID阶段的那条指令的WZ、WMEM和WREG的信号,本条指令正常执行。五、实验内容在给出的流水线代码基础上,增加ID级关闭写使能信号,以解决不正确分支指令的影响。六、实验器材(设备、元器件)ISEDesignSuite14.7集成开发环境,编程语言:VerilogHDL硬件描述语言七、实验步骤1、新建项目,将上个实验完成的解决数据冒险与数据前推的代码拷贝进来2、在直接跳转中,需要废除跳转指令的下一条(当译码出跳转指令时,下一条已经流3/9出,所以要废除掉);而在条件跳转中,需要根据z的值来判断是否废除下一条指令。在代码中译码级,pcsource定义如下assignpcsource[1]=i_jr|i_j|i_jal;//选择下一条指令的地址,00选PC+4,01选转移地址,10选寄存器内地址,11选跳转地址assignpcsource[0]=i_beq&rsrtequ|i_bne&~rsrtequ|i_j|i_jal;LOADDEPEN,BTAKEN,ID_branch);如果是直接跳转,那么一定废除,pcsource=11,如果是条件跳转,废除的条件就是pcsource=01,暂不考虑jr指令,那么要废除下一条指令的条件就是pcsource=00;3、在顶层模块添加变量wirewz;//决定是否写z值wire[1:0]exepcsource;//exepcsource主要用在条件跳转wz需要在id级计算出来,然后传递到exe级,如果废除指令那么wz=0;exepcsource与之相反,从exe级传递到id级,用来指示下一条指令是否废除。4、增加这两个变量后,顶层模块id级与exe级的代码如下pipeidid_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,exepcsource,wz);pipeexeexe_stage(wz,ealuc,ealuimm,ea,eb,eimm,eshift,ern0,epc4,//指令执行EXEejal,ern,ealu,z,malu,wmo,exeadepend,exebdepend);5、加入exepcsource后,根据步骤2的分析,如果pcsource!=00,就废除掉下一条指令,即wreg、wmem、wz全部置0,这里需要注意的是,wz的值有多种表示方法,由于wz只在控制冒险中使用,并且在控制冒险中wreg=wmem=wz,所以这里可以直接将wreg的值赋给wz,也可以wz=exepcsource[0](pcsource[0]=i_beq&rsrtequ|i_bne&~rsrtequ|i_j|i_jal,在条件跳转中pcsource[0]=i_beq&rsrtequ|i_bne)assignwreg=(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&(exepcsource[0]==0)&(exepcsource[1]==0);assignwmem=i_sw&wpc&(exepcsource[0]==0)&(exepcsource[1]==0);//为1时写存储器,否则不写assignwz=wregid级cu模块完整代码如下:modulepipeidcu(rsrtequ,func,op,wreg,m2reg,wmem,aluc,regrt,aluimm,sext,pcsource,shift,jal,4/9/*数据前推加入的参数*/exe_rd,mem_rd,exe_wreg,mem_wreg,idadepend,idbdepend,rs,rt,rd,exe_m2reg,wpc,exepcsource,wz);input[1:0]exepcsource;input[4:0]exe_rd,mem_rd,rs,rt,rd;inputexe_wreg,mem_wreg,exe_m2reg;output[1:0]idadepend,idbdepend;outputwpc;//wreg是否写寄存器//dm2reg为1时将存储器数据写入寄存器,否则将ALU结果写入寄存器//dwmem为1时写存储器,否则不写////daluimm为1时ALUb输入端使用立即数//dshift为1时ALUa输入端使用移位位数//djal为1时执行jal指令,否则不是inputrsrtequ;input[5:0]func,op;outputwz,wreg,m2reg,wmem,regrt,aluimm,sext,shift,jal;output[4:0]aluc;output[1:0]pcsource;wirei_add,i_sub,i_mul,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_jr;//对指令进行译码wirei_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]);5/9and(i_jal,~op[5],op[4],~op[3],~op[2],op[1],op[0]);wirei_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;wirei_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;//////////////////////////////