ift2icb模块用于控制ifetch模块通过ICB接口来访问ITCM(指令紧耦合内存)和BIU(使用系统存储访问接口访问外部存储器)模块。
以下是对于源码的解读
1.e203_ifu_ift2icb模块中各个信号的含义
取指请求信道的握手信号
ifu_req_valid :ifech向ift2icb模块发送请求时,此信号拉高
ifu_req_ready :ift2icb模块准备好接受ifetch模块的取值请求时,此信号拉高
响应信道的握手信号
ifu_rsp_valid:ift2icb模块准备好交付指令时,此信号拉高
ifu_rsp_ready:ifetch模块准备好接收指令时,此信号拉高
ifu_req_pc:代取指令的PC
ifu_req_seq:代取指令是否是顺序指令
ifu_req_seq_rv32:代取指令是否是32位指令
ifu_req_last_pc:上一次取值时的PC值,即当前正在运行的指令的PC值
ifu_rsp_instr:ICB交付的指令
ICB总线与ITCM进行交互时的握手信号
ifu2itcm_icb_cmd_valid:icb总线访问ITCM时,此信号拉高
ifu2itcm_icb_cmd_ready:ITCM准备好接受ICB的访问时,此信号拉高
ifu2itcm_icb_rsp_valid:ITCM相应ICB总线时(一般应该是将取到的指令交付给ICB),此信号拉高
ifu2itcm_icb_rsp_ready:ICB准备好接受ITCM的响应时,此信号拉高
ICB总线与BIU进行交互时的握手信号
ifu2biu_icb_cmd_valid:
ifu2biu_icb_cmd_ready:
ifu2biu_icb_rsp_valid:
ifu2biu_icb_rsp_ready:
这四个信号的含义与上面大致相同
这里总结一个规律,如下图,master与slave进行通信,一般后缀为_rep_valid(或_cmd_valid)的信号是master要读写slave时的请求信号,_rep_ready(或_cmd_ready)是slave准备好接受master的读写时的准备信号。_rsp_valid是slave将读写结果发送给master时拉高,而_rsp_ready时master准备好接受slave的读写结果时拉高
_cmd与_req的区别:_req是iftech模块请求访问ICB总线的握手信号;_cmd是ICB请求访问指令存储单元(ITCM 、sys_mem)的握手信号
2.bybuf实例化
接下来是实例化了一个缓冲区bybuf,出于以下几个原因:
IR准备信号由EXU级生成,该EXU级包含多个时序关键源(例如,ECC错误检查等),并且此就绪信号将反压到ifetch rsponse通道,如果没有这样的bypbuf,ifetch响应通道可能会卡住等待IR级被清除,这最终可能会陷入死锁, 因为EXU阶段可以访问BIU或ITCM,而他们正在等待IFU接受最后的指令访问,以便为LSU访问让路BIU和ITCM。
所以设置bybuf用于存放BIU交付的指令。
3.e203取值控制策略的简介
首先要明晰,e203有三种存放内存的结构,ITCM、system memory以及I cache,后两者通过BIU进行访问,一般情况下,待取指令可以在ITCM中找到,可以在一个时钟周期内完成取值,在一些特殊情况下需要访问后两者,不可能在一个周期完成。
ITCM是64位宽的SRAM,system memory使用32位宽总线,I cache是N-byte宽,其中SRAM和system memory支持输出数据的hold up (即输出的数据在下一次ITYEM/sys mem被访问之前不变)。
由于e203支持32位的标准指令和16位的精简指令,那么有可能出现指令跨Lane的情况,需要对这些情况进行处理,另外,由于e203低功耗的设计目标,IR寄存器的高16位只有在目标指令是32位时才进行使能。
剩余缓冲区机制:由于ifetch模块不知道要取的指令是32位还是16位,所以每次都取出32位,如果出现指令跨lane的情况,则将本次取出的指令放入剩余缓冲区当中,与下一个lane的低16位组成新的指令。
4.几个信号
接下来的两个信号ifu_req_pc2itcm以及ifu_req_pc2mem是要判断ifetch要从ITCM中取值还是从sys mem中取值。
ifu_req_lane_cross信号用来指示是否跨越lane边界;ifu_req_lane_begin信号用来指示是否是lane的起始;ifu_req_lane_same用来指示待取指令与上一条指令是否相同。
5.状态机的建立
接下来实现了一个如下图所示的状态机,
ICB_STATE_IDLE :空状态,指示ICB正在等待IFU的取指请求;
ICB_STATE_1ST:处理第一个请求中
ICB_STATE_WAIT2ND:等待处理第二个请求
ICB_STATE_2ND:处理第二个请求
req_need_2uop:需要两次取指的标志位;
req_need_0uop:不需要取指请求的标志位
需要两次取值请求的情况:
1:本次指令的起始地址与上一次指令在相同的Lane中,指令是跨lane的,以及访存地址的输出没有holdup
2:本次指令与上一次指令不在相同的lane中,并且指令是跨lane的
需要零次取值请求的情况:本次取指的起始地址与上次在相同的lane中,并且指令没有跨lane,且指令输出已经holdup
接下来生成了一些信号,用与保存ICB总线事务的状态(例如:ICB访问的是哪一种存储单元)
6.剩余缓冲区有关信号的例化
剩余缓冲区会在一下两种情况下被加载:
1:当第一个lane holdup的高16位被加载到剩余缓冲区
holdup2leftover_ena是在这种情况下剩余缓冲区的使能信号
2:当第一个取指请求的结果的高16位被加载到剩余缓冲区
uop1st2leftover_ena是在这种情况下剩余缓冲区的使能信号
7.取指响应信道
ICB模块向ifetch模块交付的指令有两个来源:当前读出的lane和剩余缓冲区。有两种情况:如果需要从剩余缓冲区中加载数据,则将rsp_instr_sel_leftover信号置位,ICB交付的指令为:{rdata[15:0],leftover};如果不需要从剩余缓冲区中加载数据,拉高rsp_instr_sel_icb_rsp信号,则ICB交付的指令应该为:rdata[31:0]
其中,icb_cmd_addr_2_1_r信号用于指示当前待取的指令在lane中的哪一个位置。
8.一些握手信号的生成
接下来生成了一些握手信号(ifu_icb_rsp_ready以及ifu_icb_rsp_valid)。
ifu_icb_cmd_valid信号的生成,有两种情况:
1、当ifetch取指请求到达的时候,并且 不是"need zero uops"的情况;
2、当状态机即将退出 1ST阶段或者状态机已经进入了2ST阶段。
ICB cmd address的生成,有三种情况。
ifu_req_ready信号的生成,有三种情况:当状态机的状态为空,或者需要一次或者0次取指,并且第一次取指已经完成,或者需要两次取指,并且第二次取指已经完成。
9.生成ICB接口访问ITCM和BIU模块
通过判断待取指的指令的地址的高位基地址ifu_icb_cmd_addr[`E203_ITCM_BASE_REGION]与ITCM的基地址(itcm_region_indic[`E203_ITCM_BASE_REGION])是否相等来判断ICB是否也要访问ITCM,如果是,则拉高ifu2itcm_icb_cmd_valid;如果不是,则ICB要访问BIU,需要拉高 ifu2biu_icb_cmd_valid_pre信号。