OR1200数据Cache介绍
以下摘录《步骤吓得核心——软-core处理器的室内设计与分析》一本书
上一章剖析了ICache模块。
本章将剖析DCache模块。首先指出DCache模块相比ICache的特别之处。由于这些不同。所以DCache的分析相对复杂。
接着分析了OR1200中DCache的结构,给出了构成DCache的四个模块的关系,将这四个模块分为数据部分、控制部分。介绍了数据部分的工作过程。13.3节说明了DCache中特殊寄存器的作用与格式。13.4节指出使用到DCache的7种情景。13.5节给出一个演示样例程序,当中涉及了DCache的大部分使用情景,之后。重点分析了在当中3种情景下DCache的工作过程。
13.1 DCache的特别之处
DCache中缓存的是数据。而ICache中缓存的是指令,这就是DCache与ICache的根本差别,由此也决定了DCache的特别之处。
指令存储在指令存储器中,且指令存储器是仅仅读的,相应仅仅有一个取指操作。可是数据存储在数据存储器中,且数据存储器是可读、可写的,相应载入、存储两个操作。普通情况下,指令存储器、数据存储器都属于内存的一部分,有时就是内存中相同的地址空间。
当向数据存储器中存储数据且DCache命中时。称之为写命中。能够採用两种策略:
- 通写法(Write through):不仅把数据写入DCache中对应的块。并且也写入数据存储器中对应的块。
- 回写法(Write back):仅仅把数据写入DCache中对应的块,并不会马上更新数据存储器中的内容。而是等到DCache中对应的块由于某种原因须要从DCache中移出时,才更新数据存储器中的内容。
通写法与回写法各有特点。回写法的长处是速度快,写操作能以DCache的速度进行。并且对于同一个内存块的多次写操作仅仅需最后进行一次内存写操作。通写法的长处是易于实现,并且内存与DCache的数据总是保持一致。
当向数据存储器中存储数据且DCache失靶时,称之为写不命中,也能够採用两种策略:
- 按写分配法(Write allocate):先把要写数据所在的存储块调入DCache。然后再进行写入。
- 不按写分配法(no-Write allocate):直接写数据存储器中的目的地址。而不将要写数据所在的存储块调入DCache。
一般採用通写法时使用不按写分配法,採用回写法时使用按写分配法。
在OR1200中能够配置DCache使用通写法还是回写法,採用通写法时就与不按写分配法结合使用,採用回写法时就与按写分配法结合使用,所以后面在分析的时候仅仅是说明通写法、回写法。而不再说明按写分配法、不按写分配法。
or1200_defines.v
//不凝视以下的宏定义,就是採用“通写法+不按写分配法”,
//凝视掉以下的宏定义。就是採用“回写法+按写分配法”
`define OR1200_DC_WRITETHROUGH
OR1200中关于DCache的宏定义例如以下,从中可知。DCache可以配置为512B、4KB、8KB、16KB、32KB,默认是8KB,本章採用默认配置,后面分析时不再反复说明。
此时内存块的大小是16字节,採用直接映射,DCache文件夹表有512
line。因此使用地址的4-12bit作为DCache文件夹表的查找索引。
or1200_defines.v
//`define OR1200_NO_DC //是否有DCache。默认是凝视掉,也就是有DCache //`define OR1200_DC_1W_4KB
`define OR1200_DC_1W_8KB
//`define OR1200_DC_1W_16KB
//`define OR1200_DC_1W_32KB `ifdef OR1200_DC_1W_32KB
`define OR1200_DCLS 5 //假设DCache配置为32KB,则内存块的大小是32字节
`else
`define OR1200_DCLS 4 //否则都是16字节
`endif `define OR1200_SPRGRP_DC_ADR_WIDTH 3 //特殊寄存器相应索引的宽度 //特殊寄存器DCBFR在第3组特殊寄存器中的索引是2
`define OR1200_SPRGRP_DC_DCBFR 3'd2 //特殊寄存器DCBIR在第3组特殊寄存器中的索引是3
`define OR1200_SPRGRP_DC_DCBIR 3'd3 //特殊寄存器DCBWR在第3组特殊寄存器中的索引是4
`define OR1200_SPRGRP_DC_DCBWR 3'd4 `ifdef OR1200_DC_1W_8KB //假设配置DCache为8KB,那么一些宏定义例如以下
`define OR1200_DCSIZE 13 //DCache是8KB,所以地址宽度是13 `define OR1200_DCINDX `OR1200_DCSIZE-2 // 11
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 12
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 13 //13位地址中的高9位是DCache文件夹表的索引
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS //标识的宽度,包含地址的高19位、有效标志位V
`define OR1200_DCTAG_W 20 `endif
13.2 DCache结构
与ICache相应,OR1200中实现DCache的文件有or1200_dc_top.v、or1200_dc_fsm.v、or1200_dc_tag.v、or1200_dc_ram.v、or1200_spram.v、or1200_spram_32_bw.v。分别实现了DCache模块、DC_FSM模块、DC_TAG模块、DC_RAM模块、单口RAM、可按字节写的单口RAM模块。在DCache中例化了DC_FSM、DC_TAG、DC_RAM模块。在DC_TAG模块中例化了单口RAM,在DC_RAM模块中例化了可按字节写的单口RAM。如图13.1所看到的。当中DC_TAG、DC_RAM能够称为数据部分,DC_FSM能够称为控制部分,在数据部分进行查找操作,将查找结果(DCache命中或失靶)送到控制部分,由控制部分根据查找结果进行下一步的操作。假设是写操作,那么下一步的操作还需參考当前配置的写策略。本节将介绍DCache中的数据部分、控制部分。
13.2.1 DCache模块与其余模块的连接关系
在介绍DCache数据部分、控制部分之前,先给出DCache模块与其余模块之间的连接关系,有助于后面的分析。在第3章介绍QMEM时。已经给出了DCache与QMEM、SB之间的连接关系,从中可知DCache与两者之间都是通过Wishbone总线接口连接的,參考本书光盘中的or1200_top.vsd能够得到DCache模块完整的对外连接关系。如图13.2所看到的。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGVpc2hhbmd3ZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
有下面几点说明:
(1)从图中可知DCache除了具有Wishbone总线接口外还具有特殊寄存器訪问接口:spr_cs、spr_write、spr_dat_i,与ICache一样,这说明DCache中有特殊寄存器,可是该特殊寄存器不能够读(没有spr_dat_o接口),仅仅能写(有spr_dat_i接口)。与ICache不同之处在于DCache还有spr_addr接口。说明DCache中的特殊寄存器是有地址要求的。也就是有索引,而在ICache中仅仅有一个特殊寄存器,所以其索引能够随意,參考表12.1。
(2)相比CPU与ICache之间的接口。CPU与DCache之间还添加了dc_no_writethrough、mtspr_dc_done两个接口,其作用会在后面的分析中介绍。
(3)QMEM的输出中有接口dcqmem_ci_o,该信号实际直接来自DMMU,回顾一下DTLB中每一个表项都有一个标志位CI。表示相应的页能否够被缓存,通过QMEM的dcqmem_ci_o输出到DCache中,假设要訪问一个内存块的内容,可是该内存块所在页的dcqmem_ci_o值为1,那么该内存块是不可能在DCache中。无需查找DCache,直接从内存中訪问,反之,假设dcqmem_ci_o的值为0,还要首先在DCache中进行查找。
(4)相比QMEM与ICache之间的Wishbone总线接口,QMEM与DCache之间的Wishbone总线接口多了两个输入dcqmem_dat_i、dcqmem_we_i,这是与存储操作有关的接口信号。
(5)DCache并没有与WB_BIU模块直接连接,而是在DCache与WB_BIU之间放置了一个SB(Store
Buffer)模块,后者与DCache之间的接口也符合Wishbone总线规范。该模块的作用将在下一章分析。
(6)DCache与SB之间的接口名称都是dcsb_xxx_x的形式,DCache与QMEM之间的接口名称都是dcqmem_xxx_x的形式。因此通过名称就能够知道这个接口的位置。
13.2.2 DCache中数据部分
DCache的数据部分包含DC_TAG、DC_RAM,其主体各自是单口RAM、可按字节写的单口RAM。
两者共同组成了图12.2中的文件夹表。查找方法如图13.3所看到的。
此处採用的是OR1200默认的DCache设置,即总容量是8KB,内存块大小为16字节。文件夹表有512
line。图13.3的解释请參考对ICache中数据部分的解释,须要注意一点:DC_TAG每一个表项包括标识、V、Dirty,比IC_TAG多了一个Dirty标志位,该位为1表示当前line相应的缓存数据被改动了可是相应内存块没有改动。也就是缓存与内存不一致,反之表示line相应的缓存与内存一致。參考通写法、回写法的定义可知:仅仅有在使用回写法策略时。才可能存在Dirty为1的情况,在使用通写法策略时。Dirty标志位始终为0。
DC_TAG是通过单口RAM实现的,其主要代码例如以下。注意一点:其数据宽度是21,比ICache中的IC_TAG多了一位用来保存Dirty的值。
or1200_dc_tag.v
module or1200_dc_tag( //DC_TAG clk, rst, addr, en, we, datain, tag_v, tag, dirty
);
…… //OR1200_DCTAG_W为20,所以dw为21。添加的1位是Dirty位
parameter dw = `OR1200_DCTAG_W + 1; //地址宽度为9
parameter aw = `OR1200_DCTAG; or1200_spram # //例化单口RAM
( .aw(`OR1200_DCTAG), .dw(`OR1200_DCTAG_W + 1) ) //从单口RAM中读出的数据doq包含标识、有效位V、是否改动位Dirty
dc_tag0
( .clk(clk), .ce(en), .we(we), .addr(addr),
.di(datain), .doq({tag, tag_v, dirty}) ); endmodule
DC_RAM也是通过单口RAM实现的,可是可按字节写的单口RAM,回顾一下OR1200中的存储指令l.sb、l.sh。都是仅仅改动一个字中的一部分。所以须要这样设计。DC_RAM的主要代码例如以下:
or1200_dc_ram.v
module or1200_dc_ram( //DC_RAM
clk, rst, addr, en, we, datain, dataout
); parameter dw = `OR1200_OPERAND_WIDTH; //数据宽度是32bit
parameter aw = `OR1200_DCINDX; //地址宽度是11
……
or1200_spram_32_bw # //例化单口RAM,此处的单口RAM能够按字节写
( .aw(`OR1200_DCINDX), .dw(dw) )
dc_ram //注意变量we的宽度为4
( .clk(clk), .ce(en), .we(we), .addr(addr),
.di(datain), .doq(dataout) );
endmodule
当中能够按字节写的单口RAM是使用4个8bit宽度的数组实现的。主要代码例如以下:
or1200_spram_32_bw.v
module or1200_spram_32_bw ( clk, ce, we, addr, di, doq ); parameter aw = 10;
parameter dw = 32; //数据宽度是32 ……
input [3:0] we; // 注意此处的写使能信号we的宽度是4 reg [7:0] mem0 [(1<<aw)-1:0]; //定义了4个8位数组
reg [7:0] mem1 [(1<<aw)-1:0];
reg [7:0] mem2 [(1<<aw)-1:0];
reg [7:0] mem3 [(1<<aw)-1:0];
…… //分别从4个8位数组中读出相应的数据组成一个//32位的数作为要读取的数
assign doq = {mem0[addr_reg], mem1[addr_reg], mem2[addr_reg], mem3[addr_reg]}; always @(posedge clk)
if (ce)
addr_reg <= addr; //寄存地址信号 always @(posedge clk)
if (ce) begin
if (we[3]) //假设we[3]为1表示要写目的地址的最高位字节
mem0[addr] <= di[31:24];
if (we[2]) //假设we[2]为1表示要写目的地址的次高位字节
mem1[addr] <= di[23:16];
if (we[1]) //假设we[1]为1表示要写目的地址的次低位字节
mem2[addr] <= di[15:08];
if (we[0]) //假设we[0]为1表示要写目的地址的最低位字节
mem3[addr] <= di[07:00];
end endmodule // or1200_spram
13.2.3 DCache中控制部分
DCache会根据DC_RAM、DC_TAG的查找结果,以及当前的写策略决定下一步的操作。DCache中的控制部分主要在DC_FSM模块中实现,其主体是一个状态机,有IDLE、CLOADSTORE、LOOP2、LOOP3、LOOP4、FLUSH5、INV6、WAITSPRCS7等8个状态,定义例如以下:
or1200_fsm.v
`define OR1200_DCFSM_IDLE 3'd0
`define OR1200_DCFSM_CLOADSTORE 3'd1
`define OR1200_DCFSM_LOOP2 3'd2
`define OR1200_DCFSM_LOOP3 3'd3
`define OR1200_DCFSM_LOOP4 3'd4
`define OR1200_DCFSM_FLUSH5 3'd5
`define OR1200_DCFSM_INV6 3'd6
`define OR1200_DCFSM_WAITSPRCS7 3'd7
因为有两种写策略,在不同的写策略下,DCache有不同的工作过程。状态转换也不同,比較复杂,所以本章将在分析DCache过程中逐步给出状态之间转换关系。
13.2.4 DCache数据部分与控制部分的对外接口
DC_FSM、DC_TAG、DC_RAM模块都在DCache中例化,例化语句例如以下:
or1200_dc_top.v
……
or1200_dc_fsm or1200_dc_fsm( //例化DC_FSM
.clk(clk),
.rst(rst),
.dc_en(dc_en),
.dcqmem_cycstb_i(dcqmem_cycstb_i),
.dirty(dirty),
.tag(tag),
.tag_v(tag_v),
.dcqmem_ci_i(dcqmem_ci_i),
.burst(dcfsm_burst),
.tag_we(dcfsm_tag_we),
.dc_addr(dc_addr),
.dcqmem_we_i(dcqmem_we_i),
.dcqmem_sel_i(dcqmem_sel_i),
.tagcomp_miss(tagcomp_miss),
.biudata_valid(dcsb_ack_i),
.biudata_error(dcsb_err_i),
.lsu_addr(dcqmem_adr_i),
.dcram_we(dcram_we),
.biu_read(dcfsm_biu_read),
.biu_write(dcfsm_biu_write),
.dcram_di_sel(dcfsm_dcram_di_sel),
.biu_do_sel(dcfsm_biu_do_sel),
.first_hit_ack(dcfsm_first_hit_ack),
.first_miss_ack(dcfsm_first_miss_ack),
.first_miss_err(dcfsm_first_miss_err),
.dc_no_writethrough(dc_no_writethrough),
.tag_valid(dcfsm_tag_valid),
.tag_dirty(dcfsm_tag_dirty),
.dc_block_flush(dc_block_flush),
.mtspr_dc_done(mtspr_dc_done),
.dc_block_writeback(dc_block_writeback),
.spr_dat_i(spr_dat_i),
.spr_cswe(spr_cs & spr_write)
); or1200_dc_ram or1200_dc_ram( //例化DC_RAM
.clk(clk),
.rst(rst),
.addr(dc_addr[`OR1200_DCINDXH:2]),
.en(dc_en),
.we(dcram_we),
.datain(to_dcram),
.dataout(from_dcram)
); or1200_dc_tag or1200_dc_tag( //例化DC_TAG
.clk(clk),
.rst(rst),
.addr(dctag_addr),
.en(dctag_en),
.we(dctag_we),
.tag_v(tag_v),
.tag(tag),
.dirty(dirty)
.datain({dc_addr[31:`OR1200_DCTAGL], dctag_v, dctag_dirty}),
);
……
參考上述例化语句得到图13.4。当中给出了DC_FSM、DC_TAG、DC_RAM模块的接口,以及各个接口连接到DCache的相应变量,每一个模块的左边是输入接口。右边是输出接口。每一个模块内部是接口名。外部引脚上的名称代表DCache中的相应变量。本章在后面分析DCache时须要常常參考该图,各个接口的含义也留在使用到该接口的时候再作说明。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGVpc2hhbmd3ZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
版权声明:本文博客原创文章。博客,未经同意,不得转载。
OR1200数据Cache介绍的更多相关文章
- OR1200数据Cache运用情景分析
以下摘录<步骤吓得核心--软-core处理器的室内设计与分析>一本书 13.7DCache使用情景之中的一个--存储指令运行阶段DCache失靶 存储指令运行阶段DCache失靶这样的情景 ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_32..SpringBoot2.x持久化数据方式介绍
笔记 1.SpringBoot2.x持久化数据方式介绍 简介:介绍近几年常用的访问数据库的方式和优缺点 1.原始java访问数据库 开发流程麻烦 ...
- DELPHI中枚举类型数据的介绍和使用方法
在看delphi程序的时候看到aa=(a,b,c,d);这样的东西,还以为是数组,同事说是函数,呵呵,当然这两个都不屑一击,原来这样式子是在声明并付值一个枚举类型的数据.下边写下来DELPHI中枚举类 ...
- Spring Cache 介绍
Spring Cache 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 c ...
- nopCommerce架构分析系列(二)数据Cache
原文(http://www.cnblogs.com/gusixing/archive/2012/04/12/2443799.html)非常感谢作者顾思行的分享! 序言 在很多访问量较大的系统中,尤其在 ...
- key-list类型内存数据引擎介绍及使用场景
“互联网数据目前基本使用两种方式来存储,关系数据库或者key value.但是这些互联网业务本身并不属于这两种数据类型,比如用户在社会化平台中的关系,它是一个list,如果要用关系数据库存储就需要转换 ...
- MySQL 各类数据文件介绍
数据文件 在MySQL中每一个数据库都会在定义好(或者默认)的数据目录下存在一个以数据库名字命名的文件夹,用来存放该数据库中各种表数据文件. 不同的MySQL存储引擎有各自不同的数据文件,存放位置也有 ...
- 缓存cache介绍
1. 为何要用缓存.缓存的目的是为了什么?(https://my.oschina.net/u/3378039/blog/2986697) 一个程序的瓶颈在于数据库,内存的速度远远大于硬盘的速度,当我 ...
- 【转载】Spring Cache介绍
原文地址:http://www.cnblogs.com/rollenholt/p/4202631.html 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个 ...
随机推荐
- Microsoft Visual C++ Runtime Library Runtime Error解决的方式
打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭. 一. ...
- Spring Boot 基础
Spring Boot 基础 Spring Boot 项目(参考1) 提供了一个类似ASP.NET MVC的默认模板一样的标准样板,直接集成了一系列的组件并使用了默认的配置.使用Spring Boot ...
- java中用正則表達式推断中文字符串中是否含有英文或者数字
public static boolean includingNUM(String str)throws Exception{ Pattern p = Pattern.compile(" ...
- Cocos2d-x学习笔记(9)(CCTextFieldTTF使用输入框)
1.CCTextFieldTTF创建和使用 CCTextFieldTTF::create(const char* placeholder,const char* fontName.float font ...
- 对比Windows 8模拟器(Simulator)和Windows Phone仿真器(Emulator)
原文:对比Windows 8模拟器(Simulator)和Windows Phone仿真器(Emulator) 从事移动应用开发,经常会用到模拟器(Simulator)和仿真器(Emulator),本 ...
- cassandra 服务启动流程
cassandra 服务启动流程 1. setup 1) CassandraDaemon ->main publicstaticvoidmain(String[]args) { insta ...
- C/S通信模型和相关技术要点
差点儿全部的项目中,都会涉及到client和服务端.而client与server之间的通信又是一个非经常见但又有须要问题的技术问题. 首先,连接方式有长连接和短连接.先看看概念. 长连接短连接仅仅是一 ...
- ASP.NET分页正品—分页真
承接上篇博文<ASP.NET真假分页-假分页>:http://blog.csdn.net/u010773667/article/details/38845009,继续解说ASP.NE ...
- mouseover与mouseenter与mousemove差额mouseout与mouseleave差额
<1> HTML <html> <head> <title></title> </head> <body> < ...
- JBoss配置解决高并发连接异常问题(转)
这两天一个项目在做压力测试的时候,发现只要并发数超过250个,连续测试两轮就会有连接异常出现,测试轮数越多出现越频繁,异常日志如下: Caused by: com.caucho.hessian.cli ...