我正在尝试在verilog中实现一个4路缓存,但我对缓存查找方案有一些困惑。说我有以下规格:
C = ABS
C = 1KB
A = 4
B = 128 bits (4 DWORD)
S = C/AB = (8192)/(4*128) = 16
offset = lg(B) = 7 bits
index = lg(S) = 4 bits
tag = 32 - offset - index = 21 bits
C: Capacity in data arrays
A: Way-Associativity
B: Block Size (Cacheline)
How many bytes in a block
S: Number of Sets:
A set contains blocks sharing the same index
在我的记忆中,我有:
H 0000_0000 0000 0000 0000 0000 0000 0000 0|000 0|000 0000
E 0000_0004
L 0000_0008
L 0000_000C
O 0000_0010 0000 0000 0000 0000 0000 0000 0|000 0|001 0000
0000_0014
W 0000_0018
O 0000_001C
R 0000_0020 0000 0000 0000 0000 0000 0000 0|000 0|010 0000
L 0000_0024
D 0000_0028
! 0000_002C
假设我刚刚开始,我在地址0x0000_0000处请求加载字,因为我的缓存是空的,我会将HELL
写入4个阵列之一的索引0上的缓存行。
然后我在地址0x0000_0010请求另一个加载字,此时我很困惑。
我的问题是,由于我的标记和索引是相同的,所以它是一个匹配,但我的缓存行中没有单词O
。在这种情况下我的缓存应该做什么?我是否将HELL
踢出并在同一个数组中写O WO
?如果是这样,我应该如何区分这两个地址,因为我们只查看标记和索引位?
我想的另一种方式是,因为它是一个命中,缓存不应该被驱逐,因为我们找到了一个匹配。但那场比赛没有我要求的实际字数。因此,如果我不进行替换,这种逻辑是错误的,但我的缓存很受欢迎。我刚刚进入了逐出和缓存命中之间的循环逻辑。
答案 0 :(得分:1)
更新后,问题变得清晰:internalPublish
应该是以字节为单位的大小,但您已经使用了位大小。地址中正确的偏移位数是log2(16)= 4.如果将图中的B
分隔符移动到正确的位置,一切都会正常工作:您将看到每个16B块都有一个索引比前一个高1。
|
我还注意到你的地址是以前的36位,还有一个额外的H 0000_0000 0000 0000 0000 0000 0000 0000|0000|0000
E 0000_0004
L 0000_0008
L 0000_000C
O 0000_0010 0000 0000 0000 0000 0000 0000|0001|0000
0000_0014
...
块。我也仔细检查了索引位的数量:4个索引位表示16组4路中的每一个。 16 * 4 * 16B = 1024B,因此适用于1kiB缓存。
您遇到与in your previous question相同的问题,多个内存块会转到同一个缓存行,但原因不同。这表明您遇到了严重错误,因为一个缓存行必须足够大,以便使用相同的标记+索引位保存地址中的所有数据。