《能力拓展训练》课程设计-简易CPU课程设计.doc_第1页
《能力拓展训练》课程设计-简易CPU课程设计.doc_第2页
《能力拓展训练》课程设计-简易CPU课程设计.doc_第3页
《能力拓展训练》课程设计-简易CPU课程设计.doc_第4页
《能力拓展训练》课程设计-简易CPU课程设计.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

武汉理工大学能力拓展训练课程设计说明书摘 要 目前以硬件描述语言(Verilog 或 VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至 FPGA 上进行测试,是现代 IC 设计验证的技术主流。这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(FlipFlop)或者其他更加完整的记忆块。系统设计师可以根据需要通过可编辑的连接把FPGA内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。一个出厂后的成品FPGA的逻辑块和连接可以按照设计者而改变,所以FPGA可以完成所需要的逻辑功能。计算机最核心的部分叫做中央处理器,也就是我们常说的CPU,计算机所做的所有工作都需要经过CPU的处理,本设计以Verilog HDL为基础设计一个简易的CPU。关键字:CPU Verilog HDL FPGA目 录1 CPU概述11.1 简介11.2 CPU内部框架11.3 CPU的内部工作原理22 CPU各个模块的设计及分析42.1 PC部分的设计42.2 存储器的设计52.3 指令解码器的设计82.4 算术逻辑运算单元(ALU)112.5 控制单元132.6 CPU顶层设计183 仿真结果193.1 PC部分193.2 存储器部分193.3 指令解码器部分193.4 算术逻辑运算单元(ALU)部分203.5 控制单元部分203.6 CPU顶层设计部分20小结与体会21参考文献22简易CPU设计1 CPU概述1.1 简介 计算机最核心的部分叫做中央处理器,也就是我们常说的CPU,计算机所做的工作都是由CPU来完成的。当然,作为学习,我们不能够设计出类似奔腾处理器(Pentium microprocessor)的CPU,我们用一个能够完成简单功能的简单的CPU作为讲解,麻雀虽小,五脏俱全,这个简单的CPU具有一般CPU的全部基本特征。 众所周知,CPU 只能识别二进制数据,也就是机器码。所以,在CPU内部靠不同的二进制序列来区别不同的机器码。我们把这些机器码存储在一个存储器中,共CPU读取使用。同时,为了用户和程序员能够更好的记住机器码的含义,采用相应的助记符来表示这些机器码,如用LDA表示二进制的000等。这些助记符通常被称为汇编语言,不同架构的计算机的汇编语言通常都是各不相同的。1.2 CPU内部框架如图1-1是本设计的一个CPU内部结构框架。存储器ALU控制器指令解码器PC图1-1 CPU内部结构框架1.3 CPU的内部工作原理不同架构的计算机工作原理也是不同的,此处仅以课本中讲授的CPU工作原理为例讲解。首先,CPU的指令是存储在存储器中的,所以CPU执行指令的第一步是从存储器中取出(fetch)指令,第二步,将取出的指令解码,第三步,根据指令解码出的功能决定是否再从存储器中取出需要处理的数据,第四步,根据解码出的指令决定进行相应的计算,这由(ALU)完成。第五步,根据解码出的指令决定是否将计算结果存入存储器,第六步,修改PC指针,为下一次取指令做准备。整个执行过程由控制器控制。 在介绍具体的CPU硬件架构之前,我们先确定一些CPU能够执行的指令,在这里,为了教学演示,我们设定6个计算机指令,分别为:LDA指令、STA指令、ADD指令、SUB指令、AND指令和HLT指令。指令集所表示的含义如表1-1所示:表1-1 指令集含义操作码助记符执行的功能000LDA addr将地址为addr处的存储器中的内容装载到A寄存器001STA addr将A寄存器的内容存储到存储器中的addr地址处010ADD addr将A寄存器的内容加上存储器中的addr地址处的内容011SUB addr将A寄存器的内容减去存储器中的addr地址处的内容100AND addr将A寄存器的内容与上存储器中的addr地址处的内容101HLT停止指令的执行 前两条指令,“LDA”和“STA”是数据传输指令,就像助记符表示的那样,这些指令在A寄存器和存储器之间传送数据。对于LDA指令,“源”数据是存储器的addr地址处的值(也称为内容),目的寄存器是A寄存器;对于STA指令,“源”数据是A寄存器,目的寄存器是存储器的addr地址处的存储空间。我们把这段程序放在存储器的开始(更方便程序的启动)。由于在代码中我们用到了存储器地址为01011和01100中的数据,所以我们可以在那两个位置放置一些要处理的数据。 现在,我们逐步分析汇编程序的执行情况,根据上表,我们看到,前三条指令的目的是将01011地址处对应的数据和01100处对应的数据进行相加,并且把结果存储到地址01101处。由于计算结果为11111111,所以,影响标志位NF。第3,4,5条指令是将01011地址处对应的数据和01100处对应的数据进行相“与”,并且把结果存储到地址01110处。此时,与运算的结果为00000000,所以影响标志位ZF,同时将NF标志清0。接下来的3条指令是将01011地址处对应的数据和01100处对应的数据进行相“减”,并且把结果存储到地址01110处。此时,相减运算的结果为00000000,所以影响标志位ZF,同时将NF标志清0。2 CPU各个模块的设计及分析2.1 PC部分的设计 PC(程序计数器)负责生成存储器的地址值(在下一步骤中会将对应地址的存储器中的指令取出),然后将自身加1,使其指向下一条将要执行的指令,为取下一条指令的执行做好准备。根据这些,我们设计的PC端口有:clock:时钟端 reset:异步复位端,也可以设计成同步复位en:使能端,当en为高电平的时候,允许pc工作pc:当前程序计数器的值,此处拟设计的计算机可以寻址32个字节,故pc是一个5位宽总线在模块内部有pc_next,指向下一个pc(即:pc + 1),五位宽。在下一个时钟信号上升沿的时候将pc + 1赋值给pc。模块原理图如2-1所示:图2-1 PC模块原理图测试程序源代码:module pc(clock,reset,en,pc);input clock,reset, en;output reg 4:0 pc;reg 4:0 pc_next;always(posedge clock or posedge reset)begin if(reset) pc = 0; else if(en) pc = pc_next; else pc = pc;endalways(posedge clock or posedge reset)begin if(reset) pc_next = 0; else if(en) pc_next = pc + 1; else pc_next = pc_next ;endendmodule2.2 存储器的设计 根据实际应用进行简化,实际的存储器一般有数据线口(双向的),地址线,读使能、写使能和片选信号线等,此处由于双向信号线处理起来比较繁琐,拟使用两组数据线,一组为输入数据线,一组为输出数据线,当需要将数据存储到存储器的时候,数据由输入总线输入,当需要从存储器读取数据的时候,数据由输出总线输出。另外,增加异步复位和时钟端,使数据的存取进行同步。实际用到的端口如下:clock:时钟信号线reset:复位信号,高电平有效addr:存储器地址线,5位宽din:数据线输入dout:数据线输出wr:写使能端,高电平有效rd:读使能端,高电平有效模块原理图如2-2所示:图2-2 存储器模块原理图测试程序源代码:module memory(clock,reset,addr,din,dout,wr,rd );inputclock;/:时钟信号线inputreset;/:复位信号,高电平有效input4:0 addr;/存储器地址input7:0din;/:数据线输入output7:0dout; reg7:0dout;/数据线输出/:数据线输出inputwr;/:写使能端,高电平有效inputrd;/:读使能端,高电平有效 reg7:0 mem0:31;always(posedge clock or posedge reset) begin if(reset) begin mem0 = b00001011;/ LDA 01011 mem1 = b01001100;/ ADD 01100 mem2 = b00101101;/STA 01101 mem3 = b00001011;/ LDA 01011 mem4 = b10001100;/ AND 01100 mem5 = b00101110;/ STA 01110 mem6 =b00001011;/ LDA 01011 mem7 =b01101100;/ SUB 01100 mem8 =b00101111;/ STA 01111 mem9 =b10100000;/ HLT mem10=b00000000;mem11=b10101010;mem12=b01010101; mem13=b00000000;mem14=b00000000;mem15=b00000000;mem16=b00000000;mem17=b00000000;mem18=b00000000;mem19=b00000000;mem20=b00000000;mem21=b00000000;mem22=b00000000;mem23=b00000000;mem24=b00000000;mem25=b00000000;mem26=b00000000;mem27=b00000000;mem28=b00000000;mem29=b00000000;mem30=b00000000;mem31=b00000000; endelse begin if(wr) memaddr = din; if(rd) dout = memaddr; end endendmodule2.3 指令解码器的设计 指令解码器的作用就是将从指令存储器中读出的指令进行翻译,使CPU能够根据翻译后的代码执行不同的操作。这里拟将指令分成两个组成部分:第一部分为操作码部分,由指令中的高三位组成,第二部分为存储器的地址,由指令的低五位组成。D7D6D5D4D3D2D1D0操作码操作数的地址从存储中取出的指令图2-3 指令组成示图根据以上,设置指令译码器主要有以下一些端口:clock:时钟端口 reset:复位端口en:译码使能端 instruction:指令输入端口opcode:操作码输出端口 addr:存储器地址输出端口模块原理图如2-4所示:图2-4 指令解码器模块原理图程序测试源代码:module decoder(clock,reset,en,instruction,opcode,addr);input clock,reset;input en;input7:0 instruction;output2:0 opcode;output4:0 addr;reg2:0 opcode;reg4:0 addr;always(clock or reset or en or instruction) if(reset); else if(en) case(instruction7:5) 3b000:opcode=(3b000); 3b001:opcode=(3b001); 3b010:opcode=(3b010); 3b011:opcode=(3b011); 3b100:opcode=(3b100); 3b101:opcode=(3b101); 3b110:opcode=(3b110); 3b111:opcode=(3b111);endcasealways(clock or reset or en or instruction) if(reset); else if(en) case(instruction4:0) 5b00000:addr=(5b00000); 5b00001:addr=(5b00001); 5b00010:addr=(5b00010); 5b00011:addr=(5b00011); 5b00100:addr=(5b00100); 5b00101:addr=(5b00101); 5b00110:addr=(5b00110); 5b00111:addr=(5b00111); 5b01000:addr=(5b01000); 5b01001:addr=(5b01001); 5b01010:addr=(5b01010); 5b01011:addr=(5b01011); 5b01100:addr=(5b01100); 5b01101:addr=(5b01101); 5b01110:addr=(5b01110); 5b01111:addr=(5b01111); 5b10000:addr=(5b10000); 5b10001:addr=(5b10001); 5b10010:addr=(5b10010); 5b10011:addr=(5b10011); 5b10100:addr=(5b10100); 5b10101:addr=(5b10101); 5b10110:addr=(5b10110); 5b10111:addr=(5b10111); 5b11000:addr=(5b11000); 5b11001:addr=(5b11001); 5b11010:addr=(5b11010); 5b11011:addr=(5b11011); 5b11100:addr=(5b11100); 5b11101:addr=(5b11101); 5b11110:addr=(5b11110); 5b11111:addr=(5b11111); endcaseendmodule2.4 算术逻辑运算单元(ALU) 算术逻辑单元完成各种运算功能,此处设计的ALU具有一个寄存器A(通常称作累加器),ALU具有一个输入端口,使用累加器A和这个输入端口作为两个运算数据的输入,并将运算结果存放在累加器A中。为了使所有的单元都受控制器的控制,使设计简单化,分别设置几个运算控制使能端,完成不同的运算使能。另外,为了能够监测运算结果的特殊性,设置以下相应的标志位,如进位位、溢出位、零标志位和负数标志位。本算数逻辑运算单元拟设计的端口有几下几种:clock:时钟reset:复位端en:使能ALUa:累加器输出寄存器din:操作数1输入n:输出负标志z:输出0标志c:输出进位标志v:输出溢出标志add_en:使能加法运算sub_en:使能减法运算pass_en:使din直通至累加器A,部分指令需要and_en:使能“与”运算模块原理图如2-5所示:图2-5 ALU原理图程序测试源代码:module alu(clk,reset,en, a,din,n,z,c,v,add_en,sub_en,and_en,pass_en);input clk,reset,en,add_en,sub_en,and_en,pass_en;input 7:0 din;output n,z,c,v;output reg 7:0 a;reg c;always(posedge clk or posedge reset)if(reset) begina=0;c=0;endelse begin if(en) beginif(add_en)c,a=a7:0+din;else if(sub_en)c,a=a7:0-din;else if(and_en)a=a&din;else if(pass_en)a127)|(a-128)?1:0;endmodule2.5 控制单元 接下来就是控制单元的设计了。控制单元需要做以下一些事情: (1)给出操作时序。上述的单元模块必须在一定的顺序下工作,从存储器中取指令译码根据操作码决定是否从存储器中取数据确定ALU的运算。此工作可以通过设置一些时能端口,如:按照一定的顺序使能相应的模块即可。 (2)控制器必须能够识别译码器输出的指令,并且根据指令发出不同的命令信号,故需要有一个指令输入端口,opcode2:0。 (3)如果需要做ALU运算的话,给出需要做相应运算的使能。如:给出使能加法运算信号instr_add使能 add_en。 (4)在一条指令中,如果即需要从存储器中取指令,又需要从存储器中取数据的话,则,需要在不同的阶段选择不同的存储器地址输入。故需要一个地址选择端口。所以控制单元应有以下一些端口:clock:时钟端口reset:异步复位端口s0s5:分别用作各个阶段的使能信号端口addrsel:选择程序的地址或者是数据的地址instr_add:给alu的加法运算使能instr_sub:给alu的减法运算使能instr_and:给alu的 “与” 运算使能instr_pass:给alu的直通运算使能,即不做运算opcode2:0 :解码器解码后的指令输出给控制器模块原理图如2-6所示:图2-6 控制单元原理图程序测试源代码:module control(input clock,input reset,output reg s0, / fetch instructionoutput reg s1, / decodeoutput reg s2, / read memory data for processoutput reg s3, / enable alu to computeoutput reg s4, / write to memory if nessaryoutput reg s5, / increase pcoutput reg addrsel,output reg instr_add,output reg instr_sub,output reg instr_and,output reg instr_pass,input 2:0 opcode);parameter LDA=3b000,STA=3b001,ADD=3b010, SUB=3b011,AND=3b100,HLT=3b101;reg 2:0 cnt;always(posedge clock or posedge reset)if(reset)cnt = 0;elseif(cnt = 5) cnt = 0;else cnt = cnt +1;always*begincase(cnt)0:begin/ fetch instructions0 =1;s1=0;s2=0;s3=0;s4=0;s5=0;addrsel=0; end1:begin/ decodes0 =0;s1=1;s2=0;s3=0;s4=0;s5=0;addrsel=0;end2:begin/ read memory data for process if nessary s0 =0;s1=0;/*s2=1;*/s3=0;s4=0;s5=0; addrsel=1;if(opcode = LDA )|(opcode = ADD)|(opcode = SUB)|(opcode = AND) s2=1;else s2=0;end 3:begin /enable ALU to computes0 =0;s1=0;s2=0;s3=1;s4=0;s5=0; addrsel=1; if(opcode = LDA) begin instr_add =0;instr_sub =0; instr_and =0; instr_pass=1; endelse if(opcode = ADD) begin instr_add =1;instr_sub =0;instr_and =0;instr_pass=0;endelse if(opcode = SUB) begin instr_add =0;instr_sub =1;instr_and =0;instr_pass=0; endelse if(opcode = AND) begin instr_add =0;instr_sub =0;instr_and =1; instr_pass=0; endelse if(opcode = STA) begin instr_add =0;instr_sub =0;instr_and =0;instr_pass=0; endelse begin instr_add =0;instr_sub =0;instr_and =0;instr_pass=0; end end4:begin/ write to memory if nessarys0 =0;s1=0;s2=0;s3=0;/*s4=1;*/s5=0; addrsel=1;if(opcode = STA) s4=1;else s4=0; end5:begin s0 =0;s1=0;s2=0;s3=0;s4=0;s5=1;addrsel=1; endendcaseendendmodule2.6 CPU顶层设计将各个单元模块生成符号,并且在图形输入中进行调用和连接,就可以进行CPU的仿真了。顶层原理图如图2-7所示:图2-7 顶层原理图其中sel的代码如下:module sel(input 4:0 a,input 4:0 b,input se,output 4:0 c);assign c=se?a:b;endmodule3 仿真结果3.1 PC部分图3-1 PC仿真结果图3.2 存储器部分图3-2 存储器仿真结果图3.3 指

温馨提示

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

评论

0/150

提交评论