5级流水无cache cpu实验计算机组成原理 课程设计报告

上传人:仙*** 文档编号:28297258 上传时间:2021-08-25 格式:DOC 页数:26 大小:828KB
返回 下载 相关 举报
5级流水无cache cpu实验计算机组成原理 课程设计报告_第1页
第1页 / 共26页
5级流水无cache cpu实验计算机组成原理 课程设计报告_第2页
第2页 / 共26页
5级流水无cache cpu实验计算机组成原理 课程设计报告_第3页
第3页 / 共26页
点击查看更多>>
资源描述
计算机组成原理课程设计报告5级流水无cache CPU实验1.1 实验内容:无cache流水CPU的分析与改造1. 理解无cache流水CPU的工作原理,明确系统总体结构和数据通路图,分析解决各种相关用到的主要信号,以及详细分析各流水段的功能和实现。2. 将16位的指令系统改为8位,设计新的指令系统,并修改相应的数据通路。3. 修改规则文件(cpu.txt),并编写测试程序验证系统改造的正确性。1.2 总体基本信息1. 深刻理解无cache流水cpu的工作原理。在详细分析了各流水段的功能实现、3种相关的产生原因和解决方法的基础上,完成了以下后续工作。2. 修改指令系统。具体包括:a) 16位指令改为8位,重新编写了指令OP码。b) 新增了MOVI指令。由于原指令系统没有将立即数存进指定寄存器的指令,因此此处新增一条MOVI指令。指令的汇编语句为MOVI DR, IMM其中DR为目的寄存器,IMM为立即数。因为指令长度为8位,OP和DR共占了6位,因此IMM的大小不大于3(即二进制“00”至“11”)。c) 修改及删除了部分指令。此处详见5.1。3. 修改系统控制信号。在保持原有系统逻辑功能基本不变的情况下,修改各个模块里控制信号位数以及模块接口信号位数以和新的指令系统兼容。4. 增加内存模块。使用vhdl编写了一个ram模块,根据读写信号来选择读写功能。reset时将事先写好的二进制形式程序写进内存。5. 扩展了常量定义文件。在常量定义文件unitpack.vhd中,具体地:a) 新增了ALU功能选择信号常量aluMOVI。b) 新增了寄存器编号常量R0、R1、R2和R3。c) 新增了ram类型。6. 使用Quartus II进行功能仿真并debug。7. 使用bdf构造顶层实体cpum。由于新增了内存模块,而原系统是使用vhdl编写的,为了方便对接,我们使用bdf的形式将无cache流水线cpu和内存模块连接起来构造顶层实体cpum,“m”的含义是“memory”,即带内存模块的无cache流水线cpu。8. 重画数据通路图。我们使用了Microsoft Visio软件在原有的系统总结结构图的基础上修改并新增了部分模块,详见2。2、系统总体结构及数据通路图总体结构图:数据通路图:整个CPU由以下几个模块组成:l 取指模块(IF):给出内存地址,读取指令并送入指令寄存器,为下一级准备数据。由于PC控制模块处于取指模块中,因此控制相关的检测也置于取指模块。l 译码模块(ID):读取寄存器值和指令译码。我们采取一次译码,逐级传递的方式,译出后几级流水所需的控制信号和数据(如立即数等),在每次时钟上升沿到来时送入下一级。实际上,结构相关、控制相关、数据相关的检测都可归入译码部分。考虑到“相关检测”涉及到的信号分属不同阶段以及整体结构的清晰性,我们将“相关检测”独立出来。l 执行模块(Ex):完成算术逻辑运算、计算有效地址和提供数据通道。l 访存模块(Ma):选择地址线的数据来源和数据线的流向。访存和取指在功能上是独立的,但CPU对外只有一条地址线和数据线的事实决定了访存和取指是相互联系的。当执行LOAD/STORE指令时,地址线由ALU送入“访存段”的值提供;取指时,则由PC提供。当写内存时,CPU内部数据送数据线;当需要读内存时,CPU往数据线送高阻。l 回写模块(Wb):选择回写数据源和根据写使能信号wRegEn将数据回写到寄存器堆;l HazardDetectUnit模块:检测结构相关;l ForwardingUnit模块:检测数据相关。l 内存模块memory,根据访存地址mem_adr和读写信号wr来控制。3 解决各种相关用到的主要信号的分析3.1控制相关 控制相关是指因为程序的执行方向可能改变而引起的相关。当执行跳转指令时,就会发生这种情况。除JR外,JRZ等条件跳转需要根据当前状态位来决定是否跳转,而当前状态位是由前面最近的会影响状态位的指令(如算术指令)决定。常规的也是比较简单的做法是在碰到JRX之类的跳转指令时,延迟后边流水线的进入。但我们通过分析,认为可以一点都不必延迟,通过旁路处理把控制相关转为数据相关来处理。这样处理,不必延迟,可以提高流水线的性能。按我们的方式解决控制相关需要做两项工作:1) 通过旁路,提供状态寄存器的值和临时状态位的值,为判断是否跳转作准备;2) 选择PC更新的时机1旁路处理在每条指令译码时,会产生一个信号setFlag,它决定了在执行阶段是否根据ALU计算结果改变状态位。从下面的时序图中可以发现,只要我们在JRX指令译码时提供以下3个信号就可作出是否跳转的决定:信号含义tFlagALU计算出的临时状态位,Flag状态寄存器输出,e_setFlag状态寄存器写使能表17 处理控制相关信号若e_setFlag要写状态寄存器,则说明前一条指令会影响状态位,这时根据tFlag决定是否跳转;若e_setFlag要保持状态寄存器,则说明前一条指令不会影响状态位,这时根据Flag决定是否跳转。涉及到控制相关的关键信号是setFlag信号,产生于译码模块,作用于执行模块,即identity.vhdhe exentity.vhd文件中。如下图所示。从上图可看出,凡是涉及到数值计算和关系运算的指令的低三位均为001,而不涉及的则为000。该信号传到执行模块中用于判断是否更新状态寄存器。3.2 数据相关数据相关是指在执行本条指令的过程中,如果用到的操作数是前面指令的执行结果,则必须等待前面的指令执行完成,并把结果写回寄存器或主存之后,本条指令才能继续执行。此处采用设置专用数据通路来解决数据相关问题。但旁路技术并非一劳永逸。若前一指令为LOAD,而后一指令和它数据相关,如下图所示,当下一指令的执行阶段需要数据时,上一指令尚未给出,这种情况是无法用旁路技术来解决的。相关的类型有三种:1.2.3.主要用到的关键信号是m_wRegEn和w_wRegEn,主要使用是在数据相关检测模块forwardingentity.vhd中,在identity.vhd、exentity.vhd、memaccessentity.vhd中均有使用。具体的使用方法如下。相关的检测都置于“执行阶段”。信号wRegEn是寄存器写使能,SA,SB是寄存器组A,B口选择信号。信号前缀表示信号所处的阶段。如e_SA表示处于执行阶段的SA。1相邻指令数据相关的检测 若m_wRegEn=1,则表示前一指令要回写寄存器。此时,若e_SA或e_SB等于m_SA,则必然数据相关,这是因为我们规定,若回写寄存器,则寄存器A口选择信号所指定的即为目的寄存器。否则无关。2 中间隔1条指令的两指令数据相关的检测 若w_wRegEn=1,则表示第一条指令要回写寄存器。此时,若e_SA或e_SB等于w_SA,则必然数据相关。否则无关。当然,上述两种情况可能会一同出现。这时,我们就按情况1处理。因为情况2可以理解为接连出现情况1。下图为各个指令在译码时产生的wRegEn信号,可以发现凡是会写进寄存器的指令,该信号值都为1。3.3 结构相关由于在设计中不包含缓存,因此会有取指和访存的冲突,即结构相关。如下图:关键信号是wrMem信号,表示是否读写内存。具体出现在结构相关冲突检测与问题解决模块Hazarddetectentity.vhd中,产生于译码模块identity.vhd中。具体使用方法如下:1) 冲突检测只有执行访存指令(LOAD/STORE)时,才会出现冲突。因此,我们在译码时产生一个标志是否访存的信号wrMem。含义如下:wrMem意义00写内存(STORE)01读内存(LOAD)1不占用内存 表16 wMEM控制信号通过检查“访存阶段”的m_wrMem就可确定是否冲突。2)取指延后在每次取指时,若有冲突,则往IR中写入空指令(NOP),并保持PC不变,使取指延后一个节拍。4 各流水段功能和实现的详细分析4.1取指(IF)4.1.1 实现功能列表取指模块实现的功能是:l 给定内存地址,读取内存中的指令l 将指令送入指令寄存器,提供给下一级的译码模块l 实现控制相关冲突检测l 根据读取到的指令是否为跳转指令来更新PC4.1.2输入、输出信号分析主要输入信号:Z,C状态寄存器tempZ,tempCALU计算出的临时状态位,用于相关冲突检测e_setFlag状态寄存器写使能端,产生于译码时。决定是否在执行阶段根据ALU计算出来的结果改变状态位PCStall决定是否保持PC不变,由结构相关冲突检测模块产生IFFlush决定是否往指令寄存器IR里写入空指令,来自结构相关检测模块OuterDB内存读取过来的数据主要输出信号:PC_addrPC作为内存地址输出,用于下一节拍的取指d_PCInc1PC + 1d_IR指令寄存器输出 4.1.3功能实现逻辑通过分析控制信号我们可以大概了解到取指模块的功能实现逻辑是如何的。广义上来说,取指模块包括结构相关冲突检测模块,因为PCStall信号(用来实现IF段对PC的更新)和IFFlush信号(对IR写入空指令)就来自结构相关冲突检测模块。结构相关检测模块叫HazardDetectEntity,其模块图如下:其中输入信号的含义是:m_wrMemwrMem在访存阶段的值w_rwMemwrMem在写回阶段的值d_IR指令寄存器通过检测访存阶段的wrMem信号即可确定是否发生了结构冲突。每次取指后,若有冲突,则往IR中写入空指令(NOP),并保持PC不变,使得取指延后一个节拍。除此之外,setFlag信号在此处的作用是,决定用状态寄存器输出Flag还是ALU计算出的临时状态位tFlag来判断跳转。4.2译码(ID)4.2.1 实现功能列表译码模块实现的功能是:l 读取指令寄存器中的指令l 对指令进行译码,发送控制信号4.2.2输入、输出信号分析主要输入信号:d_IR从取指模块来的指令d_PCInc1从取指模块来的pc+1w_wbData写回数据,从写回模块里来w_destReg要写回的目标寄存器w_wRegEn寄存器写使能端主要输出信号:e_RAOut寄存器A输出值e_RBOut寄存器B输出值e_IMM立即数输出值e_ALUSrcALU输入端选择信号e_ALUOprALU运算选择信号e_SetFlag状态寄存器写使能信号e_wrMem访存信号e_wRegEn寄存器写使能信号e_destReg目标寄存器e_MemToReg内存写入寄存器使能信号4.2.3功能实现逻辑译码模块内部写好了根据不同的指令发送不同的控制信号的代码,采取一次译码,逐级传递的方式,译出后几级流水所需的控制信号和数据(如立即数)。在每次时钟上升沿到来时送入下一级。实际上,结构相关、控制相关、数据相关的检测都可归入译码部分。考虑到“相关检测”涉及到的信号分属不同阶段以及整体结构的清晰性,作者将“相关检测”独立出来。4.3执行(EX)4.3.1 实现功能列表执行模块实现的功能是:l 根据控制信号完成算术逻辑运算l 根据控制信号计算有效地址l 提供数据通道,将上一级传递过来的控制信号传到下一级4.3.2输入、输出信号分析主要输入信号:e_RAOut、e_RBOut、e_ALUSrc、e_ALUOpr、e_SetFlag、e_IMM、e_memToReg、 e_wRegEn、来自译码模块的控制信号forwardA、forwardB来自数据相关冲突检测模块的输出e_ALUOut上一个指令在执行模块产生的输出,作为下一条指令在执行模块执行的输入信号之一主要输出信号: m_SA、m_ALUOut、m_RBdata、i_tempZ、i_tempC、m_flag、m_wRegEn、m_memToReg、m_destReg、m_wrMem主要来自上一级模块传过来的控制信号4.3.3功能实现逻辑执行模块执行的功能很简单,和上个学期做的CPU综合性实验类似,主要是一些ALU逻辑运算和状态寄存器的更新操作。在这里还有向下一模块传递控制信号的作用。其中,forwardA和forwardB信号是来自数据相关冲突检测模块的信号。 模块图如下所示:作用是在发生读后写数据相关时,直接将计算好了的结果在写回目标寄存器时也发往下一条指令的执行模块作为ALU的输入之一。4.4访存(MEM)4.4.1 实现功能列表访存模块实现的功能是:l 根据地址线对内存进行读操作或者写操作4.4.2输入、输出信号分析主要输入信号:m_wrMem内存读写控制信号m_ALUOut来自ALU的输出结果m_RBdata要写回的数据PC程序计数器的值主要输出信号:w_wrMem传送到写回模块的内存读写控制信号wr读写控制信号addr要读取的内存地址OuterDB既可作为输入又可作为输出,用于传输数据4.4.3功能实现逻辑访存和取指在功能上是独立的,但是因为CPU对外只有一条地址线和数据线,因此访存和取指在实际上是有联系和冲突的。当执行Load/Store指令时,地址线由ALU送入访存段的值提供;取指时,则由PC提供。当写内存时,CPU内部数据送往数据线。当需要读内存时,CPU往数据线送高阻。4.5写回(WB)4.5.1 实现功能列表写回模块实现的功能是:l 选择写回数据源(来自ALU的输出还是来自内存)l 根据写使能信号wRegEn将数据写回到寄存器组4.5.2输入、输出信号分析主要输入信号: s_w_ALUOutALU的输出 s_w_MemOut内存读取的输出 s_w_memToReg决定写入寄存器的数据来源 s_w_flag要写进状态寄存器的值4.5.3功能实现逻辑此部分较为简单,即通过s_w_memToReg信号来决定是将ALU的输出写进寄存器还是将从内存读出来的数据写进寄存器。模块图如下:5 系统改造5.1新的指令系统汇编语句操作码功能描述指令类型ADD DR,SR0000DR+SRDR算术逻辑指令SUB DR,SR0001DR-SRDRCMP DR,SR0010DR-SR 比较AND DR,SR0011DR and SRDR 逻辑与OR DR,SR0100DR or SRDR 逻辑或XOR DR,SR0101DR xor SR DR 异或SHL DR0110逻辑左移,最低位补0,最高位移入CSHR DR 0111逻辑右移,最高位补0,最低位移入CMOVI DR,IMM1000IMM(立即数)DR,存立即数进寄存器数据传送指令MOV DR,SR1001SR DRLOAD DR,SR1010SR DRSTORE DR,SR1011 SR DRJR ADR1100无条件跳转到ADR , ADR=原PC值+OFFSET控制转移指令JRC ADR1101当C=1时,跳转到ADR, ADR=原PC值+OFFSETJRZ ADR1110当Z=1时,跳转到ADR, ADR=原PC值+OFFSETNOP1111空操作其他5.1.1选择改动说明包括NOP空操作指令在内指令系统共包括16条指令,在原有的25条指令的基础上删除了10条,新增了1条。具体地,删除了DEC,INC,TEST,SAR,PUSH,POP,JRNC,JRNZ,LOADH,LOADL,新增了一条数据传送指令MOVI。5.2修改的代码及说明1)代码段1,新增内存模块memory.vhd-内存-2015-10-30library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use work.unitPack.all;ENTITY memory ISPORT ( databus : inout STD_LOGIC_VECTOR(7 DOWNTO 0);-数据总线addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);-访存地址wr : IN STD_LOGIC;-读写控制信号reset: IN STD_LOGIC);END memory;ARCHITECTURE rtl OF memory ISSIGNAL ram:ram_type;-ram_type在unitpack.vhd文件里定义BEGINPROCESS(addr,wr,ram,databus,reset) BEGINIF reset=0 THENram(0) = MOVI & R0 & 11;-此处将程序写进内存中,省略ram(15) = JR & 1110;END IF;-读写功能的实现IF wr=0 THENdatabus = Z8;ram(conv_integer(addr) = databus;END IF; IF wr=1 THEN databus = ram(conv_integer(addr);END IF;END PROCESS; END rtl;内存模块使用vhdl编写,内存由ram组成,读出数据线和写入数据线为同一条数据总线,因此不能同时进行读写。因为这样所以会产生结构相关,即在取指的时候不可以访存,否则会产生冲突。内存读写功能由wr信号进行控制,当wr为0时执行写功能,当wr为1时执行读功能。2) 代码段2,取指模块ifentity.vhdop = IR(7 downto 4);-操作码取指令的高4位-控制相关信号e_setFlag,用于选择当状态寄存器的值来源with e_setFlag select ZZ = Zwhen flag_hold, tempZ when others;with e_setFlag select CC = Cwhen flag_hold,-由于跳转信号中只保留了JR、JRC、JRZ,因此此处只判断该3个OPs_selZ = 1 WHEN( op=JRZ AND ZZ=1) -判断是否跳转 OR op=JR else 0; s_selC = 1 WHEN( op=JRC AND CC=1) -判断是否跳转 else 0; PCIncSel = 1 WHEN s_selZ=1 or s_selC=1 ELSE 0; s_PCInc1 = PC + x01;-此处修改了PC位数 WITH PCIncSel SELECT-当有跳转时pc = pc + offset,否则pc = pc + PCnext = s_PCInc1 WHEN 0, PCPlusOffset WHEN 1, s_PCInc1 when others; process(reset,clk,PCStall)beginif reset = 0 thenPC = x00;-此处修改了PC位数 elsif FALLING_EDGE(clk) and (PCStall=0) then PC ALUResult := opR + opS; tempV := (not opR(7)and(not opS(7)and ALUResult(7) or (opR(7)and opS(7)and (not ALUResult(7); when aluSub = ALUResult := opR - opS; tempV := ( opS(7)and(not opR(7)and (not ALUResult(7) or (NOT opS(7)and opR(7)and ALUResult(7); when aluAnd = ALUResult := opR and opS;when aluOr = ALUResult := opR or opS;when aluXor = ALUResult := opR xor opS;when aluShl = ALUResult(7 downto 1) := opR(6 downto 0); ALUResult(0) := 0;cx := opR(7);when aluShr = ALUResult(6 downto 0) := opR(7 downto 1); ALUResult(7) := 0;cx := opR(0); -增加了aluMOVI的alu功能选择信号及其处理实现when aluMOVI = ALUResult := 00000&opS(3 downto 0);when others = null;end case; 修改了alu选择信号以及alu功能信号的判断逻辑,以及状态寄存器的判断逻辑,之所以修改是因为位数的修改。除此以外还增加了aluMOVI的alu功能信号及其对应的逻辑功能实现。1) 代码段1,译码模块identity.vhd新增了的WriteBack:process(reset,clk) -写回模块begin if reset=0 then-新增了初始化寄存器一步 RegArray(0) = x00; RegArray(1) = x00; RegArray(2) = x00; RegArray(3) = x00;elsif FALLING_EDGE(clk) and w_wRegEn=1 thenRegArray(wRegIndex) ctrl:=d_IR(3 downto 0)&10&1&1&001&0000&001;when SUBB = ctrl:=d_IR(3 downto 0)&10&1&1&001&0001&001;when ANDins = ctrl:=d_IR(3 downto 0)&10&1&1&001&0010&001;when CMP = ctrl:=d_IR(3 downto 0)&10&0&1&001&0001&001;-新增了MOVI指令及其译码出来的控制信号when MOVI = ctrl:=d_IR(3 downto 0)&10&1&1&101&1010&000; imm ctrl:=d_IR(3 downto 0)&10&1&1&001&0011&001;when XORins= ctrl:=d_IR(3 downto 0)&10&1&1&001&0100&001;when SHLIns = ctrl:=d_IR(3 downto 0)&10&1&1&000&0101&001;when SHRIns = ctrl:=d_IR(3 downto 0)&10&1&1&000&0110&001;when MOV = ctrl:=d_IR(3 downto 0)&10&1&1&011&0000&000;when LOAD = ctrl:=d_IR(3 downto 0)&01&1&0&011&0000&000;when STORE= ctrl:=d_IR(3 downto 0)&00&0&1&000&0000&000;when JR|JRZ|JRC = ctrl:=DoNothing; -若是JR*指令,计算offset,并向Exe插入Bubble offset ctrl:=DoNothing; end case;译码模块主要修改了控制信号ctrl的位数,并根据“SA, SB, Wrmem, wRegEn, MemToReg, ALUSrc, ALUOpr, SetFlag”的顺序增加了MOVI指令的控制信号,如下所示:when MOVI = ctrl:=d_IR(3 downto 0)&10&1&1&101&1010&000; imm = 000000&d_IR(1 downto 0);最后还增加了寄存器的初始化。6 测试与总结6.1 规则文件(cpu.txt的内容)6.2测试代码-程序1-指令正确性测试- R0R1R2R3ram(0) = MOVI & R0 & 11;- 3000ram(1) = ADD & R0 & 01;- 4000ram(2) = MOV & R1 & R0;- 4400ram(3) = SUBB & R1 & 11;- 4100ram(4) = SUBB & R2 & 10;- 41-20ram(5) = ADD & R2 & 11;- 4110ram(6) = ORIns & R1 & R0;- 4410ram(7) = ANDIns & R1 & R2;- 4110ram(8) = XORIns & R0 & R1;- 5110ram(9) = SHLIns & R1 & 00;- 5210;ram(10) = SHRIns & R0 & 00;- 2210;ram(11) = LOAD & R0 & R2;- R0的值为ADD & R0 & 01, 即0000 00 01ram(12) = CMP & R0 & R1;- CF = 1, ZF = 0ram(13) = JRC & 1111;- 跳转到15号地址ram(14) = MOVI & R3 & 11;- 如果跳转则不执行该指令ram(15) = STORE & R3 & R0;- 0号地址的内容变为 0000 0001ram(16) = MOVI & R0 & 11;- R0 = 3ram(17) = MOVI & R1 & 01;- R1 = 1ram(18) = SUBB & R0 & R1;- R0 = R0 R1ram(19) = JRZ & 1111;- 此处不跳ram(20) = JR & 0000;-此处跳6.3 测试结果测试环境测试程序测试结果五级流水Quartus程序1正确6.4 测试总结试程序的结果都与预期相符,证明测试结果是正确的。7 本课程设计的总结7.1 A同学总结由于上一学期在计算机组成原理的综合性实验中担当了主力队员,对cpu的基本组织结构也算是十分了解,因此该学期主动担当了组长。然而事实并没有那么简单,当第一次看到代码时发现,由于上次综合性实验大部分通过画图连线实现,逻辑功能十分明确,一目了然,然而该学期的cpu顶层实体是通过vhdl代码实现的,因此初期花了不少时间在了解代码的语法以及逻辑功能上,完成此步以后,我们组开展了对3种相关进行详细分析。弄清楚流水CPU的实现原理后,后续的修改工作就十分简单了。一开始我们是采用机箱+DebugController的方式进行调试,后来由于实验室的机箱资源有限,便再次采取了用Quartus的时序功能仿真来调试,并添加了内存模块。7.2B同学总结在此次课程设计中,我主要:参与修订指令系统;负责数据相关模块的修改;负责译码和访存模块的修改;负责MOVI指令的增加,主要是在常量定义文件unitpack里增加MOVI的op 码常量以及aluMOVI的alu功能选择信号,并在译码模块增加MOVI的控制信号及相关代码;负责扩展常量定义文件。在组长的组织下循序渐进,大部分不懂得问题都能够通过讨论解决。7.3 C同学总结在这次的计算机组成原理课程设计里,我负责的是:参与修订指令系统;负责结构相关模块的修改;负责执行模块和写回模块的修改;负责新顶层实体cpum.bdf文件的接线,主要是在创建了cpuentity和memory的bsf文件后,新建cpum.bdf文件并将上述两个原件加入,利用Quartus的接线功能将原件连接起来。26
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!