计算机结构与组成课程实习报告_第1页
计算机结构与组成课程实习报告_第2页
计算机结构与组成课程实习报告_第3页
计算机结构与组成课程实习报告_第4页
计算机结构与组成课程实习报告_第5页
已阅读5页,还剩23页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

中国地质大学(武汉) 课题:CPU仿真设计姓名:学院:信息工程课程:计算机结构与组成课程设计班序号:Project1一.问题描述:这个工程需要编写MIPS汇编语言一个子集的指令解释器.它将实现取指、反汇编,解码,并执行MIPS机器指令。也就是构建一个缩微的MARS。二.问题分析:老师已经给出了一个工程,要求我们在所给文件中添加相应的代码,使sample.dump中的机器码(也就是一串数字)可以实现反汇编,在控制台黑屏中输出汇编指令和寄存器及内存的更新情况。而且.cpp文件中提供了两个函数disassembled和simulateInstr来分别实现上述功能。反汇编说明:在disassembled函数中,我要将数字指令转化为汇编语言,这首先需要对一段数字进行分割,如先取32位数字的前6位为其opcode段等,数字分割是通过左移和右移实现的,具体代码如下:intopcode,func,rs,rt,rd,shamt,targaddress,immediate; opcode=instr>>26; rs=(instr<<6)>>27; rt=(instr<<11)>>27; rd=(instr<<16)>>27; shamt=(instr<<21)>>27; func=(instr<<26)>>26; immediate=(instr<<16)>>16; targaddress=(instr<<6)>>6; 完成数字分割后,就进入具体的指令分析阶段,此步通过if-else语句实现。如先解析R格式语句,先选出opcode为0的32为指令数字段,再针对具体的func的值为其对上不同的汇编指令,例如opcode=0,func=33表示addu指令:if(opcode==0) {if(func==33)//addu { strcat_s(result1,"addu $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); }运用strcat函数实现字符串的拼接,itoa_s函数将二进制数变为其他进制数输出,结果便可在黑频上输出如下类似指令:addu $0,$2,$2将所有情况的不同opcode和func的值用if-else语句像上面这样表示出来,于是就可以将所有的32位指令数字段解码成汇编代码,但此时的代码只是个空壳而已,需要用下面的simulateInstr函数将不同的指令的pc改变,计算,寄存器和内存的更新表示出来。在simulateInstr函数中同样也需要对每个32位指令数字段进行划分然后依据不同的opcode和func设置pc,进行计算以及表示寄存器和内存是否被更新。在这里,寄存器及内存的是否更新使用数字表示,-1代表没有更新,例如addu:if(opcode==0) { if(func==33)//addu { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rt]+mips->registers[rs]; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; }其中pc会顺序加4,内存没有改变,但addu所加的结果被存在rd寄存器中,所以rd寄存器会更新。将所有指令的实质改变按此方法用if-else语句表示出来后,该工程也就完成了。三.所遇问题及改进方案:(1)在编程过程中,我开始不知道该怎么样实现数据的符号扩展,因为我对32位数据采用的是左移右移方法来实现指令分割的,这就相对于对所有字段都进行的是零扩展,这对于addi,lw,sw指令中需要进行符号扩展的立即数来说显然矛盾。后来,在请教同学的基础上,我改进了方法,对于那些只需做零扩展的立即数,不需要做什么改变。对与addi这类需做符号扩展的立即数,我在相应的if语句中对立即数进行判断,如果立即数小于32768(也就是2的15次方),也就是该立即数的第一位数是0,那么零扩展与符号扩展对该立即数的真实值无影响,也就不需改变什么;反之,则该立即数的第一位数是1,那么必须进行符号扩展,即将该立即数减去65536(2的16次方)即可。例如sw:if(opcode==43)//sw { strcat_s(result1,"sw $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,","); if(immediate<32768) _itoa_s(immediate,temp,10); else _itoa_s(immediate-65536,temp,10); strcat_s(result,temp); strcat_s(result,"($"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,")"); }(2)在simulateInstr函数中对于sw与lw指令,需要对内存中的值进行读取,开始时我只用rs中的地址和立即数相加得到要读或取的内存地址,但这样得不到正确的结果,在同学的提醒下我注意到该程序设计的内存首地址为0x00400000,于是将上面的数减去0x00400000即可得正确结果。四.以下为源程序代码:charresult[100]={0};charresult1[100]={0};chartemp[100]={0};char*disassembled(unsignedintinstr,unsignedintpc){ memset(result,0,100); memset(result1,0,100); memset(temp,0,100); intopcode,func,rs,rt,rd,shamt,targaddress,immediate; opcode=instr>>26; rs=(instr<<6)>>27; rt=(instr<<11)>>27; rd=(instr<<16)>>27; shamt=(instr<<21)>>27; func=(instr<<26)>>26; immediate=(instr<<16)>>16; targaddress=(instr<<6)>>6; if(opcode==0) { if(func==35)//subu { strcat_s(result1,"subu$"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); } if(func==33)//addu { strcat_s(result1,"addu $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); } if(func==36)//and { strcat_s(result1,"and $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); } if(func==37)//or { strcat_s(result1,"or $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); } if(func==42)//slt { strcat_s(result1,"slt $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); } if(func==0)//sll { strcat_s(result1,"sll $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,","); _itoa_s(shamt,temp,10); strcat_s(result,temp); } if(func==2)//srl { strcat_s(result1,"srl $"); strcat_s(result,result1); _itoa_s(rd,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,","); _itoa_s(shamt,temp,10); strcat_s(result,temp); } if(func==8)//jr { strcat_s(result1,"jr $"); strcat_s(result,result1); _itoa_s(rs,temp,10); strcat_s(result,temp); } } if(opcode==9)//addiu { strcat_s(result1,"addiu $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,","); if(immediate<32768) _itoa_s(immediate,temp,10); else _itoa_s(immediate-65536,temp,10); strcat_s(result,temp); } if(opcode==12)//andi { strcat_s(result1,"andi $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",0x"); _itoa_s(immediate,temp,16); strcat_s(result,temp); } if(opcode==13)//ori { strcat_s(result1,"ori $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",0x"); _itoa_s(immediate,temp,16); strcat_s(result,temp); } if(opcode==15)//lui { strcat_s(result1,"lui $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",0x"); _itoa_s(immediate,temp,16); strcat_s(result,temp); } if(opcode==4)//beq { strcat_s(result1,"beq $"); strcat_s(result,result1); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",0x"); if(immediate>=32768) immediate-=65536; pc=pc+4+immediate*4; _itoa_s(pc,temp,16); strcat_s(result,temp); } if(opcode==5)//bne { strcat_s(result1,"bne $"); strcat_s(result,result1); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,",$"); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,",0x"); if(immediate>=32768) immediate-=65536; pc=pc+4+immediate*4; _itoa_s(pc,temp,16); strcat_s(result,temp); } if(opcode==35)//lw { strcat_s(result1,"lw $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,","); if(immediate<32768) _itoa_s(immediate,temp,10); else _itoa_s(immediate-65536,temp,10); strcat_s(result,temp); strcat_s(result,"($"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,")"); } if(opcode==43)//sw { strcat_s(result1,"sw $"); strcat_s(result,result1); _itoa_s(rt,temp,10); strcat_s(result,temp); strcat_s(result,","); if(immediate<32768) _itoa_s(immediate,temp,10); else _itoa_s(immediate-65536,temp,10); strcat_s(result,temp); strcat_s(result,"($"); _itoa_s(rs,temp,10); strcat_s(result,temp); strcat_s(result,")"); } if(opcode==2)//j { pc=(((pc+4)>>28)<<28)+((targaddress<<6)>>4); strcat_s(result1,"j 0x"); strcat_s(result,result1); _itoa_s(pc,temp,16); strcat_s(result,temp); } if(opcode==3)//jal { pc=(((pc+4)>>28)<<28)+((targaddress<<6)>>4); strcat_s(result1,"jal 0x"); strcat_s(result,result1); _itoa_s(pc,temp,16); strcat_s(result,temp); } returnresult;voidsimulateInstr(Computermips,unsignedintinstr,int*changedReg,int*changedMem){ /*Youreplacethiscodebytherightstuff.*/ intopcode,func,rs,rt,rd,shamt,targaddress,immediate; opcode=instr>>26; rs=(instr<<6)>>27; rt=(instr<<11)>>27; rd=(instr<<16)>>27; shamt=(instr<<21)>>27; func=(instr<<26)>>26; immediate=(instr<<16)>>16; targaddress=(instr<<6)>>6; if(opcode==0) { if(func==33)//addu { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rt]+mips->registers[rs]; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==35)//subu { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rs]+mips->registers[rt]; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==36)//and { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rs]&mips->registers[rt]; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==37)//or { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rs]|mips->registers[rt]; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==42)//slt { mips->pc=mips->pc+4; if(mips->registers[rs]<mips->registers[rt]) mips->registers[rd]=1; else mips->registers[rd]=0; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==0)//sll { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rt]<<shamt; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==2)//srl { mips->pc=mips->pc+4; mips->registers[rd]=mips->registers[rt]>>shamt; if(rd==0) rd=-1; *changedReg=rd; *changedMem=-1; } if(func==8)//jr { mips->pc=mips->registers[rs]; *changedReg=-1; *changedMem=-1; } }if(opcode==9)//addiu { if(immediate>=32768) immediate-=65536; mips->pc=mips->pc+4; mips->registers[rt]=mips->registers[rs]+immediate; if(rt==0) rt=-1; *changedReg=rt; *changedMem=-1; }if(opcode==12)//andi { mips->pc=mips->pc+4; mips->registers[rt]=mips->registers[rs]&immediate; if(rt==0) rt=-1; *changedReg=rt; *changedMem=-1; }if(opcode==13)//ori { mips->pc=mips->pc+4; mips->registers[rt]=mips->registers[rs]|immediate; if(rt==0) rt=-1; *changedReg=rt; *changedMem=-1; } if(opcode==15)//lui {mips->pc=mips->pc+4; mips->registers[rt]=immediate*65536; if(rt==0) rt=-1; *changedReg=rt; *changedMem=-1; }if(opcode==4)//beq {if(immediate>=32768) immediate-=65536; if(mips->registers[rs]==mips->registers[rt]) mips->pc=mips->pc+4+(immediate<<2); else mips->pc=mips->pc+4; *changedReg=-1; *changedMem=-1; } if(opcode==5)//bne { if(immediate>=32768) immediate-=65536; if(mips->registers[rs]!=mips->registers[rt]) mips->pc=mips->pc+4+(immediate<<2); else mips->pc=mips->pc+4; *changedReg=-1; *changedMem=-1; } if(opcode==35)//lw { if(immediate>=32768) immediate-=65536; mips->pc=mips->pc+4; mips->registers[rt]=mips->memory[(mips->registers[rs]-0x00400000+immediate)/4]; if(rt==0) rt=-1; *changedReg=rt; *changedMem=-1; } if(opcode==43)//sw { if(immediate>=32768) immediate-=65536; mips->pc=mips->pc+4; mips->memory[(mips->registers[rs]-0x00400000+immediate)/4]=mips->registers[rt]; *changedReg=-1; *changedMem=mips->registers[rs]+immediate; } if(opcode==2)//j { mips->pc=(((mips->pc+4)>>28)<<28)+((targaddress<<6)>>4); *changedReg=-1; *changedMem=-1; } if(opcode==3)//jal { mips->registers[31]=mips->pc+4; mips->pc=(((mips->pc+4)>>28)<<28)+((targaddress<<6)>>4); *changedReg=31; *changedMem=-1;} }Project3一.各个部件及原理:选择赋值:给定初值,经过2位选择器选定一个输出端口将初值赋值给它,如图,2位选择器为00代表第一条线路可通。4路选择器左边有四个输入口,从4条线路中选择一条作为通路,然后可以通过一个或运算将选择的数输出,如图中2位选择器为00代表第一条线路可通,将左边输入的第一个数选择出来作为输出。Registerfile:寄存器文件中,最左边的输入段是用来给寄存器赋值的(即写回操作),选择赋值则选择出要逻辑右移(附图1)输入一个16位的数,有右移0到15位共16种移法,对每一种移法,先用一个16位的分位器将每一个数字分开,再用一个相应的16位分位器接收,比如右移一位,就将左边分位器上的高15位放在右边分位器的低15位上,并将剩下的一位赋值为0,每一种移法都采用这种方法,将这16种移法用一个选择器进行选择,为选择器提供选择信号的输入为rt寄存器中的值(正数),但寄存器的值很可能大于4位数(即15),所以对其进行选择,将其高12位数拿出来进行检验,如果不为0,证明右移数大于15,则移完后必为0,所以此时输出0,如果为0,则将其低4位拿出来对刚才的16种移法进行选择,输出选择出的值。逻辑左移(附图2)与逻辑右移原理相同,输入一个16位的数,有左移0到15位共16种移法,对每一种移法,先用一个16位的分位器将每一个数字分开,再用一个相应的16位分位器接收,比如左移一位,就将左边分位器上的低15位放在右边分位器的高15位上,并将剩下的一位赋值为0,每一种移法都采用这种方法,将这16种移法用一个选择器进行选择,为选择器提供选择信号的输入为rt寄存器中的值(正数),但寄存器的值很可能大于4位数(即15),所以对其进行选择,将其高12位数拿出来进行检验,如果不为0,证明左移数大于15,则移完后必为0,所以此时输出0,如果为0,则将其低4位拿出来对刚才的16种移法进行选择,输出选择出的值。算术右移(附图3)与逻辑右移原理大致相同,只是右边分位器空下之处每一分支赋值为左边分支的最高位即可。Lui:将输入值用16位分位器分开,取其低8位,将这8位为右边的另一16位分位器的高8位赋值,将其低8位赋值为0再输出即可。Slt:将输入的rs寄存器中的值与rt相减,再将结果经过16位的分位器,取其最高位,若最高位为1,证明rs小于rt,于是将1作为输出给rd,反之则输出0.Beq:将输入的rs寄存器中的值与rt相减,再将结果经过16位的分位器,用或门检验结果是否为0,为0则将Zero设为1输出,反之则设为0.Bne:将输入的rs寄存器中的值与rt相减,再将结果经过16位的分位器,用或门检验结果是否为0,为0则将Zero设为0输出,反之则设为1ALU:输入端为rs与rt,将rs与rt分别进行图中的11种运算,将前9种运算通过一个选择器,选择其中的一个结果作为输出,选择输入接口为ALUctr,对于beq和bne则将两个输出的Zero值做一个或门,将两个Zero合并成一个Zero接口输出.扩展器:将一个8位输入的数分两路用两个8位分位器分开,分别将这8位赋值给两个16位分位器的低8位,上边的16位分位器剩下的8位高位均被赋值为0,即实现0扩展,下边的16位分位器剩下的8位用其左边8位分位器的最高位进行赋值,即实现符号扩展。再将两者的值用一个或门连接起来,用一个2路选择器进行0扩展或符号扩展的选择输出即可。指令分割:将一个16位输入的数分别用三个16位分位器分开,代表三种格式,在每种格式上分别划分出各自区段输出,如图所示。数据内存:此图完全参照老师所给的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论