基于RISC-V参数化超标量处理器的优化设计

2022-04-09 07:02刘有耀潘宇晨
计算机工程与应用 2022年5期
关键词:流水线寄存器分支

刘有耀,潘宇晨

西安邮电大学 电子工程学院,西安 710121

目前嵌入式领域市场具有很大的发展前景,但一直以来基本被ARM系列处理器占据。RISC-V是由加州大学伯克利分校(UCB)提出的一种开源精简指令集架构[1-4],作为一个新生的开源指令集架构,具有精简、模块化设计、开源等优点,可以根据需求定制自定义customer指令[5],大大简化了处理器的设计,也因此涌现了很多优秀的开源设计[6]。目前开源的RISC-V处理器大多偏向于低功耗的嵌入式设计,例如E203、SCR1、PicoRV32和RI5CY等内核均为标量处理器。其设计的流水线阶段相对较短,专注于低功耗嵌入式区域。PicoRV32是一个精简的紧凑型内核,能够顺序地处理每条指令,因此其平均IPC为0.25。在高性能开源处理器中,代表性设计有BOOM处理器[7],能够参数化地定制各级流水线以及缓存的配置。但是其语言编写采用了较为激进的Chisel[8]语言进行编写,编译生成所得,因此属于机器生成代码,具有更好的可扩展性与可重用性。但是其人工可读性比较差,学习曲线又非常陡峭,学习成本比较大。

在嵌入式微处理器设计,低功耗处理器一般采用简单的单发射、顺序执行、写回的策略进行成本和性能的压制。在较高性能处理器中,其主要的核心思想是通过指令级并行(instruction level parallelism,ILP)[9]来提升处理器的执行多条指令的性能。在多发射时,采用分组式保留站对待发射指令进行暂存,再进行运算。执行完提交相应的提交请求进入重排序中缓存[10],其乱序处理的机制可以大大提高处理器的性能[11]。

缓存和执行单元的配置可以在一定程度上能够代表处理器的性能。充足的缓存与运算单元可以保证流水线不被大量气泡操作占用,最大程度上发挥多发射和乱序写回的性能。

可执行单元是由算术逻辑单元(ALU)、乘除法单元(MDU)等其他专用运算单元构成,单元的数目可以直接提高处理器的性能,但也同时会带来功耗收益的递减。在处理器设计中,不同运算单元是处在同一级流水线上并行运算,向后级缓存写入数据。对于不同单元的不同指令来说,需要为其分配不同的保留站进行数据相关性检测,且长周期执行单元会阻塞短周期执行单元的提交,造成处理器执行单元的空闲操作。

缓存在超标量处理器中充当着保证发射和写回的顺序严格按照程序本意的指令顺序执行。一些处理器的指令分派的机制采用了一种物理寄存器文件,重命名表和重排序提交缓冲区的数据结构。将传统的重命名寄存器堆合并到提交缓冲区中,并使重命名表分离。在配置的6个保留站(reservation stations,RS)中,获取用于每一个功能单元在下一执行阶段获得的基本操作数和功能代码,并通过比较调度指针识别最早发出的指令[12]。但是对于分布式保留站在指令发射时具有利用率低的特点,且若发布4条分支指令,需要构建五个检查点来支持未命中预测恢复,这会带来复杂检查控制机制。同时,也有一种以非推测方式进行的派遣提交被提出,从而避免了检查点。用验证缓冲(validation buffe,VB)结构替换了传统的ROB(reorder buffer,ROB)[13]。这种结构会保持已分派的指令,直到它们成为非推测性的或被推测性的为止。但是这种结构并没有区分长端周期指令在写回阶段的不同,由于指令执行时间的不确定性,该结构只能将load/store指令单独派遣,同时需要将不同的指令追踪,分离为Pending_Readers、Valid_Remapping和compile这3种状态,提高了各模块之间互联的复杂度。和在较多运算单元时,提交给缓存的请求也越多。为了使在指令提交时减少阻塞的发生,在流水线访存写回阶段将缓存划分为指令类型、目标和存储缓存结构。这种流水线方案,能够将ALU算数逻辑指令与load/store指令进行分类提交[14]。但是在指令的派遣时并未考虑到系统指令以及不定周期的指令对处理器的影响,其设计的缓存模块大量集中于流水线的末尾阶段,缓存无法匹配到各级流水线,可能导致处理器上限频率降低。循环迭代的方式检测寄存器的相关性的方式,提高了处理器的动态功耗,且在锁存队列满时测出store指令时,最差情况下只能发射一条指令。

面对嵌入式多种复杂的性能需求时[15],需要一种能够快速可配置的流水线结构胜任不同的需求,并解决各级流水线的吞吐匹配问题。在此问题基础上设计了一种优化后的基于RISC-V的参数化超标量处理器。处理器中的缓存分布在处理器的各个流水线阶段,既可以取代流水线寄存器,对RISC-V处理器指令分类处理,直连化各级缓存接口,降低时延,同时扩展了可驻留指令的上限。同时采用单周期运算单元与长周期运算单元级联,同类执行单元并行执行的方式,可以使数据流先通过ALU简单计算,再流入后级执行单元,缓存结合了集中式与分布式保留站的优点,既可以达到前级单元的高效利用,又可以通过可配置后级[16]流水模块,达到自由调整数据吞吐率的平衡。在对面积极端要求条件下,可仅配置一条32 bit指令的缓存容量与单个处理单元,达到对面积的折中。但是由于数据相关性的存在,以及cache位宽大小的限制,无限制地提高缓存大小与执行单元的数量也只能带来有限的性能提升与大量的功耗。因此,本设计更倾向于面向嵌入式领域的定制化CPU的优化实现。

1 处理器架构

本设计中设计了一种面向嵌入式的变长4级流水线结构,即“取指”“派遣”“执行”“写回”,对派遣阶段进行了两次派遣处理,具有可配置各级流水线、乱序执行、乱序写回的特点。

处理器缓存可分为以下几类:指令接收来自指令存储器或cache中的指令,同时承担来自跳转与分支指令预测后的指令拼接区域;一级派遣缓存可以直接在派遣时得出寄存器的状态,对系统指令采取特殊通路,对于算数类型且无相关性的指令可以立即发射;寄存器缓存在写回阶段需要考虑其提交顺序[17];二级派遣缓存对乘除法与存取指令缓存后,合并其向重排序缓存的请求,对于多个乘除法和一个访存模块,可以复用一条指令提交通路。

处理器可执行单元可分为:ALU与乘除法单元,可以根据实际应用做到参数化可配置。

1.1 流水线结构

处理器整体数据通路如图1所示。其中,指令缓存(instruction buffer,IB)来自指令存储器中的指令,同时也是分支跳转指令的拼接缓存区。预测单元采用局部历史分支预测器(local history),将每条分支指令的执行历史结果移入历史分支寄存器(branch history register,BHR),通过历史执行的情况对其进行预测(predict)[18]。来自一级派遣缓存(dispatch buffer,DB)和二级长指令派遣缓存(dispatch long instruction buffer,DLIB)共同组成长短指令的派遣缓存。DLIB不仅充当了存取指令的缓冲等待区,也是乘除法指令再派遣和运算结果的暂存。DLIB在释放一条长指令时,同时可向RB与DB更新指令列表信息,同时提交多个ALU指令。更新指令列表信息和当前退休指令数量有关,提交指令的数量与当前无数据相关的指令条数有关。

图1 整体架构设计图Fig.1 Total frame

设计中采用了多个参数化的缓冲模块来处理流水线中的各阶段的数据的缓冲问题。可设置每一级缓存的接口数量和大小,面向不同的设计选择性能与面积的折中。同时对(MUL/DIV unit,MDU)模块采用级并联复用长指令提交缓存的方式,进行多级派遣。可提供多个MDU单元同时运算,减少端口的复杂度,降低流水线阻塞的概率,而面积开销可以依据需求的MDU模块以及特定的程序优化,并不会很大。

本设计将RISC-V指令分为分支跳转、ALU指令、系统指令、长周期指令等,利用对应的控制与缓存模块进行缓存处理。在取指阶段可适应CPU外部存储位宽进行指令缓存,同时对缓存的指令调用预译码模块和分支预测模块对指令进行预测合并缓存。在派遣阶段将指令划分为ALU指令、特殊指令(分支跳转、环境调用、非法指令等)和长指令进行相关性检测后进行分派处理,送入不同的执行模块。在执行阶段,长、短两类指令分别在不同级流水线内处理。普通的ALU指令结果,提交给寄存器缓存(regfile buffer,RB)处理。存储指令和乘除法等指令,提交给二级长指令派遣缓存(dispatch long instruction buffer,DLIB)进行再派遣处理。对于DLIB,采用分离派遣的方式与乘除法进行数据交换,属于两类指令混合的多级派遣机制,以提高并行性。

1.2 超标量实现

RISC-V指令集相较于ARM和MIPS指令集更为精简,可以大大简化硬件架构的设计。

为确保每一级指令能够源源不断送入后级,将每一级的流水线寄存器替换为对应的缓存,如取指译码阶段为指令缓存(IB),译码执行阶段为派遣缓存(DB),执行和访存阶段为长指令派遣缓存(DLIB),写回阶段为寄存器缓存(RB)。

在取指阶段,根据RAM或Cache总线位宽,进行配置。在缓冲器的剩余空间大于读数据的位宽时,会自动发起读指令的操作,以求填满缓存。缓冲器的输出为已成型的指令。由于本设计支持RISC-V压缩指令集,指令长度可能是16 bit或32 bit,指令数目也不固定。因此输出的比特数是16的倍数。每次取指时,将已保存在缓冲器的比特和刚从指令存储器进入的比特,这两者按照前后顺序连接在一起,作为译码的对象。

在译码派遣阶段,译码多少条指令由下一级的需求决定。若下一级可以接受N条指令,则从IB中调用译码模块尽量生成N条译码结果。RISC-V规整的指令格式可以通过bit[6∶0]7位操作码(opcode)直接得出指令类型,通过功能码(func)得到需要具体执行的操作。对于操作数的获取,在派遣缓存内采用两个黑名单,分别是Rs和Rd黑名单。让每一条候选指令对照这两个黑名单,当发现Rs和Rd任意一个处于黑名单上,此条指令则不能进入选中序列,应被推移到下周期等待执行。同时每个周期需要对Rs、Rd黑名单进行更新,考察这条指令当前的状态下会影响那些操作数索引。只要当前指令不在此黑名单,即可越级发射派遣。

在执行阶段,ALU、乘除法和LSU(计算地址)共同写入长指令缓存(DLIB)中。此级缓存是逐步实现ALU指令的写入权限的。

以图2留存于缓存中的指令序列举例。其中ALU0、ALU1、ALU2、ALU3送入RB缓冲器,MUL0、MUL1和LSU0送入DLIB缓冲器。ALU0有权限写入寄存器组,但ALU0和ALU1却不能写入。在MUL0指令并没有成功执行时,寄存器组可以通过缓存器恢复到lsu0指令执行之前的状态。一旦LSU0指令成功执行,寄存器缓存(RB)则允许放开此指令之后的ALU1和ALU2指令的寄存器写入权限,和ALU0享有同等待遇。若MUL0异常,或未执行完毕,RB则不允许其写入寄存器,实现了指令的精确异常。因此RB会配合DLIB的执行结果,退休一批ALU指令。

图2 缓存指令序列Fig.2 Instruction sequence

在写回阶段,只有在外部存储返回了响应信号,store指令状态才被判决执行完毕,同时在执行期间记录索引,避免load指令访问该外部存储的地址空间。

1.3 互连线结构

每一级缓存的端口数目、位宽由参数决定,每一级缓存接口将必要的数据信息互联,并不需要复杂的公共数据总线,减少了握手所带来的时序损耗。后级缓存需要向前级缓存发出自己的空满信号[19],以确保流水线的正常运行。在长指令处理的互联情况中,采用多级派遣方式,逐级缓存上级的译码包、操作数或访存地址,因此可以提前在二级缓存DLIB刚缓存乘除法指令时即开始运算,提高并行性。DLIB向DB与RB缓存之间提交退休的长周期指令数,其自身也可以同时移除多条长指令,移除的指令结果直接写入RB内的寄存器组。ALU指令可以直接使用长指令的数据通路,但只由RB进行退休。因为ALU指令并不能随时写入寄存器组。在长指令出现异常的情况时,寄存器组不能让该条异常指令之后的指令写入。系统模块(SYS)和指令缓存器(IB)之间互联,控制系统指令和地址跳转等指令的操作。处理器中缓存与运算单元直接的互联结构直接的功能可以用简单的互联图3来表示。

图3 互联数据图Fig.3 Interconnection data graph

1.4 可配置化

四类缓存的基础可配置参数如下,输入位宽,输出位宽与暂存位宽。位宽均为2n次幂。如位宽为128 bit,可容纳4条32位指令与8条16位指令。

指令缓存中可配置最小指令位宽以支持压缩指令集,为了处理多个分支指令,支持可配的预测指令的暂存位宽,在分支预测失败时,可直接从缓存中读取正确指令。每个分支指令在进入分支暂存缓存后,它后续的指令也能放行进入后级的缓冲器。

分支预测单元的可配置参数为局部历史分支预测器(BHR)位宽,最高可配置为5 bit。当配置为2 bit时,即为2比特饱和计数器,提供基础的分支预测能力。

可执行单元的配置参数为级并联单元的个数和与其连接缓存接口个数。当配置ALU个数为3时,MDU为2,指令长度为32时,一级派遣缓存接口位宽可以自适应位宽配置为指令长度乘以ALU单元数(XLEN×ALEN,32×3=96 bit)。同理,长指令派遣缓存接口的位宽为2个MDU加上1个LSU模块的位宽也为96 bit。

以上参数均通过以Makefile脚本宏的方式进行写入编译,以实现简便化的定制流程。

2 处理机制

2.1 两级派遣

指令缓存器(instruction buffer)连接译码模块,将RISC-V指令划分为长周期指令、算数指令、跳转指令、特殊/系统指令(CSR寄存器指令、非法指令、栅栏指令等)。对于无条件跳转指令直接进行拼接指令缓存;分支指令等待预测结果,Jalr指令等待Rs寄存器结果,拼接指令缓存;CSR寄存器操作指令,直接进行寄存器操作;Fence指令暂停取指后,等待派遣模块接收;最终只能有运算指令可以进入一级派遣缓存。在指令缓存器中,只能有一条跳转指令或者特殊/系统指令被执行。由于这些指令的特殊性,导致了必须严格按照指令顺序,在其他指令执行完毕后,才能交付。跳转和分支指令,是一种具有ALU属性的指令。跳转之后将新指令进行拼接并不影响后续的指令流的运行。

DB缓存接收上级缓存器送来的ALU、存取、乘除法指令。DB缓存会通过直接互联监听寄存器的占用信息以及后级缓存、运算单元的空闲信息。对指令进行相关性检测,对没有冲突的指令进行派遣。派遣乘除法时,进入长指令缓存模块,单独对其再派遣和结果回读。派遣机制流程如图4所示。

图4 派遣机制流程图Fig.4 Dispatch mechanism

2.1.1 ALU派遣执行机制

ALU指令派遣的条件如下:(1)RB缓存有剩余空间;(2)ALU运算单元有空闲;(3)相关性检测通过。

满足一级派遣的指令进入ALU执行阶段,剩下的按照顺序留存在一级派遣DB内。在下一个周期到来时,保存在DB缓存内的指令优先进行判断派遣。每个ALU数据通路传送的是经过译码打包后的数组,包含了指令的功能码,操作数等信息。ALU计算后的数据分为两种情况:(1)正常的ALU指令结果,写回到RB中。(2)计算出MEM指令的地址,打包MDU指令送入到DLIB中。

2.1.2 长指令派遣执行机制

将原有与ALU同级的多周期MDU单元后移,其运算结果与数据存放于原有的MEM指令缓存器中,合并为长指令缓存器。在合并后的再派遣缓存中,存放着排序好的等待退休的存取指令和乘除法指令。当有长指令需要退休时,依据序号和ALU指令一同送入RB中,由RB在进一步的仲裁写入结果。

LSU/MDU指令被派遣的条件如下:(1)二级DLIB缓存有剩余空间;(2)在先前的指令周期内有LSU/MDU在第一级派遣缓存模块未被发射,先发射一级派遣缓存的指令。在本周期进入的LSU/MDU指令应保存在一级DB缓存中等待派遣。对于执行时间不定的指令,不能有后级指令超越前级指令的行为。

执行分别在两类数据通路内处理。ALU接收从派遣模块送来的指令,并再次将指令分成三类:算数指令、存取指令、乘除法指令。算数指令直接在ALU内完成运算,送给RB进行重排序评估。MEM指令和乘除法指令混合送入二级DILB进行缓存。

因为这三种指令的执行阶段不一样,故称之为变长流水线结构。在执行乘除法指令时,由于DILB缓存是第二级派遣单元,已经保存了之前存储的和指令类型和操作数的缓存元素,因此可以提前在DILB缓存刚接收乘除法指令时即开始运算。

复用结构执行操作如下:(1)当有长指令进入二级派遣缓存时,通过功能码检测其指令类型,并根据类型进行序号若是MEM指令交给LSU处理,若是MUL/DIV指令交给MDU处理。(2)若是MEM指令,检测LSU单元是否被占用。占用时在Buffer中进行等待调度,空闲时进行内存读写操作,序号(order)进行加1。在二次派遣和指令提交时,序号自减,只需提交统一的结果即可。(3)若是MUL/DIV指令,检测MDU单元是否被占用。查询送入的指令序号(md_ord=n),取出缓存中暂存的操作数和功能码送往动态分配的MDU。同时准备下一条指令的序号(md_ord_next=N)。直到读出下一条N为缓存的最高容量,说明无需要处理的指令。与MEM指令不同的是二级派遣缓存可以对应多个MDU单元同时运算。通过与运算单元直连的简单握手信号进行通信,存储来自MDU的运算结果,待下一个周期送入REB进行写入寄存器。

两种指令可以混合缓存来自上级模块下发的指令。缓存的指令参数段存放指令的类型、Rd索引号、有效标志和功能码。若是乘除法和load指令,Rd为结果或加载的目的寄存器。若是store指令,则为全0。其中long_addr来自load/store指令的地址或者是乘除法的一个操作数。long_wdata存储来自store指令的Rs2或者是乘除法的另一个操作数。

其具体行为操作如图5所示。

图5 长指令派遣Fig.4 Long instruction dispatch

通过此部分二次派遣的方法,一方面减少互联复杂度,只需发送整体的提交信息,使一级调度缓存和RB等模块直连的信号大大缩减。同时重用了DILB的缓存空间,相当于增加了MDU的缓存大小,使运算单元不容易受制于缓存大小而造成流水线阻塞。对于改进后的面积开销,只会增大因需要存储MDU返回结果的资源。

2.1.3 长指令派遣执行机制

特殊指令可以分为这两类:error、illegal、sys、fencei、fence、csr系统非法类和branch、jalr、jal正常跳转类。这些指令会在指令缓存中进行处理,系统等指令会在下一级派遣缓存DB之前,送给SYS模块进行跳转到异常程序入口或进行csr读写操作。

sys模块会实现CSR寄存器的相关读写操作,它是处理系统指令和CSR指令并控制整个CPU状态的模块。sys模型在对CSR寄存器进行处理时。一般会涉及到系统跳转,会取到一个新的PC地址进行取指。同时会有清除所有缓存内指令的操作。

跳转指令会将下一条指令直接进行拼接,分支指令根据预测的结果觉得是否需要进行拼接。当分支指令的缓存清空时,且下级缓存被清空时(正常指令执行完),可以执行系统指令。送往DB缓存的将只有算术存取指令的功能码(func)和对源操作数和目的操作数的索引号(index)。

为了管理经过预测执行的指令,为每一条指令设置一个预测真实梯度grade。grade表示当前指令前有多少条分支指令未给出实际的结果。带不同grade标准的指令允许进入后级流水线。当一条分支指令被确认预测正确,那么grade等级会自动减1。只有grade等级为0的指令可以进入寄存器堆或写入mem中。如图6所示,只有ALU0和ALU1指令允许写入寄存器堆中。

图6 预测指令真实梯度Fig.6 Forecast true grade

2.2 重排序写回

RB缓存主要负责存储来自ALU、DLIB、CSR指令中需要的寄存器堆数据。RB缓存中内嵌了32个RISC-V标准寄存器组,因而可以方便地对其进行操作。同时RB也为DLIB设置了专门访问通用寄存器的接口,方便ALU指令再排序后能够在长指令提交后同时写入寄存器。ALU送来的数据夹杂着存取指令的地址,RB仲裁器需要仲裁出来自ALU的算数指令,将其写入缓存并分配序号。每新来一个MEM指令时,对序号加1,若是ALU指令,则不变。每个周期进行评估,对序号等于0的数据才允许写入寄存器堆。序号大于0的,只能保存在RB的缓存器内。如果发生序号为1的MEM指令发生了异常(MEM指令必须严格顺序读写,所以只有序号为1才能进入读写序列),只需要清除包括序号为1之后的数据即可。保证了寄存器堆的数据正确,同时可以精确定位异常指令。

若MEM指令正确执行,则RB中的序号自动减1,允许新数据写入寄存器堆。这种分类隔离的方式避免了MEM指令异常而导致的数据错误提交。同时对于后续指令取用寄存器堆内数据时,不仅要从寄存器堆内取用,同时还要从RB缓存中取出进行比对。对于不同的数据,以RB缓存中的数据作为基准,这保证了运算单元索引的寄存器中的数据是被正常提交所得的。

3 实验结果及分析

指令集验证采用RISC-V社区开源的指令集自测试程序。该测试程序用汇编语言编写,属于指令兼容性测试。该方法通过循环计数,检测寄存器的值来判断测试是指令集架构中定义的指令是否符合RISC-V的标准。使用自测试下,处理器通过了RISC-V的IMC(整数、乘除法、压缩)指令集的测试。

在128 bit的取指位宽情况下,对不同发射数的缓存进行了匹配,评估了不同缓存接口数与大小下的性能,同时运行了CoreMark与Dhrystones的跑分测试。Dhrystone用于衡量处理器的整数运算处理性能,比如数据的赋值、间接指针函数调用、赋值等常见操作,有是否选择编译器优化两种情况。CoreMark程序包含了常见的矩阵运算、链表操作、状态机和循环冗余校验(CRC)等算法。这些测试程序都能较好地衡量处理器的性能。

可配置性,是通过Makefile脚本中sed命令,直接修改define.v文件中相应的定义来实现。在定义文件中,可定义的选项有指令缓存、派遣缓存、长指令缓存、寄存器缓存大小、ALU单元、MDU单元和分支预测位宽。如:直接sed修改`define MDU_NUM为2。

为了能够更加简便化实现对应测试环境的性能测试,在配置选项中加入了launch选项(编译器优化),分别对应该发射数在对应测试程序下的最优配置。

处理器性能主要依赖于合成基准测试程序进行评估。在不同基准程序中IPC可能会有所差异。在处理前和后分别采用modelsim仿真记录运行程序的时间,取平均,可以得到各个配置下的IPC。

下列配置是在Dhrystones和CoreMark测试程序对乘除法分析后进行最优配置。若目标程序采用此类运算较多,可直接进行增加,所以此设计更倾向于嵌入式领域中运算指令密集型的应用处理。

1发射:ALU:1,MDU:1,IB缓存:2,DB缓存:2,DLIB缓存:4,RB缓存:4。

2发射:ALU:2,MDU:1,IB缓存:3,DB缓存:4,DLIB缓存:8,RB缓存:8。

3发射:ALU:3,MDU:2,IB缓存:5,DB缓存:7,DLIB缓存:14,RB缓存:14。

4发射:ALU:4,MDU:2,IB缓存:6,DB缓存:8,DLIB缓存:16,RB缓存:16。

5发射:ALU:5,MDU:3,IB缓存:8,DB缓存:10,DLIB缓存:20,RB缓存:20。

图7测试表明,不同发射数对性能的影响是巨大的。但随着发射数的提升,处理器的性能增益也会有所降低,这主要是由于指令的相关性约束所导致的[20]。在这几种跑分场景中可以发现3发射的配置占优。越高的取指位宽和运算单元可以显著提升处理器性能。

图7 不同发射数下IPCFig.7 IPC with different emission numbers

为了支持取指,cache的功耗与面积代价会不可避免地增加[21],但是本设计理论上可以灵活地对接不同的存储取指位宽,加上不同的运算单元和发射数目,达到性能与面积的平衡。

在采用三发射的配置,即ALU:3,MDU:2的基准,表1为在TMSC 28HPC+工艺综合和FPGA实现两种派遣指令内核的配置,即在相同运算单元数目下,分别采用基准程序测试了在MDU与ALU同级流水线与缓存复用派遣下的性能。用不同模式下的平均跑分与逻辑单元数目的比值,Average Cells/IPC,作为一个评判依据。值越低,其单位性能下所占用的数目越少。在采用复用派遣后,因需要缓存从MDU来的指令,需要适当增大DILB缓存提升性能而带来一定面积开销。

表1 不同派遣模式参数对比Table 1 Comparison of different mode parameters

单级派遣即是乘除法MDU单元与ALU单元处在同级流水线中的执行阶段,LSU访存模块处于访存阶段。这种做法在执行乘法指令时可以快一个周期,但是此类指令为长周期指令,需要为此指令类指令再增加另外的派遣缓存,在无此类指令时不工作。在访存指令执行时,需要为所有执行单元设计一个重排序缓冲区,该缓冲区需要时刻接受来自公共数据总线的释放信号,这无疑增大了总线复杂度。

复用派遣即为本设计所采用的方法。所有执行和访存指令均通过派遣缓存(DB),提高了缓存利用率。同时将乘除法单元(MDU)移至访存阶段,由于LSU和MDU指令均为长周期指令,长指令缓存(DLIB)能够更加有效管理指令执行的流向。普通指令结果即可流向寄存器缓存(RB),乘除法指令在运算结束后也可暂存在DLIB,随即流向RB。LSU指令,对于load指令可直接操作RB从Regfiles取操作数,Store指令直接访问外部Memory。同时仅在有需要通信的缓存之间以直接连线的方式,既可以高效完成功能,又可以降低设计复杂度。

可以看到,由于MDU单元需要通过二级DLIB缓存,所以需要适当增大此部分缓存的大小,总体采用的逻辑门数略有增加,这部分面积开销由总线控制模块,DB和DLIB共同承担。但同时性能也有提升,同时简化了复杂的互联机制。对于乘除法和load指令来说,其目的操作数都是RISC-V内部规划的32个32 bit寄存器。其数据流索引被记录在DLIB中,可以直接写入到RB中,当无指令冲突时,即可写入寄存器堆,实现指令退休。store指令为目的操作数为外部存储的空间,在store指令执行中,DLIB可以避免load指令访问该外部存储的地址空间。

采用TMSC 28HPC+工艺,在200 MHz频率下对本设计进行综合。采用CoreMark 5 000次迭代,和Dhrystone进行FPGA功能验证。通过配置发射数,依据各个执行时间结果计算出不同基准测试程序下的IPC数,并平均化处理,得到在不同发射数下的平均IPC。结果表明,本设计配置在2/4发射时,已较为接近知名的BOOM处理器。如表2所示,相较于同类型处理器IPC分别有122.1%、122.3%和176.8%的提升。且采用复用派遣后内核面积仅增大8.1%。

表2 不同处理器性能对比Table 2 Performance comparison of different processors

表3所示为在最优配置下(ALU:3,MDU:2)各个缓存与Top模块在TMSC 28HPC+工艺库下综合参数。得出所需的门电路单元的数目和面积等参数信息。缓存单元容量与总线位宽与逻辑运算单元数量息息相关。当取指位宽与ALU增加时,IB与DB也应增加适应其性能。

表3 主要模块综合结果Table 3 Synthesis results of main modules

从模块综合结果来看,三类缓存中,派遣缓存(DB)占用资源最多。因为所有指令均要经过相关性检测才能从流水线中被派遣,未满足条件的应当留在此阶段,等待发射。

得益于可配置的缓存接口,不仅在较高性能的处理器中占有优势,当配置为单发射顺序执行时,因引入了缓存,虽然面积会大于其他低功耗处理器,但仍在可接受范围内,且性能较其他处理器仍占有优势。此时设计为在配置1发射时,同时配置分支预测为2 bit时情况。作为通用型处理器,本设计与几类嵌入式处理器逻辑门数,跑分等性能方面进行了对比。表4为最低配置时相较于ARM Cortex-M系列和开源RISC-V低功耗处理器的性能对比。

表4 单发射处理器对比Table 4 Single transmitter processor comparison

4 结束语

本文通过对简便的参数化配置,实现了一种基于RISC-V开源指令集的超标量微架构,通过分类指令的数据通路,不同周期的执行单元采用级联与并行的混合分布方式,将充当排序缓存中的指令再派遣,达到指令暂存和分类执行的目的。该方案通过定制优化后的取指中的分支预测,执行中的混合派遣,缓存与执行单元,直连的简洁,等CPU流水线中关键的性能优化点,改善处理器中流水线不匹配以及缓存堵塞的问题。

最终,本设计在FPGA开发板上完成功能处理器功能验证,并在TSMC 28HPC+工艺上进行了面积综合。受益于上述描述的各级流水线的性能点优化,在本设计的最佳配置中,性能相比同类型处理器IPC提升132.4%;在单发射最低配置中,性能和逻辑门数与对应级别的低功耗处理器持平。针对嵌入式多样化的应有方向,下一步研究将此处理器应用到神经网络的向量化处理中,设计特定指令集并在长指令派遣单元中集成更多的专用并行处理单元,实现算法的并行化处理,专用领域的加速研究。

猜你喜欢
流水线寄存器分支
一类离散时间反馈控制系统Hopf分支研究
软件多分支开发代码漏合问题及解决途径①
Lite寄存器模型的设计与实现
流水线
基于PLC的饮料灌装流水线设计
巧分支与枝
二进制翻译中动静结合的寄存器分配优化方法
移位寄存器及算术运算应用
流水线
汽车喷漆流水线的应用与研究