CV32E40P处理器源码剖析(一):IF_Stage

原文链接:CV32E40P处理器源码剖析(一):IF_Stage - 知乎 (zhihu.com)

1. 简介

CV32E40P是PULP项目中一个最早开源采用RISC-V架构的处理器核,2016年成为基金会认可的RISC-V内核之一,2020年2月由RI5CY更名CV32E40P,OpenHw平台维护。CV32E40P是32位按序(in-order)调度的处理器内核,具有四级流水线,RI5CY的指令集支持多个扩展指令,包括硬件循环、增量后加载和存储指令以及附加的ALU指令,核心结构图如下。

CV32E40P整体架构

2. 取指阶段剖析

CV32E40P取指模块设计相对简单,不涉及分支预测、多发射等复杂操作。其内部主要包含cv32e40p_prefetch_buffer、cv32e40p_aligner和cv32e40p_compressed_decoder模块。其中cv32e40p_prefetch_buffer模块负责读取指令SRAM,并将读取的结果送给cv32e40p_aligner模块;cv32e40p_aligner模块负责根据读取数据的低两bit判断是32b指令或者是16b压缩指令,对于非对齐32b指令,需要通过拼接两条32b数据获得;cv32e40p_compressed_decoder模块负责将16b压缩指令补充为32b指令。下面对cv32e40p_prefetch_buffer、cv32e40p_aligner两个关键模块展开介绍。

cv32e40p_if_stage内部模块组成

2.1 cv32e40p_prefetch_buffer

cv32e40p_prefetch_buffer内部包含三个模块cv32e40p_prefetch_controller、cv32e40p_fifo和cv32e40p_obi_interface。其中cv32e40p_prefetch_controller负责根据pc值向cv32e40p_obi_interface发起取指请求,同时依据cv32e40p_obi_interface返回的取值响应以及cv32e40p_aligner的ready信号控制fifo的写入与读取。cv32e40p_fifo则是缓存从指令SRAM读取的数据。值得注意的是,在遇到支指令时需要将fifo中缓存的数据清除后方能继续发起读请求。

2.1.1 cv32e40p_prefetch_controller

cv32e40p_prefetch_controller内部通过控制三个计数器(cnt_q, flush_cnt_q, fifo_cnt_masked)来控制读取指令、清除指令、读写fifo功能。其中,需要关注的点包含三个方面:

1)控制信号信号

  • busy_o:高有效,用于标识是否正在访问指令sram;

 
 

assign busy_o = (cnt_q != 3'b000) || trans_valid_o; //* cnt_q表示正在读取指令SRAM的请求数,trans_valid_o表示正在发起一次新的请求

  • fetch_valid_o:高有效,用于标识是否指令可以输出;

 
 

assign fetch_valid_o = (fifo_valid || resp_valid_i) && !(branch_i || (flush_cnt_q > 0)); //* fifo_valid标识已读取指令fifo非空,resp_valid_i表示指令数据sram正在返回数据, //* branch_i标识分支指令,flush_cnt_q标识分支指令之前已经发起读取指令sram的次数;

  • fifo_cnt_masked:记录指令fifo已经缓存的数量,当发生跳转时置0;

  • cnt_q正在读取sram的指令数,与fifo_cnt_masked的和需要小于预先设定的DEPTH阈值;

 
 

assign trans_valid_o = req_i && (fifo_cnt_masked + cnt_q < DEPTH);

2)指令SRAM地址控制,相对简单,仅两个状态:

  • IDLE,初始装填,有两种情况:a)未发生指令跳转时,指令地址累加4;b)发生跳转时,状态跳转至BRANCH_WAIT;

  • BRANCH_WAIT,等待读取分支跳转地址的指令,状态跳转至IDLE;该状态下有种特例,即仍可能发生中断引起的新分支;

3)指令Fifo读写控制,从指令fifo预取的数据缓存在该fifo中

  • 写fifo:当有指令从sram返回,且fifo非空或cv32e40p_aligner反压有效,且非分支指令,且分支指令之前读取sram的结果均已返回;

 
 

assign fifo_push_o = resp_valid_i && (fifo_valid || !fetch_ready_i) && !(branch_i || (flush_cnt_q > 0));d

值得注意的是fetch_ready_i除了受cv32e40p_aligner影响外,还受fifo_valid、req_i、halt_if_i、id_ready_i(后三个信号来自id)影响;;

  • 读fifo;fifo非空,且cv32e40p_aligner未反压;

 
 

assign fifo_pop_o = fifo_valid && fetch_ready_i;

2.1.2 cv32e40p_obi_interface

cv32e40p_obi_interface模块设计相对简单,负责根据cv32e40p_prefetch_controller读指令需求,向sram发起读请求。cv32e40p_obi_interface模块内部支持两种处理模式:

  • TRANS_STABLE==1模式,即cv32e40p_prefetch_controller接口数据直接赋值给obi接口。cv32e40p_prefetch_controller接口数据在obi_gnt未有效时,需要一直保持原值;

  • TRANS_STABLE==0模式,cv32e40p_prefetch_controller接口数据会被寄存。在obi_gnt未有效时,赋予寄存的值;

2.2 cv32e40p_aligner模块

cv32e40p_aligner模块的核心功能是对齐cv32e40p_prefetch_buffer模块从指令SRAM读取数据。其处理主要包含以下几种情况:

  • ALIGNED32:4B对齐,a)最后两b为11,是32b指令,直接输出,状态仍在ALIGNED32;b)最后两b不是11,是16b指令,直接输出,状态跳转至MISALIGNED32;

  • MISALIGNED32:非4B对齐,已经接收到高2B数据,a)最后两b为11,是32b指令,将上一指令高2B与当前指令低2B拼接,状态仍在MISALIGNED32;b)最后两b不是11,是16b指令,直接输出,状态跳转至MISALIGNED16,如果当前周期还接收到新指令,则需要反压cv32e40p_prefetch_buffer,让其下一拍仍输出当前指令;

  • MISALIGNED16:4B对齐,a)最后两b为11,是32b指令,直接输出,状态跳转至在ALIGNED32;b)最后两b不是11,是16b指令,直接输出,状态跳转至MISALIGNED32;

  • BRANCH_MISALIGNED:非4B对齐,未接收到高2B数据,a)当前指令高2B最后两b为11,是32b指令,需要继续接收32b数据,以拼接成完成32b指令,状态跳转至MISALIGNED32;b)当前指令高2B最后两b不是11,是16b指令,直接输出高2B数据,状态跳转至ALIGNED32;

2.3 cv32e40p_compressed_decoder

cv32e40p_compressed_decoder模块负责将压缩指令统一到32b标准指令。

2.4 模块间控制信号分析

cv32e40p_prefetch_buffer、cv32e40p_aligner、cv32e40p_compressed_decoder三个模块数据信号的交互为cv32e40p_prefetch_buffer将从指令SRAM读取的32b数据交给cv32e40p_aligner,cv32e40p_aligner负责对齐32b指令,然后将其交给cv32e40p_compressed_decoder ,最后cv32e40p_compressed_decoder将压缩指令统一到32b标准指令。

由于两条压缩指令仅占一条32b数据空间,因此存在cv32e40p_aligner输出两条指令,仅需要cv32e40p_prefetch_buffer交付一条32b数据的情况。为此,需要cv32e40p_aligner通过反压信号aligner_ready告知cv32e40p_prefetch_buffer无需读取新的指令。将模块间数据有效和控制信号总结如下。

信号名

方向

含义

fetch_valid

cv32e40p_prefetch_buffer -> cv32e40p_aligner

表示prefetch模块还有指令可用于输出:一直保持有效,当取值fifo非空,或者resp_valid_i有数据返回(指令数据sram返回的结果)

if_ready

中间变量

表示prefetch模块还有指令可用于输出&id_ready_i有效;

if_valid

cv32e40p_prefetch_buffer -> cv32e40p_aligner

表示输出给id指令是否有效,仅当if_ready有效且halt_if_i无效

instr_valid

用于输出给id阶段

表示cv32e40p_aligner输出的数据有效

halt_if_i

来自id阶段

表示遇到分支、debug、irq等pc跳转情况,需要暂停取指

id_ready_i

来自id阶段

表示id阶段是否可以继续接收新指令

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值