首页 > 代码库 > OR1200中指令Cache的结构
OR1200中指令Cache的结构
以下内容摘自《步步惊芯——软核处理器内部设计分析》一书
12.3 ICache结构
OR1200中实现ICache的文件有or1200_ic_top.v、or1200_ic_fsm.v、or1200_ic_tag.v、or1200_ic_ram.v、or1200_spram.v,分别实现了ICache模块、IC_FSM模块、IC_TAG模块、IC_RAM模块、单口RAM。在ICache中例化了IC_FSM、IC_TAG、IC_RAM模块,在IC_TAG、IC_RAM模块中例化了单口RAM。如图12.4所示。其中IC_TAG、IC_RAM可以称为数据部分,IC_FSM可以称为控制部分,在数据部分进行查找操作,将查找结果(ICache命中或失靶)送到控制部分,由控制部分依据查找结果进行下一步的操作,比如:当发生失靶时,控制部分会读入16个字节填充到ICache。本节将介绍ICache中的数据部分、控制部分。
12.3.1ICache模块与其余模块的连接关系
在介绍ICache数据部分、控制部分之前,先给出ICache模块与其余模块之间的连接关系,有助于后面的分析。在第3章介绍QMEM时已经给出了ICache与QMEM、WB_BIU之间的连接关系,从中可知ICache与两者都是Wishbone总线接口。ICache的完整接口如图12.5所示。
说明以下几点:
(1)从图中可知ICache除了具有Wishbone总线接口外,还具有特殊寄存器访问接口:spr_cs、spr_write、spr_dat_i,这说明ICache中有特殊寄存器,但是该特殊寄存器不可以读(没有spr_dat_o接口),只能写(有spr_dat_i接口)。
(2)QMEM的输出中有接口icqmem_ci_o,该信号实际直接来自IMMU,回忆一下ITLB中每个表项都有一个标志位CI,表示对应的页是否可以被缓存,该值最终通过QMEM的icqmem_ci_o输出到ICache中,如果要读一个内存块的内容,但是icqmem_ci_o的值为1,那么该内存块是不可能在ICache中的,无需查找ICache,直接从内存中读取,反之,如果icqmem_ci_o的值为0,还要首先在ICache中进行查找。
(3)ICache与WB_BIU之间的接口名称都是icbiu_xxx_x的形式,ICache与QMEM之间的接口名称都是icqmem_xxx_x的形式,因此,可以通过名称知道这个接口的位置。
12.3.2 ICache中数据部分
ICache的数据部分包括IC_TAG、IC_RAM,其主体都是单口RAM。两者共同组成了图12.2中的目录表。查找方法如图12.6所示。
此处采用的还是OR1200默认的ICache设置。IC_TAG共有512个表项,每个表项包含标识、V,其中标识就是物理地址的高19位。IC_RAM中包括的是数据,对ICache而言,此处的数据就是指令。IC_RAM中4个表项(每个表项是一个Word,含4个字节)与IC_TAG中一个表项组成ICache目录表中的一个line,比如:IC_TAG的第1个表项与IC_RAM中位于地址4-7的Word组成ICache目录表的line1。当要取指时时需查找IC_TAG,利用要读取指令地址4-12位的值作为索引查找IC_TAG,得到IC_TAG对应的表项,将该表项返回给ICache模块,后者据此判断Cache是否命中。在查找IC_TAG表的同时,利用物理地址2-12位的值作为索引读出IC_RAM中对应的字,如果ICache命中,那么从IC_RAM中读出的字就是需要的指令。
IC_TAG是通过单口RAM实现的,其主要代码如下:
or1200_ic_tag.v module or1200_ic_tag( //IC_TAG clk, rst, addr, en, we, datain, tag_v, tag ); //数据宽度dw为20,包括地址高19位、有效标志位V parameter dw = `OR1200_ICTAG_W; //地址宽度为9 parameter aw = `OR1200_ICTAG; …… or1200_spram # //例化单口RAM ( .aw(`OR1200_ICTAG), .dw(`OR1200_ICTAG_W) ) ic_tag0 //从单口RAM中读出的数据doq包括标识、有效位 ( .clk(clk), .ce(en), .we(we), .addr(addr), .di(datain), .doq({tag, tag_v}) ); endmodule
IC_RAM也是通过单口RAM实现的,其主要代码如下:
or1200_ic_ram.v module or1200_ic_ram( //IC_RAM clk, rst, addr, en, we, datain, dataout ); parameter dw = `OR1200_OPERAND_WIDTH; //数据宽度为32bit parameter aw = `OR1200_ICINDX; //地址宽度为11 …… or1200_spram # //例化单口RAM ( .aw(`OR1200_ICINDX), .dw(32) ) ic_ram0 ( .clk(clk), .ce(en), .we(we[0]), .addr(addr), .di(datain), .doq(dataout) ); endmodule
12.3.3 ICache中控制部分
ICache的控制部分会依据IC_TAG、IC_RAM的查找结果控制ICache下一步的操作,ICache的控制部分主要在IC_FSM模块中实现。IC_FSM模块的主体是一个状态机,有三个状态:IDLE、CFETCH、LREFILL3,定义如下:
or1200_defines.v `define OR1200_ICFSM_IDLE 2'd0 `define OR1200_ICFSM_CFETCH 2'd1 `define OR1200_ICFSM_LREFILL3 2'd2 //本状态虽然定义了,但是并没有使用,所以IC_FSM中状态机只有3个状态 `define OR1200_ICFSM_IFETCH 2'd3
状态转换如图12.7所示。
处理器复位的时候处于IDLE状态,当要取指时会进入CFETCH状态,此时分三种情况:
- 如果ICache命中,那么将从IC_RAM中查找的指令返回给处理器,同时保持CFETCH状态
- 如果ICache失靶,那么会从内存中读取所需指令,然后进入LREFILL3状态,在该状态下会读出所需指令所在内存块中剩余的3个字,也就是将所需指令所在内存块的4个字都读入ICache,然后回到IDLE状态
- 如果所需指令所在内存块禁止缓存(即CI为1),那么会从内存中读取所需指令,然后回到IDLE状态
上述三种情况也是ICache的三种使用情景,本章在后面会结合代码深入分析这三种情景下ICache的工作过程,包括IC_FSM中状态机的状态转换,届时读者朋友会有更加深刻的认识。
12.3.4 ICache数据部分与控制部分的对外接口
IC_FSM、IC_TAG、IC_RAM都在ICache中例化,例化语句如下:
or1200_ic_top.v …… or1200_ic_fsm or1200_ic_fsm( //例化IC_FSM .clk(clk), .rst(rst), .ic_en(ic_en), .icqmem_cycstb_i(icqmem_cycstb_i), .icqmem_ci_i(icqmem_ci_i), .tagcomp_miss(tagcomp_miss), .biudata_valid(icbiu_ack_i), .biudata_error(icbiu_err_i), .start_addr(icqmem_adr_i), .saved_addr(saved_addr), .icram_we(icram_we), .biu_read(icfsm_biu_read), .first_hit_ack(icfsm_first_hit_ack), .first_miss_ack(icfsm_first_miss_ack), .first_miss_err(icfsm_first_miss_err), .burst(icfsm_burst), .tag_we(icfsm_tag_we) ); or1200_ic_ram or1200_ic_ram( //例化IC_RAM .clk(clk), .rst(rst), .addr(ic_addr[`OR1200_ICINDXH:2]), .en(ic_en), .we(icram_we), .datain(to_icram), .dataout(from_icram) ); or1200_ic_tag or1200_ic_tag( //例化IC_TAG .clk(clk), .rst(rst), .addr(ictag_addr), .en(ictag_en), .we(ictag_we), .datain({ic_addr[31:`OR1200_ICTAGL], ictag_v}), .tag_v(tag_v), .tag(tag) ); ……
参考上述例化语句得到图12.8,其中给出了IC_FSM、IC_TAG、IC_RAM模块的接口,以及各个接口连接到ICache的对应变量,每个模块的左边是输入接口,右边是输出接口,每个模块内部是接口名,外部引脚上的名称代表ICache中的对应变量。
图12.8中,IC_TAG的输出tag_v、tag是查找结果,ICache依据此查找结果设置信号tagcomp_miss的值,该信号表示ICache是否命中,并且该信号输入到IC_FSM的同名接口,IC_FSM依据该值进行状态转换、输出控制信号,以进行下一步的操作。
本章后面分析ICache时需要经常参考该图,读者此刻也不必明白各个接口的含义,笔者留在使用到该接口的时候再做介绍。