《3774.计算机组成原理课程设计报告.doc》由会员分享,可在线阅读,更多相关《3774.计算机组成原理课程设计报告.doc(33页珍藏版)》请在三一办公上搜索。
1、计算机组成原理课程设计报告专业名称: 计算机科学与技术班级学号: 计算机0802学生姓名: 指导教师:设计时间: 2010年 06 月 28 日2010年 07 月 01 日2010年 07 月第一天 取操作数微程序的设计和调试一、设计目标 设计并调试取操作数的微程序二、取操作数微流程三、测试程序、数据及运行结果格式如下:1、测试内容:立即数寻址、直接寻址、间接寻址、相对寻址、寄存器寻址立即寻址测试指令(或程序):MOV #1234H,R1 机器码: 内存地址(H)机器码(H)汇编指令00000761 1234MOV #1234H,R1运行结果及分析:为了分析微程序是否正确,首先通过查看微指令
2、流程判断BM和NC是设置是否正确,如果执行的微指令依次是:00100200300400B00F016006018007。(后面的MOV指令的EXE微指令是由老师提供的),根据前面指令微流程的设计,所执行的微指令次序是正确的。在上图中,测试指令微程序最后一条微指令的地址为046,微指令是88000000,所代表的微操作应该是TRoe,GRSce。执行后CRS=0000,好像出错了。但是我们看到在下一条微指令时GRS=1234,赵老师在上实验课的时候曾经讲过这个问题,这是因为GRS的装入使能信号GRSce受时钟信号的影响,内容在微指令周期结束时才被保存,所以观察到的数据慢了一步。直接寻址测试指令(
3、或程序):MOV 0014H,R1机器码: 内存地址(H)机器码(H)汇编指令00000761 1234MOV 0014H,R1运行结果及分析:为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确,如果执行的微指令依次是:00100200300400B00F014015016006018007。根据前面指令微流程的设计,所执行的微指令次序是正确的。间接寻址测试指令(或程序):MOV( 0014),R1机器码: 内存地址(H)机器码(H)汇编指令00000721 1234MOV (0014),R1运行结果及分析:为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是
4、设置是否正确,如果执行的微指令依次是:00100200300400B00F0120013014015016006018007。根据前面指令微流程的设计,所执行的微指令次序是正确的。测试指令(或程序):MOV disp(0014),R1机器码: 内存地址(H)机器码(H)汇编指令00000701 1234MOV +disp,R1运行结果及分析:为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确,如果执行的微指令依次是:00100200300400B00F010011017015016006018007。根据前面指令微流程的设计,所执行的微指令次序是正确的。由于时间关系,今
5、天只验证了5种寻址方式。后面两种寻址方式的指令和编码如下所示:寄存器间接寻址MOV #1234H,(R1) 指令编码为0769 1234寄存器变址寻址MOV #1234H,disp(R1) 指令编码为0771 1234四、设计中遇到的问题及解决办法遇到的问题:1. 搞不清楚取操作数入口的微程序是由什么组成。2. 对软件UniDebugger的操作不太熟悉。3. 以为只需要将取源操作数的微程序输入到micro中就行了。解决的办法:1:一时搞不清楚去源操作数的入口的微程序究竟是要填什么,便不和它纠缠,往下看的时候,看到图中的都填满了微命令,便知道了,原来取操作数的入口的微命令是空的(NOP)。2:
6、认真地回忆了做实验的时候的上机步骤后,对该软件的基本操作基本熟悉,然后按照课程设计指导书上的要求便能更好地运用该软件。3:MOV指令为双操作数指令。原本以为该指令虽然是双操作数指令,但应该只涉及到取源操作数,至于目的操作数,该指令应该只是将源操作数输送到目的地址中,取不取目的操作数不影响问题的。但是很快,我就意识到这个认识是错误的了。因为在我执行该MOV指令的时候,程序竟然运行到0018处。这个微指令地址应该出现在取目的操作数阶段,但是我却没有将取目的操作数的微指令编码输入micro中,导致程序运行到该行后输出地微指令编码是00000000。当然运行结果肯定是错误的。于是我毫不犹豫地将取目的操
7、作数的微指令编码全都输入到micro中,然后再次运行MOV指令,这一次运行结果就正确了。第二天 运算指令的微程序设计与调试一、设计目标 设计并调试运算指令的微指令二、运算指令微程序入口地址指令助记符指 令 编 码入口地址(H)FEDCBA9876543210MOVsrc, dst000001源地址码目的地址码044ADDsrc, dst000010源地址码目的地址码048ADDCsrc, dst000011源地址码目的地址码04cSUB src, dst000100源地址码目的地址码050SUBBsrc, dst000101源地址码目的地址码054CMPsrc, dst000110源地址码目的
8、地址码058ANDsrc, dst000111源地址码目的地址码05cOR src, dst001000源地址码目的地址码060XOR src, dst001001源地址码目的地址码064TESTsrc, dst001010源地址码目的地址码068INC dst00000010001目的地址码0A4DEC dst00000010010目的地址码0A8NOT dst00000010011目的地址码0AC三、运算类指令微程序(参照指导书图26的形式)ADDC:04C98B0 006FTRoe,ADDC,SV,PSWce0:NA-uAR06FSUB: 05098F0 006FTRoe,SUB,SV,
9、PSWce0:NA-uAR06FSUBB: 0549930 006FTRoe,SUBB,SV,PSWce0:NA-uAR06FCMP: 05898C0 006FTRoe,SUB,PSWce0:NA-uAR000AND: 05C9970 006FTRoe,AND,SV,PSWce0:NA-uAR06FOR: 060 99B0 006FTRoe,OR,SV,PSWce0:NA-uAR06FXOR: 0649A30 006FTRoe,XOR,SV,PSWce0:NA-uAR06FDEC: 0A81AB0 006FTRoe,DEC,SV,PSWce0:NA-uAR06FNOT: 0AC19F0 006
10、FTRoe,NOT,SV,PSWce0:NA-uAR06F四、测试程序、数据及运行结果1、测试内容:1:将数据移动到寄存器中;2:将存储数据单元的内容加1;3:将寄存器中的数据和地址单元里的数据进行比较;4:将寄存器做为变址寄存器,将其与1111进行逻辑与运算运行数据:0760 0000MOV #0000H,R1;077A 1101MOV #1101,0010;023A 0011INC (0011);1B2A 0015CMP (0015),(R1);1F71 1111AND #1111,DISP(R1);运行结果:对于MOV指令而言,在第一天的课程设计的时候已经得到了验证,结果是正确的,这里就
11、不在重复了。加一指令INC,为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确,如果执行的微指令依次是:00100200300600B00F02200230240250260070A406F071072000。根据前面指令微流程的设计,所执行的微指令次序是正确的,而且,通过ALU运算后,输出结果加1,说明运算是正确的。对于CMP指令的执行出现了问题,没将图片拷下来。为了验证指令的正确性,我重新编写了MOV指令,并用了比较简单的寻址方式,以便快速查处问题所在。之后就是所遇到的问题。五、设计中遇到的问题及解决办法对于CMP指令的执行出现了问题,没将出问题的图片拷下来。但为了
12、验证指令的正确性,我重新编写了MOV指令,并用了比较简单的寻址方式。1B7A FFFD 0008MOV #FFFD,0008H并对RAM中的0008单元做了设置,将其中的内容改成了FFFD,根据CMP指令的工作原理,比较两个相同的数据的时候(两个数据都是FFFD),输出地PSW的标志位中的ZF应该为1,其他结果应该是0的。但是运行的结果与想象中的有很大差别。运行结果如下:仔细看图片中的数据:00100200300600B00F01600601B01F024025026007058000 指令的运行顺序没出现问题。但是结果出现了问题。SZOC为8,说明标志位SF为1,结果竟然是负的。再看看ALU
13、中的运行结果,竟然不是0000,而是FFFD,由此可知,并不是我的CMP指令出现了错误,而是ALU运算器出现了一点小小的错误(SUB指令的编写出了点问题)。第三天 CPU硬件的初级设计与验证一、设计目标 在运算器实验的基础上对硬件进行扩充,建立初级CPU的数据通路,构造一个只支持运算指令的初级CPU。二、硬件设计1、PC模块设计(加上适当注释) /*程序计数器PC与R模块一样采用异步复位,当n_reset有效时,PC清0,否则在时钟信号clk的上升沿如果数据装入使能ce有效则dq,如果自加信号PCinc有效则q+1q。PC通过三态门与IB相连。*/timescale 1ns / 1psmodu
14、le PC(d,q,n_reset,clk,ce,PCinc); input 15:0 d; input n_reset,clk,ce; input PCinc;output 15:0 q;reg 15:0 data;always (posedge clk or negedge n_reset)beginif(!n_reset)/当n_reset有效时,PC清0data = 0;else if(ce)/ce有效则dqdata = d;else if( PCinc )/PCinc有效则q+1qdata = data+1;endassign q = data;endmodule2、IR模块设计ti
15、mescale 1ns / 1ps/* DR连接内部总线IB和系统总线的DB;DR有两路数据输入data_IB、data_DB,分别来自IB、DB,相应的有两个装入使能信号DRce_IB、DRce_DB,输出端q分别通过两个三态门连到IB、DB。DR采用异步复位,复位时DR清0,否则在时钟信号的上升沿,当DRce_IB有效时则data_IBq,当DRce_DB有效时则data_DBq。*/module DR #(parameter DATAWIDTH=16)(input wire DATAWIDTH-1:0 data_IB, input wire DATAWIDTH-1:0 data_DB,
16、input wire clk, input wire DRce_IB, input wire DRce_DB, input n_reset, output reg DATAWIDTH-1:0 q);always(posedge clk or negedge n_reset) begin if(!n_reset)/ DR采用异步复位,复位时DR清0 q = 0; else if(DRce_IB)/DRce_IB有效时则data_IBq q = data_IB; else if(DRce_DB)/DRce_DB有效时则data_DBq q = data_DB;endendmodule3、顶层模块设
17、计(自己增加的设计部分)/TR寄存器的实例化R #(DATAWIDTH) TR(.q(TR_out), .d(IB), .clk(clock), .ce(TRce), .n_reset(n_reset);/AR寄存器的实例化R #(DATAWIDTH) AR(.q(AR_out), .d(IB), .clk(clock), .ce(ARce), .n_reset(n_reset);/IR寄存器的实例化R #(DATAWIDTH) IR(.q(IR_out), .d(IB), .clk(clock), .ce(IRce), .n_reset(n_reset);三、验证0762 0014 MOV
18、#0000H,R1;023A 0014 INC 0014H;1B2A 0015CMP (0015),(R2);0762 0001 MOV #0001,R2;1F72 1010 AND #1010,DISP(R2);运行结果:结果分析:为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确,如果执行的微指令依次是:00100200300400B00F016006018007044046000根据前面指令微流程的设计,所执行的微指令次序是正确的,而且GRS里的数据内容为:0014,所以执行的结果是正确的。INC指令的执行的微指令依次是:00100200300601B01F024
19、0250260070A406F071072000根据前面指令过程微流程的设计,所执行的微指令次序是正确的。INC指令执行后,ALU中内容是FFFD(原来0014单元内容为FFFC),所以执行结果是正确的。CMP指令:为了分析微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确。执行的微指令依次是:00100200300400B00F012013014015016006019025026007058000根据执行结果看:ALU中运行结果是0000,而且标志位为。说明结果为,且没有借位。执行结果正确。MOV+AND指令指令的执行是没问题的。为了分析微程序是否正确,首先通过查看微指令流
20、程判断BM和NC是设置是否正确。执行的微指令依次是:00100200300400B00F01600601A01C01D01E02702502600705C06F071072000根据执行结果看:ALU中运行结果是0000,而且标志位为。说明结果为,且没有借位。执行结果正确。四、设计中遇到的问题及解决办法问题:INC指令在结果执行过程中仔细看程序执行的过程可知:INC指令应该在取完目的操作数之后(026)就转到EXE执行007,但是程序中却是直接返回取指令入口。这个问题应该出在微指令设计的正确性上,果然,查看micro中的微指令(026)单元,竟然是00000000,问题出现在这里。但是这个确实
21、很奇怪,在第二天的时候我已经将所有微指令都保存好了,但现在下载的微指令却和第二天的微指令不一样,很可能是软件设计上的缺陷吧。将正确的微指令输入后,问题也就解决了。同样的问题出现在AND指令上。一下就是AND指令运行的结果。从程序运行的流程上看:正确的AND指令应该在执行完01A后执行的01C的。但是这里却出现了错误。经检查,同样的问题出现了,micro了的微指令已经和第二天设计的微指令不一样了,由此可见该软件还存在一些缺陷。第四天 为CPU扩充转移指令一、设计要求 在初级CPU的基础上进行功能扩充,使其支持转移类指令二、硬件uAG模块设计(自己修改的设计部分,加上适当注释)3d3: uAGou
22、t=NA8:1,BM3_uAR0;case(IR7:6)/ 条件转移类指令 * 2b00: Flag_MUX=1b0; 2b01:Flag_MUX=1b0; / 添加第四天的代码,参照指导书图210 2b10: Flag_MUX=1b0; / 根据标志位正确生成BM3_uAR0 2b11: Flag_MUX=1b0; default:Flag_MUX=1b0; endcase三、转移指令微程序的设计四、测试程序、数据及运行结果1、测试内容(1):通过比较指令,将PSW标志位设置为5,然后测试转移指令是否能正确执行。运行数据:(0010单元设置为1111,如下图)1B7A 1111 0010CM
23、P #1111,0010;019A 000BJZ 000B;运行结果及分析:为了分析CMP+JZ微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,CMP执行的微指令依次是:00100200300400B00F01600601B01F024025026007058000根据执行结果看:ALU中运行结果是0000,而且标志位为。说明结果为,且没有借位。执行结果正确。接下来验证JZ指令执行是否正确:00100200300601B01F024025026007075077000,程序正常跳转,执行结果正确。测试内容(2):通过比较指令,将PSW标志位设置为9,然后测试转移指令是
24、否能正确执行。运行数据:(0010单元设置为FFEF,如下图)1B7A 1111 0010CMP #1111,0010;019A 000BJZ 000B;运行结果及分析:为了分析CMP+JZ微程序是否正确,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,CMP执行的微指令依次是:00100200300400B00F01600601B01F024025026007058000根据执行结果看:ALU中运行结果是EEDE,而且标志位为9。说明结果为负,且有借位。执行结果正确。接下来验证JZ指令执行是否正确:00100200300601B01F024025026007075076000,程序
25、正常跳转,执行结果正确。五、设计中遇到的问题及解决办法出现的问题:在程序编写完成后,开始验证。但是指令运行顺序出现了问题。如图所示:(程序没有跳转到075的位置)微指令运行的顺序出现了问题,首先考虑微指令编码有没有出现错误。经仔细检测,指令编码没有出现问题。接下来很可能是程序出现了问题。果然,在转移指令的入口的地方,原本要设置为075H,但是我在编写代码的时候写成了 4b0011 IR7:5 1b01;这样子虽然能运行程序,但是却将程序复杂化,本来只需要一个模式来执行转移程序的,现在却必须为8个转移指令准备8个转移条件。为了使程序运行,将代码改成 h075 后,程序只需要一个入口来为8个转移指
26、令服务。第五天 为CPU扩充移位指令一、设计目标 在前面CPU的就出上扩充硬件,使其支持移位指令。二、硬件设计1、SHIFTER模块设计(加上适当注释)mux mux_lsb(.addr(IR76),.q(data_lsb),.d1(1b0),.d2(1b0),.d3(dDATAWIDTH-1),.d4(CF);mux mux_hsb(.addr(IR76),.q(data_hsb),.d1(dDATAWIDTH-1),.d2(1b0),.d3(d0),.d4(CF);2、CF模块设计timescale 1ns / 1psmodule CF_MUX(d15, d0, Cout, q, SL,
27、SR);input d15, d0, Cout;input SL, SR;output q;reg q;always (*)begincase (SL, SR)3b01: q = d0;3b10: q = d15;default:q = Cout;endcaseendendmodule3、IR_DECODE模块设计(自己增加修改的设计部分) 2b00: BM4_uA= 5b01001,IR7:5,1b0;4、顶层模块设计(增加自己修改的设计部分)wire CF;CF_MUX CFM(.d15(ALU_outDATAWIDTH-1),.d0(ALU_out0),.Cout(Cout),.q(CF
28、),.SL(SL),.SR(SR);三、移位指令微程序的设计微地址(H)微指令(H)微指令字段(H)微命令F0F1F2F3F4F5F6F7F8F9092SAR06010000006F1810 006F094SHL06020000006F1820 006F096SHR06010000006F1810 006F098ROL06020000006F1820 006F09AROR06010000006F1810 006F09CRCL06020000006F1820 006F09ERCR06010000006F1810 006F四、测试程序、数据及运行结果1、测试内容:测试7中移位指令是否能正确执行。运
29、行数据:0761 0011 MOV #0011,R1; 0021 SAR R1; 0761 0011 MOV #0011,R1;0041 SHL R1; 0761 0011 MOV #0011,R1;0061 SHR R1; 0761 0011 MOV #0011,R1;0081 ROL R1; 0761 0011 MOV #0011,R1;00A1 ROR R1; 0761 0011 MOV #0011,R1;023B FFFF INC #FFFF;00C1 RCL R1; 运行结果及分析:由于验证过程比较顺利,没有出现严重的错误,移位指令的执行结果也正确。这里只列出算术右移指令和带进位循环
30、右移指令的验证结果。先分析SAR:显然,MOV指令执行结果是正确的。现在分析SAR指令。首先通过查看微指令流程判断BM和NC是设置是否正确。首先,SAR执行的微指令依次是:00100200300601800709206F070000根据执行结果看:ALU中运行结果是0008,符合算术右移指令的规则。在分析RCR:在这个程序中,先执行MOV指令,再执行加一指令,最后执行带进位循环右移指令。显然,MOV指令的执行结果是正确的,加一指令也能按照其正确流程执行。对于RCR指令,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,RCR执行的微指令依次是:00100200300601800709E
31、06F070000,从指令执行流程来看,RCR指令时正确的。从指令运行结果来看,RCR由0000 0000 0001 0001变成了1000 0000 0000 1000,可见运行结果也是正确的。四、设计中遇到的问题及解决办法今天这次课设,主要问题出现在CPU的设计上。由于对Verilog的掌握还不是太熟悉,编写代码的时候还是会出现一些小问题。如实例化。而且在移位指令的编码上,我的想法还是和老师的有点不同。在我看来,移位指令的编码应该仅需要2个流程分支,即左移与右移,然后具体是逻辑左移还是算术左移,在shifter.v中已经用多路选择器来判断了,然而,最后还是为转移指令准备了7个分支,下次课设
32、的时候若时间有剩余的话,我会验证用2个流程分支来实现7个转移指令的正确性。第六天 为CPU扩充堆栈类指令一、设计目标 在前面CPU的基础上增加堆栈,使其支持与堆栈有关的PUSH,POP,CALL,RET指令。二、硬件设计1、SP模块设计(加上适当注释)timescale 1ns / 1psmodule SP(q,d,clk,ce,n_reset); parameter DATAWIDTH=16; output DATAWIDTH-1:0 q; input DATAWIDTH-1:0 d; input clk,ce,n_reset;reg DATAWIDTH-1:0 q;always (pose
33、dge clk or negedge n_reset)beginif (!n_reset) /复位信号有效时,堆栈SP为03Fq = h03F;else if (ce) /ce有效时,将输入送给输出q = d;endendmodule2、顶层模块设计(自己增加修改的设计部分)SP #(DATAWIDTH) SP1(.q(SP_out), .d(IB), .clk(clock), .ce(SPce), .n_reset(n_reset); buffer #(ADDRWIDTH) SP_Buf(.q(IB), .d(SP_out), .oe(SPoe);三、PUSH、POP、CALL、RET指令微
34、程序的设计PUSH指令微程序的设计:微地址(H)微指令(H)微指令字段(H)微命令F0F1F2F3F4F5F6F7F8F90C0F400 00C17500000000C1SPoe,Ace0C102B0 00C200A3000000C2DEC,SV0C27C08 00C33700200000C3Soe,ARce,SPce0C30005 2000000011020000ARoe,DRoe,WRPOP指令微程序的设计:微地址(H)微指令(H)微指令字段(H)微命令F0F1F2F3F4F5F6F7F8F90C8B000 00C95400000000C9ARoe,TRce0C9E008 00CA7000
35、200000CASPoe,ARce0CA0006 10CB0000110100CBARoe,RD,DRce0CB1008 00CC0400200000CCTRce,ARce0CC0005 20CD0000110200CDARoe,DRoe,WR,0CDF400 00CE7500000000CESPoe,Ace0CE0270 00CF0093000000CFINC,SV0CF7C00 0000370000000000Soe,SPceCALL指令的微命令设计:微地址(H)微指令(H)微指令字段(H)微命令F0F1F2F3F4F5F6F7F8F90D0F400 00D17500000000D1SPo
36、e,Ace0D1B2B0 00D254A3000000D2DEC,SV,ARoe,TRce0D27C08 00D43700200000D3Soe,ARce,SPce0D32003 00D41000300000D4PCoe,DRce0D48405 2000410011020000ARoe,DRoe,WR,TRoe,PCce RET指令的微命令设计:微地址(H)微指令(H)微指令字段(H)微命令F0F1F2F3F4F5F6F7F8F903CE008 003D70002000003DSPoe,ARce03D0006 103E00001301003EARoe,RD,DRce03EC400 003F61
37、000000003FDRoe,PCce03FF400 0040750000000040SPoe,Ace0400270 004100930000041INC,SV0417C00 0000370000000000Soe,SPce四、测试程序、数据及运行结果1、测试内容(1):CALL 0008H;MOV #1234,R1;RET;MOV #1111,R2;运行数据:运行结果及分析:结果分析:在这个程序中,先执行CALL指令,再执行MOV指令,接着执行RET指令,最后执行MOV指令。对于CALL指令,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,CALL执行的微指令依次是:0010020
38、0300601B01F0240250260070D00D10D20D30D4000,从指令执行流程来看,CALL指令时正确的。从指令运行结果来看,跳转到0008H单元执行MOV指令,可见运行结果也是正确的。对于MOV指令,这里就不再重复分析了。对于RET指令,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,RET执行的微指令依次是:00100200300703C03D03E03F040041000,从指令执行流程来看,RET指令时正确的。从指令运行结果来看,跳转到0002H单元执行MOV指令,可见运行结果也是正确的。测试内容(2):PUSH 0008H;POP 0008H;运行数据:运行结果及分析:结果分析:在这个程序中,先执行PUSH指令,再执行POP指令。对于PUSH指令,通过查看微指令流程判断BM和NC是设置是否正确。首先,CALL执行的微指令依次是:00100200300601B01F0240250260070C00C10C20C3000,从指令执行流程来看,POP指令时正确的。从指令运行结果来看,DR中保存了FDDA,且SP自减一,可见运行结果也是正确的。对于POP指令,首先通过查看微指令流程判断BM和NC是设置是否正确。首先,POP执行的微指令依次是:00100200300601B01F0240250260070C80C90CA