首页 > 编程知识 正文

计组存储器设计,cache控制器实验心得体会

时间:2023-05-06 18:26:22 阅读:254794 作者:4323

一、实验目的

1. 认识和掌握Cache控制器的原理及其设计方法;

2. 掌握Cache控制器的实现方法,代码实现方法。

 

二、 实验内容

本实验要求采用直接相联地址变换,实现Cache(数据Cache)及其地址变换逻辑(也叫Cache控制器)。CPU从Cache读数据,读到就送CPU,若读不到,还必须考虑先从主存中读取数据,然后再将数据写到Cache中,之后,将数据送往CPU;其次,还要考虑CPU修改Cache和存储器数据的情况。

说明:CLK为系统时钟(用于计数器计数控制等操作),CLR为系统总清零信号(清区表存储器、计数器),WCT为写Cache区表存储器信号,AB31..AB0为CPU访问内存的地址(地址总线),RD(为0,读)为Cache的读信号,CMWr(为1,写)为Cache和主存的写信号,MRd(为0,读)为主存的读信号,CA17..CA0为Cache地址,MD31..MD0为主存与Cache的数据传送线,D31..D0为Cache和CPU的数据传送线,LA3...LA0为块内地址。

 

三、 实验原理

    本实验采用的地址变换是直接相联映象方式,这种变换方式简单而直接,硬件实现很简单,访问速度也比较快,但是块的冲突率比较高。其主要原则是:主存中一块只能映象到Cache的一个特定的块中。

假设主存的块号为B,Cache的块号为b,则它们之间的映象关系可以表示为:

b = B mod Cb

其中,Cb是Cache的块容量。设主存的块容量为Mb,区容量为Me,则直接映象方法的关系如图1所示。把主存按Cache的大小分成区,一般主存容量为Cache容量的整数倍,主存每一个分区内的块数与Cache的总块数相等。直接映象方式只能把主存各个区中相对块号相同的那些块映象到Cache中同一块号的那个特定块中。例如,主存的块0只能映象到Cache的块0中,主存的块1只能映象到Cache的块1中,同样,主存区1中的块Cb(在区1中的相对块号是0),也只能映象到Cache的块0中,看图1。根据上面给出的地址映象规则,整个Cache地址与主存地址的低位部分是完全相同的。

     

        

           直接映象方式的地址变换过程如图2 所示,主存地址分为三个部分:区号E、块号B和块内地址W;Cache地址分为两部分:块号b和块内地址w。主存地址中的块号B与Cache地址中的块号b是完全相同的。同样,主存地址中的块内地址W与Cache地址中的块内地址w也是完全相同的,主存地址比Cache地址长出来的部分称为区号E。

 

          

          在程序执行过程中,当要访问Cache时,为了实现主存块号到Cache块号的变换,需要有一个存放主存区号的小容量存储器(称为区表存储器),这个存储器的容量与Cache的块数相等,字长为主存地址中区号E的长度,另外再加一个有效位。

         从主存地址到Cache地址的变换过程中,首先用主存地址中的块号B去访问区表存储器(用块号B作为区表存储器的地址,访问它),然后,将读出来的区号与主存地址中的区号E进行比较,比较结果相等,有效位为1,则Cache命中,表示要访问的那一块已经装入到Cache中了,可以直接用块号及块内地址组成的缓冲地址到缓存Cache中取数,把读出来的数据送往CPU;如果比较结果不相等,有效位为1,可以进行替换,如果有效位为0,可以直接调入所需块。至于比较不相等情况,不论有效位是1或0均为Cache没有命中,或称为Cache失效,表示要访问的那个块还没有装入到Cache中,这时,要用主存地址去访问主存储器,先把该地址所在的块读到Cache中,然后CPU再从Cache中读取该地址中的数据。Cache和CPU以及存储器的关系如下图所示。

   

       

       如图3所示,32位主存地址为AB31..AB0(地址总线),RD(为0,读)为Cache的读信号,CMWr(为1,写)为Cache和主存的写信号,MRd(为0,读)为主存的读信号,D31..D0为CPU与Cache的数据传送线,MD31..MD0为存储器RAM与Cache的数据传送线。

     如图4所示,区号E取14位,块号B为14位,块内地址为4位,这样Cache地址就是18位了,其中Cache块号b为14位,块内地址w为4位,所以Cache容量为256KB(2^18)个单元,块号b取14位,那么Cache分为16KB(2^14)块,块内地址w取4位,则每块为16个单元(每个单元一个字节)。


       

       实现Cache的存储体的方法是先实现一个8位的存储单元,然后用这个8位的存储单元来构成一个256Kb X 8位的Cache(地址18位)。

      再实现一个15位(14+1)的存储单元,然后,用这个15位的存储单元来构成一个16k X 15位的区表存储器(地址14位与块号B相同),用来存放区号(14位)和有效位(1位)。在这个部分中,还要实现一个区号E比较器,也就是如果主存地址的区号E和区表存储器中按块号B取出的相应单元中的区号E相等,有效位标志为M,且有效位为1,M=1时,则Cache命中,否则Cache失效,M=0时表示Cache失效。

      当Cache命中时,就将Cache存储体中相应单元的数据送往CPU,这个过程比较简单。当Cache失效时,就将主存中相应块中的数据读出写入Cache中,这样Cache控制器就要产生主存储器的读信号MRd(为0,读),由于每个Cache块占十六个单元,按32 位(4个字节)为访问存储器单位,那么需要连续访问4次主存,读取存储器中该块的数据,即16个字节,然后写入Cache相应块中,最后再修改区表存储器(标志位M=1)。至于访问主存的方法,要用到计数器。写数据时,如果Cache中有该地址数据,则修改,同时,修改存储器该地址内容(CMWr为1,写,为主存的写信号);如果Cache中无该地址数据,就直接修改存储器该地址单元内容,这时无需修改Cache。读/写存储器时,要注意互锁情况。

二、 实验设备

电脑一台、Xilinx ISE 软件一套。

三、 实验分析与设计

(1)实验的分析

     有了缓存之后,CPU就可以通过减少对内存的方位来减少开销。即每一次从内存中获取数据之后先将数据存进缓存中,并做相应的标记。这样下一次再访问相同的数据时,就可以直接从缓存中命中获取相应的数据而不用再访问内存。

我们在这个实验中采用的是直接映射方法,即内存中的某一个数据块在缓存中只能有唯一的内存块位置与之对应。也就是说,为了使缓存与内存中的数据有某种对应关系,我们将缓存和内存中的空间划分为一块块的内存块,而在内存和缓存中,内存块的大小应该是一样大的。由于缓存的大小相对于内存来说要小得多,所以每一次只有内存的一些内存块能够对应到缓存中的内存块中。所以在缓存中必需有一张表来记录当前缓存中所存的内存块是对应主存中的哪一个内存块,即上面原理分析所讲到的区表存储器。由于一开始缓存中是没有数据块的,所以表中还应该有一个标记位来标记是否已经有内存块存进Cache中相应的位置。

(2)实验的设计

     根据设计好的数据通路图可以知道,我们只需设计Cache和RAM两个模块。Cache中除了用来存储数据的空间之外还应该有一些空间来记录当前在缓存中每一个内存块对应主存相应的某个内存块和标记位。而那些来自CPU的数据,比如写入内存的数据或是访问的地址Address或是控制信号RD,CMWr直接在测试文件中提供就可以了。

首先是Cache模块的设计:

由于地址中有14位是作为内存块的块号,还有4位用来做块内地址,所以在缓存中应该得有2^18的空间来做缓存的空间大小,而且每一个空间的大小应该有8位。另外,因为有2^14的数据块,所以用来标记内存块的表的大小应该有2^14个空间,而且用来存相应内存地址所在的区号的位数是14位,所以表的每一个空间的位数是14位。

因为一开始没有数据块被载入缓存中,所以缓存中表中的标记为应该初始化为0。完成初始化之后就可以检测各个输入的不同信号来使缓存Cache执行不同的操作。如果要读的数据不在缓存中,就需要从RAM中获取,由于每一个内存块是16个字节,但是每次从RAM中拿回来的数据只有一个字大小即4个字节。所以每一次从主存RAM中读一个内存块到缓存Cache中应该要4次主存的访问。所以需要一个用于计数的变量counter。每从主存中读4个字节数据进入缓存时,counter加1,当counter为4时,说明整个内存块已经读完了,所以这是在设置相应的信号使缓存不再从主存读数据。同时这个counter的作用还可以使缓存知道要修改内存块中具体的那个内存块内地址上的值。又内存块中有16个地址,所以在主存中也应该知道要相应内存块中的哪个地址的数据,可以通过在Cahce模块传递一个类似counter作用的信号给RAM模块来实现。

同时,当有需要修改缓存中某个地址的数据时,也是应该检测地址对应的缓存块是否已经载入缓存中。

具体的实现代码如下:





       对于RAM的设计,首先应该考虑其存储数据空间的设置。这里设计的是1G即2^20的空间,所以要注意之后测试代码中地址就应该注意不能超过最大的地址20’hfffff。虽然地址有32位,但是如果开一个2^ 32大小的空间会导致初始化RAM中的数据时耗时过多。

      为了便于后续的测试,我在初始化的时候对某些具体的地址赋了具体的值。初始化完毕之后就是要检测各个输入的变量。RAM需要的信号量比较少,就只有MRd,CMWr以及从缓存传进来的计数用的变量。其中当MDr为0时,将内存中的数据读出并放到输出端口,传递给缓存Cache。当CMWr为1时,修改相应内存地址的数据。

具体的代码如下:




       然后是在主模块里面对Cache模块和RAM模块进行实例化,具体代码如下:



(3)实验的测试和结果的分析

在测试代码中我分别检测了读缓存中不存在的数据,读缓存中存在的数据,修改即在主存有在缓存中的数据,也修改了只在主存中的数据等四种情况。具体的测试代码如下:






    

【Java技术专题】较为深度的分析JVM的直接内存「上篇」RoadRunner有哪些特性产品优势 数据仓库 UDW DorisLinux服务器安装FTP服务

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。