Cache在干嘛

Cache在干嘛 (友情提示:全是字)

(信号的命名跟指导书上是差不多的,建议看一下指导书上的那几个图,先把信号记住,下面会很多次提到相关信号。还有是一个Group里面有几部分的那个结构图,对于搭这玩意很有帮助)

建议先看wyl大佬写的总结,我搭的思路跟他差不多(感谢wyl大佬)。

我下面提到的Enable就是一开始MuxGroup译码出来的东西,对应wyl大佬的Sel,而wyl大佬的Enable就是同时考虑了我的Enable和stop得出的信号。

本纸只是粗略的写了一下cache的工作原理,希望可以帮助大家理解,有错误的地方请及时指出。

1.大体上

​ Cache是做为一个中转站,在CPU和RAM之间起到桥梁的作用,做为中间站点,本身要能存储一些信息,同时这些信息可以被更新,所以总体来看Cache做的工作有四个环境:

1.写入并且未命中:

​ 如果没有命中那直接写到内存里面就可以,把data和相关的标签连到RAM上就行。(直接把Cache当成RAM

2.写入并且命中:

​ 这个时候既要写入内存,同时Cache中对应的块也要更新,既然要更新就要有数据来源,本题中一个block里面是四个字,要更新同时更新,所以RAM里面提供了类似内部转发的东西,根据传入的地址(MuxGroup和Tag和MuxBlock)把要写入的字所在的块(4个字)全部输出来给Cache,以便下一个周期(上升沿或这个周期的末尾)更新Cache中的值(下一个周期内存也被真正更新)。

注:

MuxGroup:传进来的地址的4~5位,对应组号。

MuxBlock:传进来的地址的2~3位,注意它代表的是是块内哪个字,而不是组内哪个块,组内的块的序号没有任何意义,就是有空位就塞,没空位替换,要不然也不会比较全部四个块的Tag。

Tag:传进来的地址的6~11位,每个块的命门,判断是否命中的因素之一(另一个是V,也就是是否有效,只有V==1且外传Tag与块内tag相同时才算命中)。

3.读数且命中:

​ 这个时候需要输出从命中块中读出来的数据,因为Cache是分了四个组,每个组四个块,每个块四个字,所以先通过MuxForBlock模块在组内通过hit值筛选出来一个块,然后再通过MuxForGroup模块在组间通过MuxGroup信号筛选一下,这个时候得到了目的块,再通过MuxBlock筛选出块中想要的那个字(4选1)。

注:

MuxForBlock: 在Group中的一个子模块,负责筛输出哪个Block。

MuxForGroup:在Cache(最顶层)中的一个子模块,负责筛输出哪个组提供的Block。

4.读数且没有命中:

​ 这种情况下需要把内存中的块替换到Cache中,为了假装他很慢,要停五个周期,并且把读到的数据输出。

​ 这里设计的时候就有点麻烦还不是很好想,在判断出来没有命中(通过hit)并且是读数时(MemRead),RAM中计算出来stop为1,同时要保证stop接下来5个周期均为1,这就要求hit值不能改变,所以说在stop的时候是不能更新Cache的,因为一更新就会变成命中,hit一变那么stop就会变,所以说Cache是正儿八经停了五个周期。

在第六个周期stop变为0的时候,就可以根据读数(MemRead)和未命中(Hit为0)的信息去更新Cache,生成更新信号(由LRU计算出来的),并且在第六个周期结束的上升沿将数据真正更新到Cache中。

​ 更新的数据来源呢? 因为这五个周期是暂停并且保证第六个周期的指令不变(题干),所以地址就没有变,那么通过组合逻辑从RAM中读出来的块的数据就没有变,所以说这个块是一直准备好了的,只不过无法写到Cache里,当stop为0,时,LRU生成了更新信号,那么在下一个上升沿就可以把数据写进去(替换)。

​ 数据输出的话,通过上一段我们可以知道在第六个周期stop变为0,LRU据此生成更新信号,确定了哪个Block要更新(下面跑一遍的过程会提到),但是第六个周期数据是没有替换到Cache中的,因为缺一个上升沿让数据进到寄存器里面(只是确定了要更新,但是是下一个上升沿更新),但是我们又要输出数据,所以说这个时候就要把RAM中的数据输出来,实现的方式就是在MuxForGroup模块中在加一个多选器,当处于Memread&&!hit的状态时,选择RAM的数据输出。(注意一下,在MemWrite=1或者stop=1的时候输出0,所以说最后再把一下关,再选择一次就可以了。这样的话前五个周期stop为1,虽然是读数且未命中,选择了RAM的数据,但是最后把关过不了,还是输出0。在第六个周期,指令没变,Memread有效,并且结合前文,数据并没有写进Cache中,所以hit不变,还是没有命中,故选择RAM中数据,但此时stop为0,MemWrite为0,最后把关是可以过的,所以把RAM中的数据成功输出)。

(块内部的4选1用MuxBlock信号就可以)。
(其实好像可以下降沿写入Cache,但是我没细想)

​ 计数器的事等会再说,所以总的来看:

​ 对于写入,可以发现不管命没命中对于RAM的操作是一样的,都是存数,只不过命中了去更新Cache而已,所以说通过内部转发(RAM自带)先把数据准备好,之后计算更新信号就可以。对于读数,命中了就更新计数器,没命中暂停,等暂停结束更新Cache和计数器。

注:

本纸涉及到了好几个hit,在Group中每个块有一个hit(共4个)表示块中没中,这里命名为小小hit,在Cache中每个Group对应一个hit(共4个),表示这个组中没中,这里命名为小hit,四个小hit经过或运算变成上述提到的hit,也就是整体看来中没中。

2.跑一遍

​ 一起来跑一遍过程,首先Cache是分了四个组的,用G1~4表示,每个组有四个块。

​ 对于每个周期会传进来地址,数据和读写信号(clk和reset就不提了),根据地址可以分线得到Tag,MuxGroup,MuxBlock。

​ 之后先通过MuxGroup信号确定用哪个组(译码,对应组的Enable为1),之后在这个组里,可以通过传进来的Tag以及Block寄存器里面的V和tag判断每个块是不是命中了,生成4个小小hit(对应每个块是不是命中了),4个小小hit 一下变成小hit(注意或完之后与Enable 一下,如果说连组的位置都不对,即便tag和有效位都合理也没用),这个小hit就是这个组是不是中了,这个小hit会传到Cache这个最顶层中,跟其他三个组的小hit 一下变成hit,也就是Cache中没中,这个也是传入RAM的hit。这样子就可以得到stop信号。

​ 因为是组合逻辑,stop传回Group这个次顶层模块里面之后就可以计算一系列信号。

​ 首先是LRU可以根据stop和Enable,四个小小hit,四个counter值,读(写)信号计算四个Block的更新信号,这个更新信号可以用于判断Block是否更新并且用于判断counter的下一个行为(归不归零),也就是影响了Block和Counter中寄存器下一个周期的走向

(传到LRU的enable端口的值是 !stop&&Enable,因为暂停的时候不可以更新,所以四个更新信号必须是零

​ 而更新的数据就像前边所说的,对于读RAM这个组合逻辑行为而言,数据是一直准备好了的,只不过是等更新信号和一个上升沿而已。

​ 连线的时候不用考虑这么多,把接口写好假装他们都准备好了连就行(

​ 顺提一下,更新信号是1不意味着对应counter归零(命中且读也更新,但是不归零)错了错了 是命中且写也更新(指更新数据,counter不变) 但是不归零

注:

counter是每个Block都有一个的计数器。

3.再来说一下counter:

​ 对于ALL和Hit的计数器,就是MemRead且stop为0的时候,ALL加一,如果命中了Hit加一。(未命中且读导致的stop=1的时候是不加的)。

​ 至于每个Block对应的计数器counter,只有在读数并且命中读数并且未命中的第六个周期生成归零信号,并且在下一个周期一开始(上升沿)更新为0,也就是load个0。注意在stop(暂停信号)=1和Enable(Group用不用信号)=0的时候计数器不加1。(第二个点就是这么wa的,虽然没细想为啥)

补充:

感觉前边一段说的不是很清楚,打算重新捋一遍。

首先计数器counter就用logisim中自带的那个counter就行

在Cache中,计数器有三个行为:1.加一 2.归零 3.不变

1.先只考虑加一,那么有个MemRead信号就可以了,也就是连counter的左下角。

2.第二个是归零,我们把他叫做zero信号,归零要求上面标黑的两种情况任选一种,对于读数命中那就是MemRead和hit,对于读数未命中且第六周期,那就是MemRead和!hit和update(注意update是LRU生成的,不是小小hit,这个update包含了stop和enable的信息),zero就是这两种情况任选一种,那么得到zero信号之后,把他连到counter左上角就可以,也就是counter左上角为1的时候load0(constant 0提前连好),但是需要注意counter在左上左下均为1的时候是减数的,所以需要把左下角加上一个!zero,也就是左上角为1的时候,左下角为0,归零,左上角为0的时候,左下角为1,可以选择加一或者不变(看MemRead)。

3.第三个是不变,前边只考虑了归零和MemRead引起的加一和不变,其实在暂停和enable=0的时候也是不变的(估计是怕爆),所以再把这两个信号分别在左上角左下角 一下就可以,0的时候左上角左下角全输入0,那么不变,为1的时候加一还是归零还是不变就是前边两种情况了。

(天干物燥,记得多喝水,不然会上火)

我嘴比较笨 可能说的不是太清楚 凑活看吧(
可恶怎么一改连评论都没有了 我还没来得及看(

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值