i-cache和d-cache区别:
从两个方面来回答:
一方面是cache的行为。Icache大多都是顺序取指,碰到分支指令也会跳转, 而Dcache访问的模式变化比较大.也就是前者所说的pattern的问题. 指令只有读和refill没有写,而数据有读也有写. 最重要的是冯氏的结构是指令和数据分离.I和D在一起只有相互干扰.另一个方面就是,物理设计上考虑:
一个union的cache,同时需要数据和指令的访问,端口上是很难实现的。
所以一般在流水线的主干上,都是采用分离的icache和dcache.
非主干的L2 cache,从容量的角度考虑采用union的方式.
当然早期的也有不分离icache和dcache.因为早期的结构也简单.
http://www.newsmth.net/nForum/#!article/CSArch/9393
Cache的层次设计
1 引 言
微处理器和存储器的发展一直以来都不是很均衡,这导致了两者在性能上的巨大鸿沟。在
1980
年,典型的微处理器的运行频率是
10MHz
,典型的
SDRAM
访问时间是
250ns
。而如今微处理器运行在
GHz
的频率内,提高了几个数量级,而
SDRAM
却差不多只提高了一个数量级。对主存的访问速度成为了约束微处理器性能的瓶颈。解决微处理器访问
SDRAM
速度慢的方法是采用访问速度快的
SRAM
,但是
SRAM同DRAM相比存储密度较低,造价太高。所以通常会在微处理器上使用SRAM作为一个暂存,这些暂存的单元就是Cache。采用SRAM的Cache技术则在很大成程度上克服了对主存访问速度慢的瓶颈。
随着对处理器性能要求的提高,流水线技术已经是当前微处理器中广泛采用的一种实现手段。本文以一款参考
MIPS
架构的
RISC
型流水线微处理器作为研究对象,介绍了如何为这款处理器设计相应的
Cache
结构。
2 Cache的层次设计
出于对简化设计的考虑,也为了提高系统的性能,本次设计采用了指令
Cache(以下简称为ICache)和数据Cache (以下简称为DCache)
分开的方式。在
ICache中存储有微处理器需要的指令,在微处理器的取指阶段,通过程序计数器PC提供给ICache的地址,微处理器可以获取需要的指令。而DCache则是作为一个数据的存储,并提供对于Load/Store指令所要操作地址的数据,它地址则来自于ALU运算的结果。
ICache和微处理器的接口以及ICache和L2 ICache的接口都是单向的。DCache和微处理器的接口以及DCache和L2 Cache的接口是双向的。这样处理的原因在于ICache存储的是指令,不需要更改所存储的数据的值。而DCache
中存储的是数据,其值会根据指令操作的不同而改变。比如:在运行
Store
指令的时候会对
DCache
中相应地址进行写入数据的操作。
整个系统的层次结构如图1所示,由ICache和DCache构成L1 Cache,以及和L1 Cache接口的L2 Cache,和L2 Cache接口的DRAM。其中L1 Cache和L2 Cache是在微处理器片内,而DRAM是作为主存,存在于片外。这跟目前主流的个人电脑的层次结构很相似。
3 Cache的结构分析
从微处理器架构的角度来说,所谓的
Cache包括了两部分:Cache控制器和Cache
存储器。文本所提及的
Cache
设计也包括了这两个方面。
由于
ICache
只是读出指令,控制上比
DCache
要简单许多。所以
ICache
的设计完全可以参考
DCache
的设计,本文会针对
L1 Cache
中
DCache
的设计进行详细的描述。
3.1 DCache存储器的结构
Cache
存储器其一般实现方式主要有三种,分别是全相联,直接映射和组相联。全相联最灵活但是实现比较复杂。直接映射比较容易实现,但是可能产生快速抖动。组相联则是前两者的一个折衷。本文采用的是两路组相联的方式。
图
2
:
DCache
结构图
为了设计方便,整个
DCache
存储器被分成了两块,为别用来存储标签域
(Tag)
和数据域
(Data)
。其结构如图
2
所示,在数据域中,每一组中包括
512
行,每行有
16
字节的数据,在标签域中,每组中都有
512
行与数据域的行相对应,每一行中有
19
位的标签。通过地址总线的中间的地址位来选择某一行的数据,同时通过地址总线的高端的地址位来判断
DCache
是否命中。并且由于读出的是
16
字节的数据,而设计的微处理器所需要的仅仅是
32
位的数据,因此在数据被读出后还需要通过地址总线的低端的地址位来选择相应的字段,并把微处理器需要的字段放到数据总线上。
3.2 DCache控制器的结构
DCache
控制器在整个
DCache
中处于非常重要的地位,它控制了整个
DCache
所要进行的操作,同时会在发生缺失时采取相应的对策。其主要功能如下:
1)
反馈给微处理器读取
DCache
的信息,包括
DCache
的命中或者缺失等信息。如果发生缺失,可能会要求流水线发生阻塞。
2)
如果发生缺失,需要从下一级存储单元寻找相应的地址中的内容,并将内容载入到
DCache
中。
3)
控制读写操作。如果是读操作,则需要为下一级的操作提供相应的数据。如果是写操作,则需要将数据写入到相应的地址中去。
为了完成上述的功能,整个
DCache
控制器被分为三个部分,分别为用来判断命中还是缺失的判断部分和用来执行发生缺失时一些相应操作的有限状态机部分以及正常读写的控制部分。其中有限状态机部分中还包括了两个存储块,分别是为了实现
LRU (least recently used)
算法的
LRU
数据块和为了判断存储的数据有没有被改写过的
Dirty
数据块,其具体的结构图如图
3
所示。
图3:
DCache
控制器的结构图
通过将
Tag
和地址总线的高地址位比较所得出的
hit
标志提供给
FSM
,来确定是否需要启用缺失处理功能。同时
FSM
可以通过控制
L1 Cache
和
L2Cache
的读写,来实现缺失后数据的操作。
hit
标志同样也会输出到微处理器,使得微处理器在发生缺失的时候阻塞流水线。
4 Cache的操作分析
由于
DCache
中会发生读或者写两种操作,下面将对
DCache
中的读写操作分别进行分析。
本文涉及的微处理器由
5
级流水线构成,分别是取指
(IF)
,指令译码
(ID)
,执行
(EXE)
,内存存取
(MEM)
,回写
(WB)
。在
MEM
操作之前是
EXE
操作,也就是
ALU
会根据指令的不同,计算出不同的地址值,无论进行的是读或者写操作,都需要进行读
DCache
中相应地址的
Tag
值,并通过比较
Tag
标志位来判断需要读出或者写入的地址单元是否存在于
DCache
中。
4.1 读操作
本设计所采用的读操作的方式是将标签域
(Tag)
中的内容和数据域
(Data)
中的内容同时读出,然后再将
Tag
的内容与地址高端进行比较。如果相等,则说明
DCache
命中,读出的
Data
的内容正是给出的地址中的内容。如果不相等,则说明发生了
DCache
读缺失,需要进行缺失处理。在不发生缺失的情况下,一次读操作可以在一个
Clock
周期内完成。这非常符合流水线的特性。
如果发生读缺失,
DCache
中
FSM
会首先查看
LRU
块,确定两路数据存储中具有同一索引的两个行中哪一行将会被替换出去。然后
FSM
会查看
Dirty
块,确定是否需要将行中的内容更新到主存。如果需要,则将之前读出的数据写入到主存,然后将主存中的数据读出,放到数据总线上,供流水线的下一级使用。如果不需要,则直接读取主存中相应地址的数据并放到数据总线上,供下一级使用。这些操作完成之后
FSM
会通知微处理器停止阻塞流水线,这样在下一个时钟周期微处理器又会正常运行。
图4:读操作流程图
读操作的具体流程和发生缺失后
FSM
的相应操作流程如图
4
所示。
4.2 写操作
写操作一般有两种方式分别是写通过
(Write-through)
方式和写回方式
(Write-back)
。写通过方式支持改写
Cache
中的内容,但是不允许
Cache
和主存内容不一致,因此,对在对
Cache
进行写操作时,对主存也要进行写操作。这会延长写操作的时间。而写回方式则是对相应的
Cache
进行写操作,但是并不立即对主存进行写操作,这能有效的减少访问主存的延迟。但是这种方式的实现比较复杂,因为
Cache
和主存的内容存在不一致性。处于提高性能的考虑,本设计所采用的是写回的方式。
写操作分两步进行,第一步需要读取标签域
(Tag)
和数据域
(Data)
中的内容,然后把
Tag
的内容与地址高端进行比较。如果相等,则说明
DCache
命中,需要写入数据的地址存在,可以将数据写入
DCache
中。同时由于写入的数据只有
32
位,而读出的数据有
128
位,需要通过地址总线的低位来进行选择需要写入的字段。如果
Tag
不相等,则说明发生了
DCache
写缺失,需要进行缺失处理。在不发生缺失的情况下,一次写操作需要两个
Clock
周期来完成。这不符合流水线的要求,所以本次设计中采用了流水线式的写入方式,在微处理器和
DCache
之间加入了一级写缓存。在读取
DCache
的标签和数据的内容的同时,将数据写入写缓存。这样就能够使得写入操作以流水线的方式进行。可以满足流水线微处理器的要求。
当发生写缺失时,同样
FSM
会先查看
LRU
块,确定哪一行需要从两路数据存储块中删除,然后再查看需要从
Dcache
中删除的行是否为“脏”。如果是“脏”行,则将之前从
DCache
中读出的数据写入到主存,并将主存的数据读出,并连同之前存入写缓存中的数据,准备写入到
DCache
中。如果行“干净”,则直接读出主存中的数据,并和写缓存的数据做好写入
DCache
的准备。完成之后
FSM
会通知微处理器停止阻塞流水线,这样在下一个时钟周期微处理器又会正常运行,同时将数据写入。
图5:写操作流程图
写操作的具体流程和发生缺失后
FSM
的相应操作流程如图
5
所示。
5 使用FPGA进行验证
本设计采用
Xilinx
公司的
Virtex-II Pro
开发板进行验证。开发板上所用的芯片型号为
XC2VP30
,它有
2448Kbits
,也就是
306KB
的片上
SRAM
。本设计中
L1 Cache
中的使用的
SRAM
为
16KB
,其中
ICache
和
DCache
分别为
8KB
。
L2 Cache
为
256KB
,总数为
272KB
,充分使用了芯片的资源,同时也完全符合本设计的需求。
整个设计全部使用
Verilog
代码编写,在完成了对设计的综合与布局布线后,进行的后仿真结果如图
6
所示:
图6:布局布线后仿真波形
从图中可以看出在发生读
/
写操作并且
Cache
都命中的时候,微处理器按照流水线的方式在运行。当读
/
写操作遇到了
Cache
缺失问题时,流水线就被阻塞了,
Cache
中的控制器开始处理缺失问题。等缺失处理完之后,流水线恢复运行,微处理器回到阻塞前的状态。
使用开发板上的
100MHz
晶振,并通过
Xilinx
提供的
DCM
模块将频率倍频到
200MHz
。在把编译后的代码下载到
FPGA
芯片之后,系统能够稳定地运行,达到了预期的目的。
6 结 论
本文以具有普遍意义的兼容MIPS指令微处理器作为原型,来研究在流水线型微处理器中如何实现一种Cache的结构。并通过对Cache读/写过程的分析,采用在写操作中加入写缓存的方式,使得设计的Cache在不发生缺失的情况下读/写操作都只要一个时钟周期就可以完成,大大提高了流水线型微处理器的效率。
http://www.360doc.com/content/11/1013/00/1317564_155625188.shtml