蜂鸟 E203 处理器核
文章目录
蜂鸟 E200 处理器的流水线
处理器的流水线结构是处理器微架构最基本的一个要素,犹如汽车底盘对于汽车一般具有基石性的
作用,它承载并决定了处理器其他微架构的细节
- 取指(IFU 单元)
- 执行(EXU 单元)
- 写回(WB 单元)
- 访存(LSU 单元)
- BIU(地址判断和 ICB 总线控制)。取指和访存若需要访问外部存储器,均需通过 BIU 单元
一、取指单元(Instruction Fetch Unit,IFU)微架构
- 对取回的地址进行简单译码(Mini-Decode)。
- 简单的分支预测(Simple-BPU)。
- 生成取指的 PC(PC 生成)。
- 根据 PC 的地址访问 ITCM 或 BIU(地址判断和 ICB 总线控制)。
IFU 在取出指令后,会将其放置于和 EXU单元接口的 IR(Instruction Register)寄存器中。该指令的 PC 值也会被放置于和 EXU 单元接口的 PC 寄存器中,如图中的圆圈所示,EXU单元将使用此 IR 和 PC 进行后续的执行操作。
1、Mini-Decode
2、Simple-BPU 分支预测
3、PC 生成
4、访问 ITCM 和 BIU
5、ITCM
6、BIU
二、执行单元(Execution Unit,EXU)微架构
- 将 IFU 通过 IR 寄存器发送给 EXU 的指令进行译码和派遣(如中的“译码与派遣”)。
- 通过译码出的操作数寄存器索引(Index)读取 Regfile(如图中的 RD-Regfile)。
- 维护指令的数据相关性(如图中的 OITF)。
- 将指令派遣(Dispatch)给不同的运算单元执行(如图中的 ALU、Long-Pipes、LSU 以及EAI)。
- 将指令交付(如图中的交付)。
- 将指令运算的结果写回 Regfile(如图中的 WB Arb)。
1、译码(Decode)模块
根据核心指令格式,取出指令的关键编码段
RISC-V实际只有四种基本格式,但我们可以保守地认为它有六种格式——
- 分支指令(B类型)的立即数字段在S类型的基础上旋转了1位;
- 跳转指令(J类型)的直接字段在U类型的基础上旋转了12位。
RV32I指令集指令格式,六种基本指令格式:
- R型指令:寄存器-寄存器操作
- I 型指令:用于短立即数和访存load操作
- S型指令:用于访存store操作
- B型指令:用于条件跳转操作
- U型指令L:用于长立即数指令
- J型指令:用于无条件跳转
2、整数通用寄存器组(Integer Register File,IR)模块
- RISC-V架构的整数通用寄存器组,包含32个(I架构)或者16个(E架构)通用整数寄存器,其中整数寄存器0被预留为常数0,其他的31个(I架构)或者15个(E架构)为普通的通用整数寄存器。
- 如果使用浮点模块(F 或者 D),则需要另外一个独立的浮点寄存器组,包含 32 个通用浮点寄存器。如果仅使用 F 模块的浮点指令子集,则每个通用浮点寄存器的宽度为 32 比特;如果使用了 D 模块的浮点指令子集,则每个通用浮点寄存器的宽度为 64 比特。
- RISC-V的整数指令都是单操作数或者两操作数指令,且蜂鸟E200属于单发射(一次发射派遣一条指令)的微架构,因此IR模块只需要支持两个读端口。同时,蜂鸟E200的写回策略是按顺序每次写回一条指令的微架构,因此IR模块只需要支持一个写端口
- Integer-Regfile 的写端口逻辑将输入的结果寄存器索引和各自的寄存器号进行比较,产生写使能信号,被使能的通用寄存器即将写数据写入寄存器(x0由于是常数,因此无须写入)。
- Integer-Regfile 的每个读端口都是一个纯粹的并行多路选择器,多路选择器的选择信号即读操作数的寄存器索引。为了减少功耗,读端口的寄存器索引信号(用于并行多路选择器的选择信号)被专用的寄存器进行寄存,只有在执行需要读操作数的指令时才会被加载(否则保持不变),从而减少读端口的动态翻转功耗。 请参见第 15章了解更多低功耗设计的诀窍。
- Integer-Regfile 有两个可配置选项,可以通过 config.v 中的宏进行配置。通用寄存器的个数可以由E203_CFG_REGNUM_IS_32 或者E203_CFG_REGNUM_IS_ 16 进行制定为 32 个(即为 RV32I 架构)或者 16 个(即为 RV32E 架构)。通用寄存器可以用锁存器(Latch)实现,可以由宏 E203_CFG_REGFILE_LATCH_ BASED 进行配置。如果没有定义此宏,通用寄存器则由 DFlip-Flops(DFF)实现。使用锁存器能够显著地减少 Integer-Regfile 的面积和功耗,但是也会给 ASIC 流程带来某些困难,用户可以自行选择是否使用。
- 。。。
3、控制和状态寄存器(Control and Status Register,CSR)
RISC-V架构中定义了一些控制和状态寄存器(CSR),用于配置和记录一些运行的状态
- CSR 寄存器是处理器核内部的寄存器,使用其自己的地址编码空间,与存储器寻址的地址区间完全无关系
- CSR 寄存器的访问采用专用的 CSR 读写指令,包括 CSRRW、CSRRS、CSRRC、CSRRWI、CSRRSI、CSRRCI 指令
- ALU 模块中的 CSR 读写控制模块会产生 CSR 读写控制信号(参见第 8.3.8 节对ALU 模块中 CSR 读写控制模块的介绍),而 CSR 寄存器模块则严格按照 RISC-V 架构的定义实现各个 CSR 寄存器的具体功能。其相关源代码片段如下所示。
4、指令发射(Issue)派遣(Dispatch)
- 蜂鸟 E200 是简单的两级流水线微架构,派遣(Dispatch)或者发射(Issue)发生在流水线的执行阶段,指的是同一个概念,即表示指令经过译码且从寄存器组中读取了操作数之后被派发到不同的运算单元执行的过程
- 蜂鸟 E200 的派遣功能由派遣模块和 ALU 模块联合完成:
1、其所有指令都必须被派遣给 ALU,并且通过 ALU 与交付模块的接口进行交付
2、如果是长指令,也需通过 ALU 进一步将其发送至相应的长指令运算单元。譬如,属于长指令类型Load/Store 指令便是通过 ALU 的 AGU 子单元被进一步发送至 LSU单元进行执行
3、由于所有的指令都需要通过 ALU,因此实际的派遣功能发生在 ALU 的内部。由于蜂鸟 E200 的译码模块在进行译码时,已经根据执行指令的运算单元进行了分组,并且译码出了其相应的指示信号,所以可以按照其指示信号将指令派遣给相应的运算单元
5、流水线冲突、长指令和 OITF(数据相关性)
- 执行阶段的维护并解决流水线的冲突,包括资源冲突和数据冲突(包括 WAW、WAR 和 RAW 等数据相关性)
- OITF 本质上是一个先入先出的 FIFO,FIFO 的深度默认为 2 个表项
6、ALU
蜂鸟 E200 的 ALU 单元,包括 5 个功能子单元:
- 普通 ALU 运算:主要负责普通的 ALU 指令(逻辑运算,加减法,移位等指令)的执行
- 访存地址生成:主要负责 Load、Store 和“A”扩展指令的地址生成
- 分支预测解析:主要负责 Branch 和Jump 指令的结果解析和执行
- CSR 读写控制:主要负责 CSR 指令的执行
- 多周期乘除法器:主要负责乘法和除法指令的执行
4、高性能乘除法
5、交付
6、写回
7、协处理器扩展
三、交付
- 在经典的五级流水线模型中,处理器的流水线分为取指、译码、执行、访存和写回,其中并没有提及“交付”。那么“交付”又有何功能呢?
- 流水线中的指令被“交付”,是指该指令不再是预测执行(Speculative)状态。它被判定为可以真正地在处理器中被执行,可以对处理器状态产生影响
- 分支跳转指令可以以一种预测的形式执行,分支跳转指令是否真正需要产生跳转可能需要经过执行阶段之后才能够被确定
1、交付、取消、冲刷简介
- 当处理器流水线需要将没有“交付”的后续指令全都“取消”掉时,就会造成“流水线冲刷。
- 在 RISC-V 架构的处理器核中只需要处理如下两类流水线冲刷情形。
1、分支预测指令错误预测造成的后续指令流取消
2、中断和异常造成的后续指令流取消
2、处理器交付常见实现策略
- 影响指令“交付”的因素:
1、中断,异常,分支预测指令
2、有的指令集架构中(譬如 ARM),还存在着条件码(Conditional Code)。因此对于每条指令,只有其条件码满足条件为真才会“交付”,否则会被“取消”(只“取消”它自己,并不会产生造成流水线冲刷而取消后续所有指令)。
3、分支预测指令的处理
- IFU 单元中对以上带条件跳转指令均采取静态预测,即如果是向后跳转,则预测为跳(Taken);如果是向前跳转,则预测为不跳(Not Taken)
- 条件跳转指令需要经过“比较”运算才能确定最终是否真的需要跳转,而“比较”运算需由“执行”阶段的 ALU 完成。
- e203_exu_alu_bjp 模块仅处理必要的控制,真正“比较”操作复用的是 ALU 的数据通路
- ALU 在计算出是否需要跳转的结果之后,发送给“交付”模块。“交付”模块则根据预测的结果和真实的结果进行判断。如果预测和真实的结果相符,则意味着预测成功,不会进行流水线冲刷;反之,则预测失败需要进行流水线冲刷。
4、多周期执行指令的交付
- 对于单周期指令而言,其“交付”和“写回”操作在“执行”阶段的同一个周期内完成
- 执行周期超过一个周期的多周期指令,其“交付”同样在“执行”阶段完成,但是“写回”操作则需在后续的周期内写回
四、写回
1、写回硬件实现
- 将指令划分为单周期指令和长指令两大类。
- 将长指令的“交付”和“写回”分开,使得即便执行了多周期长指令,仍然不会阻塞流水线,让后续的单周期指令仍然能够顺利地写回和交付。
- 写回的组件:
1、最终写回仲裁(Final Write-Back Arbitration)
2、长指令写回仲裁(Long-Pipes Instructions Write-Back Arbitration)
3、OITF(Outstanding Instruction Track FIFO)。