(本文为一个期末考试题,文中的图部分摘引自(美)David.patterson <<计算机结构与组成>>一书
第一章 32 位单周期RISC处理器设计
要设计一款处理器,首先要选择体系结构,本题选择的是RISC体系结构,因为它适合于流水线设计。然后需要选择一个标准的指令集,本题选择的MIPS指令集并按照常规的五段流水的方式来实现流水线。流水线的实现过程将在第二章介绍。
1.1目标处理器指令集与指令格式
本题目标CPU以能实现部分MIPS指令为目标,具体指令如下表1:
表1 目标CPU指令集
1.2 从指令具体行为反推设计方案
CPU要执行一条指令,不外乎需要完成以下几个过程:取指令,指令译码,将译码出的指令放到算术逻辑运算部件ALU上执行运算,根据ALU算得的访存地址进行访存和将访存的结果写回寄存器等。当然,不同的指令类型(R、I、J)可能经过的过程稍有不同,即它们的数据通路有所不同,以下将具体介绍:
1、 R格式指令数据通路:
1)从指令寄存器Instr MEM中取出指令,同时PC增值(即加1等待下个CLK到来);
2.)寄存器单元rs1和rs2的内容从寄存器堆Reg File中读出;
3.)ALU根据功能码Opcoder确定操作方式,对从寄存器堆读出的数据进行计算;
4.)ALU运算结果被写入寄存器堆,由rd确定写入的寄存器堆存储单元地址。
图1 R指令数据通路
2. I 指令(除lw、sw和分支指令)数据通路如图2:
1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);
2.)寄存器单元rs1的内容从寄存器堆Reg File中读出;
3.)ALU将从寄存器堆rs1单元中读出的数据与符号扩展后的指令低16位值相加;
4.)ALU的运算结果被写入寄存器堆,由rt确定写入的寄存器堆存储单元地址。
图2 I 指令(除lw、sw和分支指令)数据通路
3、Lw指令数据通路如图3:
1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);
2.)寄存器单元rs1的内容从寄存器堆Reg File中读出;
3.)ALU将从寄存器堆rs1单元中读出的数据与符号扩展后的指令低16位值相加;
4.)将ALU的运算结果作为数据存贮器的地址读出相应单元的内容;
5)把从数据存储单元取出的数据写入寄存器堆,由rt确定写入的寄存器存储单元地址。
图3 LW指令数据通路
4、Sw指令数据通路如图4:
1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);
2.)寄存器单元rs1和rs2的内容从寄存器堆Reg File中读出;
3.)ALU将从寄存器堆rs1单元读出的数据与符号扩展后的指令低16位值相加;
4.)将ALU 的运算结果作为数据存贮器的写入地址,把从寄存器堆rs2单元中取出的数据写入数据存储器中。
图4 SW指令数据通路
5)分支和跳转指令数据通路如图5:
分支和跳转指令主要控制PC的输入来达到分支或跳转的目的。
分支指令数据通路:
1.)从指令寄存器Instr Mem中取出指令,同时PC增值(即加1等待下个CLK到来);
2.)寄存器单元rs1和rs2的内容从寄存器堆Reg File中读出;同时主控制单元还计算各控制线应被设置的状态,具体状态表如表2所示;
3.)ALU将从寄存器堆读出的两数相减,同时把PC+1的值与符号扩展后的指令低16位值相加,其结果即为分支目标地址;
4.)根据ALU的Zero端口值和branch输出共同决定的PC的值:当Zero端口和branch的输出均为高电平时PC的值取第3步计算所得的分支目标地址,否则取第1步的PC+1值。
跳转指令数据通路:
1.)从指令寄存器Instr Mem从取出指令,同时PC增值(即加1等待下个CLK到来);
2.)主控制单元计算各控制线应被设置的状态,状态表如表2所示。PC+1的值的高6位[31~26]加上指令低26位([25~0])值组成跳转目标地址,根据主控制单元生成的Jump值决定是否跳转,Jump为1则PC的值取跳转目标地址,否则取其它地址。
此外,对于空操作指令,只要把jump、branch、memwrite、memread、regwrite均设为低电平,就可以保证该指令进行空操作,即执行没有任何效果的操作。
在理清各格式指令的数据通路后把它们综合在一起构成即构成目标CPU的总的数据通路,具体如图5。
图5 目标CPU数据通路
1.3 目标处理器的控制
处理器的控制主要为ALU的控制和主控制单元设计两个方面的问题。主控制单元的设计即为图5中Control Unit模块设计。处理器中除了控制ALU操作的opcoder(由主控制单元产生的ALUop和R指令功能码共同产生)和控制条件分支的信号(由主控制单元产生的branch和ALU运算结果Zero的与决定)外,所有控制信号都可直接由主控制单元根据指令的操作码字段来产生。具体对应关系如表2。
ALU的控制主要由图5中的ALU Logic模块产生。由表1中的指令以及它们在图5中数据通路可以看出,只有R和I类型指令运行需要ALU运算单元的参与,而且ALU需要完成的功能为:加、减、与、或、或非、小于置1和等于置1(Zero端口),而小于置1和等于置1也只需要对减法运算结果再进行一些组合控制而已,所以确切的说,ALU只需要能进行加、减、与、或、或非运算即可。由此得出的ALU控制位(ALU opcoder)和ALUop以及指令R型指令功能码之间的关系如表3。
到此为止,32 位单周期RISC处理器整体设计基本结束。从图5中可以看出,该处理器CPI为1,即每条指令执行的平均时钟周期数为1,即要求处理器要在一个时钟周期内执行完一条指令。对于像lw之类的指令,执行完一条指令需要5步,再加上时钟Set up和Hold延迟,那么一条指令的执行时间比较长,这就严重阻碍了CPU频率的提高,影响CPU的处理速度的提高。为解决此问题,将在下一章引入流水线处理。
第二章 带五级流水线的32 位RISC处理器设计
上一章谈的是32 位单周期RISC处理器设计,其中并没有引入流水线。为了提高处理器的处理速度,本章将在上一章设计的32 位单周期RISC处理器的基础上做一些改进(保持控制真值表不变,增加4个寄存器),添加成5级流水线。对于在流水线执行中常碰到的3种流水线冒险,本设计将不做考虑,而全部由软件编译器来处理,不占用硬件资源来解决这些问题。
流水线带来的性能提升是通过增加同时执行的指令的数目从而提高处理器的吞吐率来完成的,五级流水线意味着在任何一个单时钟周期内,最多有五条指令会位于流水线中。因此,在把上一章中图5的数据通路基础上增加五级流水线时必须把数据通路也分为五个部分。上一章曾说过,CPU要执行一条指令,不外乎需要完成以下5个过程:取指令,指令译码,将译码出的指令放到算术逻辑运算部件ALU上执行,根据ALU算得的结果进行访存和将访存的结果写回寄存器。由此CPU内部的动作被很自然的划分成取指(IF)、译码(ID)、执行(EX)、访存(MEM)和写回(WB)5个部分,如图6所示。从图6中可看出,在这些中左到右的指令流中有3个例外,就是写回阶段、分支地址选择和跳转地址选择,这些从右到左的箭头会导致数据冒险和控制冒险。同时为了保持一条指令路径执行的完整性,需要使流水线中的各条指令保持各自的值,所以必须在各级之间加上一个寄存器来保存该级中运算的结果,到下个时钟到来时把数据传给下一级进行运算,例如图6中的IF/ID、ID/EX、EX/MEM、MEM/WB模块,它们都是作为流水线寄存器加入的,PC也可以看成流水线中的一个寄存器,用它们来完成这样一个保存的功能。图6中,WB为2位,分别是memtoreg/regwrite,M为4位,分别是jump/branch/memread/memwrite,EXE为5位,分别是ALUsrc/regdst/ALUop。
如图6五级流水线数据通路
指令运行时在流水线数据通路中经过的五个步骤如下:
1.)取指令(IF):利用PC中的地址从指令寄存器中读出数据,然后将指令存入IF/ID流水线寄存器中,在IR段即0~31位;同时把PC+1后的地址NPC也存入IF/ID流水线寄存器中,在NPC段即32~63位。所以IF/ID寄存器为64位。
2.)指令译码与读取寄存器堆(ID):把从IF/ID流水线寄存器取出来的指令进行译码,由其31~26位(指令的操作码)产生控制位WB(memtoreg/regwrite)、M(jump/branch/memread/memwrite)和EX(alusrc/regdst/aluop)并存入流水线寄存器ID/EX的174~164位,从寄存器堆中读取2个操作数据并存入ID/EX的105~74和73~42位,同时把其他以后用到的数据也存入ID/EX中,如图6。
3)运算模块(EX):主要执行数据运算和分支、跳转地址计算。数据运算是指ALU根据opcoder的控制位执行相应的算术逻辑运算,同时把运算结果存入EX流水线寄存器(37~69)作为下级数据存储器的地址或返回寄存器堆的运算结果;同时计算分支地址和跳转地址并存入EX流水线寄存器(70~101位 和102~133位),同时相应的把M、WB等数据也存入EX流水线寄存器以便后面使用。
4)访存模块(MEM):一则起传递作用,把ALU运算的结果存入MEM流水线寄存器(5~36);二则访存,把ALU运算的结果作为地址从数据寄存器中取出相应的数据并存入MEM流水线寄存器(37~68),同时把上一级中的信号WB和WS存入MEM流水线寄存器以便流入下一级;在这一级中还要把分支地址和跳转地址连回IF模块。
5)写回模块(WB):以MEM流水线寄存器中的低5位WS为寄存器堆写入地址,根据控制信号memtoreg来选择把MEM流水线寄存器5~36或37~68位数据存入寄存器堆中。
到此,流水线的加入工作完成,此处理器的处理速度理论上为没有流水线的处理器的5倍。
第三章 五级流水线的32 位RISC处理器RTL级实现
本课题采用VHDL语言描述,开发工具是Xilinx ISE7.1,采用modelsim6.0进行时序仿真,用ISE7.1自带的综合工具进行综合。
3.1顶层模块设计
按照图6所示,把CPU顶层分为取指(IF)、译码(ID)、执行(EX)、访存(MEM)和写回(WB)五个模块,它们之间的连接关系如下图7。为了方便监控流水线运行进程和观察输出结果,本课题引出了4个输出端口。
图7顶层模块设计
3.2 CPU模块的RTL设计
按照图6所示分别进行5个模块的底层设计,各模块输入输出端口定义如图7。其他模块设计都比较简单,所以本文只重点介绍EX模块里面的CPU核心运算模块——ALU的RTL实现过程。
算术逻辑单元(ALU)能实现32位的加、减、与、或、异或、小于置1和等于置1的功能。ALU黑盒和opcoder功能定义分别如图8、表4,其中a、b为32位输入操作数,result位32位运算结果,zero为1位输出,为beq指令专用:当a=b时,zero=1,否则为0。
为了加快加法和减法运算的速度,本设计将采用超前进位进行设计。同时为减少复杂度,部分采用行波进位进行设计。具体为:用2个16位超前进位的加法器串联构成32位加法器,而16位超前进位的加法器则采用两级抽象的快速进位设计,使得运算速度比全部用行波进位快大约6倍。图9为使用4个4位超前进位ALU构成的16位超前进位ALU(即第2级抽象的快速进位)。
其中,C0为表1中carryin的值,C1、C2、C3求法如下:
C1=G(0) + (P(0) · C0);
C2=G(1) + (P(1) · G(0)) +( P(1) · P(0) ·C0);
C3=G(2) + (P(2) · G(1)) +(P(2) · P(1) · G(0)) + (P(2) · P(1) · P(0) ·C0);
而P(0)=pi(0) · pi(1) · pi(2) · pi(3); P(1)=pi(4) · pi(5) · pi(6) · pi(7);
P(2)=pi(8) · pi(9) · pi(10) · pi(11);
P(3)=pi(12) · pi(13) · pi(14) · pi(15);
图9 4个4位超前进位ALU构成的16位超前进位ALU
G(0)=gi(3) + (pi(3) ? gi(2)) + (pi(3) ? pi(2) ? gi(1)) + (pi(3) ? pi(2) ? pi(1) ? gi(0));
G(1)=gi(7) + (pi(7) ? gi(6)) or (pi(7) ? pi(6) ? gi(5)) + (pi(7) ? pi(6) ? pi(5) ? gi(4));
G(2)=gi(11) + (pi(11) ? gi(10)) + (pi(11) ? pi(10) ? gi(9)) + (pi(11) ? pi(10) ? pi(9) ? gi(8));
G(3)=gi(15) + (pi(15) ? gi(14)) + (pi(15) ? pi(14) ? gi(13)) + (pi(15) ? pi(14) ? pi(13) ? gi(12));
对于pi和gi,有两种情况。当opcoder=“0110“和”0111“时,gi=a与(/b),pi=a 或(/b);否则,gi=a 与b,pi=a 或b;
而4位超前进位ALU的设计与此雷同,只是C1,C2,C3的计算有些不同而已,这里不在说明。
下面重点介绍构成4位超前进位ALU的1位ALU的设计过程。本设计ALU需要实现加、减、与、或、异或、小于置1和等于置1的功能。小于置1和等于置1在ALU中都将进行减法运算。对于小于置1(opcoder=0111),它的结果为32位,其中最低位等于32位减法运算中的最高位,其余为0;对于等于置1,它的输出为zero端口,为1位,当32位减法结果为0时,zero=1,否则为0。这两个功能将在把2个16位超前进位的ALU串联构成32位ALU时定义,所以1位ALU 只需要考虑加、减、与、或、异或5个功能即可。具体实现电路和对应的控制表如图10、表5。
图10 1位ALU的电路图 表5 功能控制表
第四章 设计验证
本课题的测试验证计划如下:运行32条指令(包含全部的操作数),观察4个输出结果,运行结束后查看寄存器堆和数据存储器中保存下来的数据是否是预期数据,通过这个过程初步验证CPU功能和行为的正确性。指令和预期结果如表6。
表6 测试指令和预期结果
图11 流水线寄存器输出
图11为4个流水线寄存器的输出结果。通过监控这4个输出结果,很方便的对程序进行调试,因为每个线寄存器完整的记录了一条指令通过该级生成的所有数据和信号,而且固定了存储位置,如图6所示。图中1、2、3为三条指令在4个寄存器中的运行过程。
通过modelsim仿真后本课题最后寄存器堆和数据存储器数据分别如图13和图12所示。
图13寄存器堆运算结果
从图12、图13可以看出,CPU运算的结果完全符合预期情况,按照以上方法设计的CPU是正确的。
原文地址:http://wrw8167.blog.163.com/blog/static/5752525020093191733789/