《多级流水CPU设计单片机课程设计.doc》由会员分享,可在线阅读,更多相关《多级流水CPU设计单片机课程设计.doc(29页珍藏版)》请在三一办公上搜索。
1、装订线 (指导教师用表)学 生 姓 名指 导 教 师论文(设计)题目多级流水CPU设计主要研究(设计)内容灵活运用所学到的基础知识和主要专业知识,设计、制作、调试最终完成多级流水CPU的设计研究方法根据所学基础知识和主要专业知识,设计多级流水CPU,使用VHDL语言。开发平台是FPGA-CPU设计平台,主要开发工具:Quartus7.0,DebugController主要任务及目标1. 设计出CPU实现多级流水 2. 完成从系统级设计到代码实现以及硬件上调试3. 完成学年论文主要参考文献1 (美)亨尼西,(美)帕特森计算机体系结构:量化研究方法(第3版)机械工业出版社,20032 汤志忠,杨春
2、武.开放式实验CPU设计.北京:清华大学出版社,2007进度安排论文(设计)各阶段名称日期系统概念设计及总体设计第10周代码实现阶段第1114周系统调试、试运行阶段第15周论文的整理定稿第15周 指导教师签字:系主任签字:主管教学院长签字: 学生姓名专业 年级论文(设计)题目多级流水CPU设计论文(设计)内容提要论文完成的主要工作包括:(l) 综合运用了所学知识,完成多级流水CPU系统级设计。(2) 通过VHDL语言实现逻辑设计。(3) 设计成果在FPGA硬件平台的运行指导教师评语成绩: 指导教师(签名): 年 月 日摘要本学期计算机体系课程设计题目是多级流水CPU设计。以计算机硬件为主,兼顾
3、计算机软件和计算机应用技术。在教师指导下,灵活运用所学到的基础知识和主要专业知识,自己设计、制作、调试,完成16位五级流水CPU的实际。本组设计并最终在FPGA实验平台上实现一个CPU芯片,具有五级流水。采用流水处理技术解决了流水线技术中的结构相关、数据相关和控制相关。设计了指令系统、指令格式、寻址方式、寄存器结构、数据表示方式、存储器系统,运算器、控制器和流水线结构等。用VHDL硬件语言进行逻辑设计,采用先进的工具软件进行模拟和测试,测试通过之后下载到FPGA芯片中,并在测试平台上通过规定测试程序的测试。关键字:流水线;FPGA;五级流水目录1.前言11.1实验目的11.2实验环境12.流水
4、线工作原理33.系统设计53.1概念设计53.2指令系统53.3时序设计64.结构设计94.1总体逻辑结构设计94.2分模块结构设计115.代码实现及测试135.1代码实现135.2程序测试195.3测试结果216.实验总结251. 前言1.1 实验目的1. 本实验需要自己设计并最终用FPGA实现一个CPU芯片。利用已有的计算机组成原理知识,以及对计算机系统结构的初步学习,设计一个包括指令系统、寻址方式、寄存器组、存储系统、流水线结构等的CPU。设计的CPU必须具有复位功能,以便使用TEC-CA实验台上的“CPU复位”按钮对CPU复位,使CPU处于调试前的初始状态。CPU复位脉冲按负脉冲设计。
5、2. 熟练掌握VHDL硬件描述语言,对CPU的各个功能模块进行代码编写,并学会将各个功能部分组织连接成一个完整CPU体系结构。3. 学会利用先进的硬件设计工具软件Quartus II对程序进行仿真和调试。并熟练掌握FPGA-CPU在“TEC-CA开放式CPU实验教学系统”上的调试方法。4. 在完成实验的过程中锻炼和提高实际动手能力、创新思维、团队合作精神等方面的能力。1.2 实验环境1. 总体描述FPGA-CPU设计平台能够支持下载到FPGA中的CPU的单步调试和连续运行。用户用VHDL编写的CPU代码通过编译之后,可以下载到设计平台上的FPGA芯片中。FPGA-CPU的运行通过执行预先写到外
6、部存储器中的程序来实现。使用DebugController程序对外部存储器进行读写操作,并能监控FPGA-CPU的状态和通过设置断点调试FPGA-CPU正在执行的程序。这套实验环境为实验者提供了最大的自由度来写出具有自己风格的CPU软核,并在测试运行平台上调试和运行。2. 硬件环境整个硬件平台主要有PC监控系统、外部程序存储器、FPGA-CPU及其下载相关电路,以及控制电路组成。其中PC监控系统主要是由监控软件DebugController及相关通信接口等构成,提供一整套的运行和调试功能。3. 软件环境Quartus-7.0我们使用该软件完成编码工作,并在active-hdl功能模拟通过后,进
7、行有效的时序模拟。最终烧片等都用该软件。调试程序DebugController使用该软件对外部存储器进行读写操作,并能监控FPGA-CPU的状态和通过设置断点调试FPGA-CPU正在执行的程序。2. 流水线工作原理流水线处理技术是在重叠、先行控制的基础上发展起来的,包括指令控制功能和功能处理过程都可采用流水处理。在先行控制方式中将一条指令的执行分为“分析”和“执行”两个子过程。这两个子过程分别使用指令分析器和运算器两个独立的部件来完成。所以可以利用多条指令执行时,在时间上相互错开,轮流重叠地利用这两个独立部件,来加快程序的执行速度。若实现“分析”与“执行”中的每一个子过程都需要t1=T/2时间
8、,则4条指令流水执行只需5t1,比起4条指令顺序执行所需的8t1时间少了近一半。如果将指令的“分析”子过程再进一步划分成“指令译码”和“取操作数”两个子过程,分别由“译码”和“取数”两个独立的子部件执行,并使所有子部件的经过时间都改进成t2=T/4,指令执行顺序如图2-1所示。图表 21指令执行顺序图图2-2是指令流水执行的时空图。图中横坐标为时间,纵坐标为空间(即各个子过程),标有数字的方格说明占用该空间与时间的任务号,在本例中表示机器处理的第1、第2、第3、第4、第5条指令,最多可以有4条指令在不同的部件中同时进行处理。这样计算机每隔t2就能输出一条指令的执行结果。图表 22指令流水执行时
9、空图按此思路,流水线的定义可以具体描述为:将一个复杂的处理过程分成m个复杂程度相当、处理时间大致相等的子过程,每个子过程由一个独立的功能部件来完成,处理对象在各子过程连成的线路上连续流动。在同一时间,m个独立部件同时进行不同的操作,完成对不同子过程的处理,这种工作方式称为流水线。在计算机流水线的实际应用过程中,为平滑缓冲各子部件之间的速度差异,在子部件之间往往都要设置高速接口缓冲器或一定容量的高数缓冲器来保存中间结果。也就是通常所说的n级流水处理中的级间寄存器。3. 系统设计3.1 概念设计指令流水的基本思路是把每条指令划分为几个执行步骤,这些步骤在执行过程中使用不同的资源从而在时间上能重叠起
10、来,提高了整体工作负载的吞吐率。我们将每条指令划分为“取指”、“译码”、“执行”、“访存”、“写回”这五个执行步骤。如图3-1所示。取指令IF指令译码ID指令执行EXE存储器读写 MEM寄存器写回WB图表 31多级流水CPU设计图3.2 指令系统指令系统设计的好坏影响整个系统各个方面的性能。我们采用了实验指导书中的指令系统。如表3-2所示:汇编语句操作码功能描述指令类型ADD DR,SR00000000DR+SRDR算术逻辑指令SUB DR,SR00000001DR-SRDRDEC DR00000010DR-1DRINC DR00000011DR+1DRCMP DR,SR00000110DR-
11、SR 比较AND DR,SR00000111DR and SRDR 逻辑与OR DR,SR00001000DR or SRDR 逻辑或XOR DR,SR00001010DR xor SR DR 异或TEST DR,SR00001011DR and SR, 测试SHL DR00001100逻辑左移,最低位补0,最高位移入CSHR DR 00001101逻辑右移,最高位补0,最低位移入CSAR DR00001110算术右移,最高位右移,同时再用自身的值填入MOV DR,SR00001111SR DR数据传送指令LOAD DR,SR01000001SR DRSTORE DR,SR01000010 S
12、R DRMOVI DR,IMM01000011IMM DR (双字指令)PSHF01000100FLAG入栈POPF01000101FLAG出栈PUSH SR01000110SR入栈POP DR01000111出栈 DRJR ADR00010000无条件跳转到ADR , ADR=原PC值+OFFSET控制转移指令JRC ADR00010001当C=1时,跳转到ADR, ADR=原PC值+OFFSETJRNC ADR00010010当C=0时,跳转到ADR, ADR=原PC值+OFFSETJRZ ADR00010011当Z=1时,跳转到ADR, ADR=原PC值+OFFSETJRNZ ADR00
13、010100当Z=0时,跳转到ADR, ADR=原PC值+OFFSETJMPA ADR01010000无条件跳转到ADRRET01010001子程序返回CALL ADR10000000调用首地址在ADR的子程序(双字指令)NOP11000000空操作其他HALT0001000011111111停机 (JR 0XFFFF)图表 32CPU的指令系3.3 时序设计本次课程设计采用的五级流水时序如图3-3所示,数据通路如图3-4所示。图表 33 五级流水时序图图表 34 五级流水数据通路为保证指令的正确执行。处理结构相关需要做两项工作:冲突检测和取指延后。1. 冲突检测只有执行访存指令(LOAD/S
14、TORE)时,才会出现冲突。因此,我们在译码时产生一个标志是否访存的信号wMem。含义如图3-5:wMem意义00写内存(STORE)01读内存(LOAD)1不占用内存图表 35 wMEM控制信号通过检查“访存阶段”的m_wrMem就可确定是否冲突。2. 取指延后在每次取指时,若有冲突,则往IR中写入空指令(NOP),并保持PC不变,使取指延后一个节拍。在解决了结构相关、控制相关、数据相关后,五级流水时序图最终设计如图3-6:图表 36 五级流水时序图4. 结构设计4.1 总体逻辑结构设计总体逻辑设计的RTL图参考课本中的设计,如图4-1所示。图表 41各个功能部件的功能及其使用的控制信号:
15、1. ALU:组合逻辑部件,对两个16位的输入及进位输入Cin可进行由3位控制信号控制。2. 数据选择器BUS_MUX:组合逻辑器件,其输入包括:源寄存器数据,目标寄存器数据,带符号位扩展的偏移地址,PC,以及从内存读取的立即数、跳转地址等数据。在3位控制信号的控制下它进行ALU 模块A、B端输入的选择。3. 程序计数器PC:时序逻辑器件,16位寄存器,在控制信号pc_en的控制下可接收ALU的运算结果(高电平接收,否则保持不变)。输出送往地址寄存器(读取指令内容)以及数据选择器(进行自增运算)。4. 地址寄存器AR和指令寄存器IR:都是16位的寄存器,地址寄存器用于存放要读写的内存地址单元的
16、地址,输出送往地址总线,输入可能为PC内容,也可能为ALU的输出(对读写内存指令);指令寄存器存放当前执行指令的内容,它的输入来自从内存读取的指令和数据,输出送往控制逻辑。二者共用两位控制信号REC。寄存器组和寄存器的选择:本实验中的寄存器都为16位,带有清零端和使能端,实际上在写VHDL程序时,通用寄存器以及AR、IR、PC使用的都是同一个模板。按照我们的设计,通用寄存器共有16个,由指令的低8位的全部或其中的高4位或低4位来从寄存器组中选择源寄存器和目的寄存器。安排寄存器选择器件reg_mux,为组合逻辑器件,用于输出选定寄存器的内容。5. 节拍发生器:时序逻辑器件,作用是用多位触发器的输
17、出信号的不同组合状态,来标识每条指令的执行步骤。其功能相当于一个状态机。前文已述,我们设计的节拍发生器共有3位触发器。在编码方面,遵循了这样的原则:从一个状态变到下一个状态时,状态发生变化的触发器数目应尽量少。6. 控制逻辑:组合逻辑器件,前面已提到,它根据指令内容(由IR提供)和指令的执行步骤(由节拍发生器提供)及其他一些条件信号(标志寄存器输出),形成并提供出计算机各部件当前时刻要用到的控制信号。根据前面所总结的全部控制信号的意义、作用和数值,可以比较容易地写出控制逻辑部件。7. REG_OUT:对外输出寄存器内容的译码电路,组合逻辑器件,根据外部输入的寄存器选择信号输出制定的寄存器内容(
18、包括为了便于观察引出的内部信号寄存器)。8. 时序设计:结构相关的处理和数据相关的处理。整个CPU由以下几个模块组成:1. 取指模块(IF):给出内存地址,读取指令并送入指令寄存器,为下一级准备数据。由于PC控制模块处于取指模块中,因此控制相关的检测也置于取指模块。2. 译码模块(ID):读取寄存器值和指令译码。我们采取一次译码,逐级传递的方式,译出后几级流水所需的控制信号和数据(如立即数等),在每次时钟上升沿到来时送入下一级。实际上,结构相关、控制相关、数据相关的检测都可归入译码部分。考虑到“相关检测”涉及到的信号分属不同阶段以及整体结构的清晰性,我们将“相关检测”独立出来。3. 执行模块(
19、Ex):完成算术逻辑运算、计算有效地址和提供数据通道。4. 访存模块(Ma):选择地址线的数据来源和数据线的流向。访存和取指在功能上是独立的,但CPU对外只有一条地址线和数据线的事实决定了访存和取指是相互联系的。当执行LOAD/STORE指令时,地址线由ALU送入“访存段”的值提供;取指时,则由PC提供。当写内存时,CPU内部数据送数据线;当需要读内存时,CPU往数据线送高阻。5. 回写模块(Wb):选择回写数据源和根据写使能信号wRegEn将数据回写到寄存器堆;6. HazardDetectUnit模块:检测结构相关;7. ForwardingUnit模块:检测数据相关。其中由我完成取指模块
20、、译码模块、执行模块。4.2 分模块结构设计1. 取指模块主要完成两个任务,一是根据程序计数器PC里的指令地址从指令存储器里读取指。另一个任务主要完成PC+1计算和下一条指令地址的猜测。对下一条指令的猜测主要是假设分支条件不成立,猜测下一条指令地址是本指令地址的下一地址,除了对下一条指令的猜测,还完成对上一次的猜测的确认。本指令地址的确认主要是完成如果上一条指令是分支指令时,如果分支条件不成立,本指令地址猜测是正确,指令有效,继续执行,否则本指令无效,重新再取指。2. 译码模块译码阶段,是整个系统中的关键控制阶段,不但进行指令译码,从寄存器堆中读取操作数,而且判断分支指令的跳转条件,计算跳转地
21、址和处理数据相关性问题。这一阶段主要器件有译码单元,寄存器堆,加法器,比较器和地址选择器等。译码单元,可以说是核心控制单元,根据指令代码译码成各种控制信号控制各个单元的控制,而且进行数据相关处理。执行阶段主要完成指令的逻辑运算工作,ALU根据操作控制码对所提供的操作数进行相应的操作。读/写储存阶段主要完成存储器中数据的读取和写入,是微处理器系统中比较复杂的功能,在这主要完成微处理器内部数据存储器的读写。3. 执行模块执行阶段主要完成指令的逻辑运算工作,ALU根据操作控制码对所提供的操作数进行相应的操作。读/写储存阶段主要完成存储器中数据的读取和写入,是微处理器系统中比较复杂的功能,在这主要完成
22、微处理器内部数据存储器的读写。结构图如图4-2所示。图表 42五级执行模块结构图5. 代码实现及测试5.1 代码实现使用VHDL语言语言编写内部模块,完成程序编译后下载到硬件平台上,通过元件的例化配置,将内存模块和已有的CPU模块连接起来,构成一个完整的计算机系统。1. 取指模块取指模块给出内存地址,读取指令并送入指令寄存器,为下一级准备数据。该模块RTL图如图5-1所示:图表 51 取指模块RTL图PC作为程序计数器,程序计数器控制关键代码如下:op = IR(15 downto 8);-操作码with e_setFlag select ZZ = Zwhen flag_hold, tempZ
23、 when others;with e_setFlag select CC = Cwhen flag_hold, tempC when others;s_selZ = 1 WHEN( op=JRZ AND ZZ=1) -判断是否跳转 OR ( op=JRNZ AND ZZ=0) OR op=JR else 0; s_selC = 1 WHEN( op=JRC AND CC=1) -判断是否跳转 OR ( op=JRNC AND CC=0) else 0; PCIncSel = 1 WHEN s_selZ=1 or s_selC=1 ELSE 0; s_PCInc1 = PC + x0001;
24、WITH PCIncSel SELECT PCnext = s_PCInc1 WHEN 0, PCPlusOffset WHEN 1, s_PCInc1 when others; process(reset,clk,PCStall)beginif reset = 0 thenPC = x0000; elsif FALLING_EDGE(clk) and (PCStall=0) then PC = PCnext;end if;end process;取指部分采用一个process来完成,关键代码如下:process(reset,clk,OuterDB,IFFlush)beginif reset=
25、0 thenIR IR IR = NOPIns;end case;d_PCInc1 ctrl:=d_IR(7 downto 0)&10&1&1&001&0000&001;when SUBB = ctrl:=d_IR(7 downto 0)&10&1&1&001&0001&001;when DEC = ctrl:=d_IR(7 downto 0)&10&1&1&100&0000&001;when INC = ctrl:=d_IR(7 downto 0)&10&1&1&010&0000&001;when ANDins = ctrl:=d_IR(7 downto 0)&10&1&1&001&0010
26、&001;when CMP = ctrl:=d_IR(7 downto 0)&10&0&1&001&0001&001;when TEST = ctrl:=d_IR(7 downto 0)&10&0&1&001&0010&001;when ORins= ctrl:=d_IR(7 downto 0)&10&1&1&001&0011&001;when XORins= ctrl:=d_IR(7 downto 0)&10&1&1&001&0100&001;when SHLIns = ctrl:=d_IR(7 downto 0)&10&1&1&000&0101&001;when SHRIns = ctrl
27、:=d_IR(7 downto 0)&10&1&1&000&0110&001;when SAR = ctrl:=d_IR(7 downto 0)&10&1&1&000&0111&001;when MOV = ctrl:=d_IR(7 downto 0)&10&1&1&011&0000&000;when LOADH= ctrl:=11111111&10&1&1&101&1000&000; imm ctrl:=11111111&10&1&1&101&1001&000; imm ctrl:=d_IR(7 downto 0)&01&1&0&011&0000&000;when STORE= ctrl:=
28、d_IR(7 downto 0)&00&0&1&000&0000&000;when JR|JRZ|JRNZ|JRC|JRNC = ctrl:=DoNothing; -若是JR*指令,计算offset,并向Exe插入Bubble offset ctrl:=DoNothing; end case;SA = ctrl(21 downto 18);SB = ctrl(17 downto 14);WrMem = ctrl(13 downto 12);wRegEn = ctrl(11);MemToReg= ctrl(10);ALUSrc = ctrl(9 downto 7);ALUOpr = ctrl(6
29、 downto 3);SetFlag = ctrl(2 downto 0);end process;流水控制信号的处理部分代码如下:process(reset,clk)beginif reset = 0 then e_wrMem = 10;- do nothinge_wRegEn = 0; elsif RISING_EDGE(clk) thene_SA = SA;e_SB = SB;e_RAOut = RA;e_RBOut = RB;e_IMM = imm;e_ALUSrc = ALUSrc;e_ALUOpr = ALUOpr;e_SetFlag = SetFlag;e_wrMem = wrM
30、em;e_wRegEn = wRegEn;e_destReg = SA;e_MemToReg = memToReg;end if;end process;3. 执行模块选择运算器A,B口数据来源的部分的关键代码如下:with forwardA selectALUaIn= e_RAOut when 00, e_ALUOut when 10, w_WBdata when 01, e_RAOut when others;with forwardB selectALUbInopR := 0&ALUaIn;opS := ZERO17;when selAB=opR := 0&ALUaIn;opS := 0
31、&ALUbIn;when selA1=opR := 0&ALUaIn;opS := 0&(X0001); when sel0B=opR := ZERO17;opS := 0&ALUbIn;when selAF=opR := 0&ALUaIn;opS := 1&(XFFFF);when selAD=opR := 0&ALUaIn;opS := 0&e_IMM;when others = opR := ZERO17;opS := ZERO17;end case;case e_ALUOpr is -选择ALU的运算when aluAdd = ALUResult := opR + opS; tempV
32、 := (not opR(15)and(not opS(15)and ALUResult(15) or (opR(15)and opS(15)and (not ALUResult(15); when aluSub = ALUResult := opR - opS; tempV := ( opS(15)and(not opR(15)and (not ALUResult(15) or (NOT opS(15)and opR(15)and ALUResult(15); when aluAnd = ALUResult := opR and opS;when aluOr = ALUResult := o
33、pR or opS;when aluXor = ALUResult := opR xor opS;when aluShl = ALUResult(15 downto 1) := opR(14 downto 0); ALUResult(0) := 0;cx := opR(15);when aluShr = ALUResult(14 downto 0) := opR(15 downto 1); ALUResult(15) := 0;cx := opR(0); when aluSar = ALUResult(14 downto 0) := opR(15 downto 1); ALUResult(15
34、) := opR(15); cx := opR(0);when aluLOADH = ALUResult := opS(8 downto 0)&opR(7 downto 0); when aluLOADL = ALUResult := 0&opR(15 downto 8)&opS(7 downto 0);when others = null;end case; dout tempC := ALUResult(16);when aluShl|aluShr|aluSar = tempC := cx;when aluAnd|aluOr|aluXor = tempC := 0; tempV:= 0;
35、-逻辑运算,状态位C,Z置零when others = null;end case;i_tempC = tempC;if ALUResult = ZERO17 thentempZ := 1;else tempZ := 0;end if; i_tempZ (C,Z,V,S) C=tempC;Z = tempZ;V = tempV;S (C,Z,V,S) C=0; Z=0; V=0; S (C,Z,V,S)= tempFLAG; end case;end process;修改状态寄存器部分的关键代码如下:WriteFlag:process(reset,clk)beginif reset = 0 t
36、hentempFlag = 0000;elsif RISING_EDGE(clk) thentempFlag = C&Z&V&S; end if;m_flag = tempFlag;end process; 传递给Mem部分的控制信号处理关键代码如下:process(reset,clk)begin if reset=0 then m_wrMem = 10;m_wRegEn = 0;elsif RISING_EDGE(clk) thenm_SA = e_SA;m_ALUOut = dout;m_RBdata = ALUbIn;m_wRegEn = e_wRegEn; m_memToReg = e_memToReg;m_destReg = e_destReg;m_wrMem = e_wrMem; end if;end process;5.2 程序测试1Test1 8位8位乘法运算; 8bit x 8bit multiplier; 测试指令:置立即数,AND, 条件跳转, 左移, 右移;MAIN: MOV