我有一些函数可以处理来自具有这些规范的缓存的读取请求:
缓存有两级:
- 一个缓存块是16字节。
- 每个地址访问1个字节的数据。
- L1 缓存是一个 64 字节的 2 路组关联缓存。
- L2 缓存是一个 256 字节的 4 路组关联缓存。
- 缓存是包容性的,即L1缓存中的数据也会保留在L2缓存中。其他 换句话说,L1 中的数据是 L2 中数据的子集(此假设简化了您的设计)。
- 缓存采用先进先出的缓存替换策略
这里是
void write()
将被实现的代码(它位于第一个代码片段的末尾)
我已经完成了所有读取请求处理,请不要在您对我的 SO 问题的回复中更改它们。请仅根据以上信息和以下代码编辑 write()
#include "cacheSim.h"
#include <string.h>
#include <stdlib.h>
// In this question, we will assume DRAM will take a 4-byte values starting from 0 to
void init_DRAM()
{
unsigned int i=0;
DRAM = malloc(sizeof(char) * DRAM_SIZE);
for(i=0;i<DRAM_SIZE/4;i++)
{
*((unsigned int*)DRAM+i) = i;
}
}
void printCache()
{
int i,j,k;
printf("===== L1 Cache Content =====\n");
for(i=0;i<2;i++)
{
printf("Set %d :", i);
for(j=0;j<2;j++)
{
printf(" {(TAG: 0x%x)", (unsigned int)(L1_cache[i][j].tag));
for(k=0;k<16;k++)
printf(" 0x%x,", (unsigned int)(L1_cache[i][j].data[k]));
printf(" |");
}
printf("\n");
}
printf("===== L2 Cache Content =====\n");
for(i=0;i<4;i++)
{
printf("Set %d :", i);
for(j=0;j<4;j++)
{
printf(" {(TAG: 0x%x)", (unsigned int)(L2_cache[i][j].tag));
for(k=0;k<16;k++)
printf(" 0x%x,", (unsigned int)(L2_cache[i][j].data[k]));
printf(" |");
}
printf("\n");
}
}
u_int32_t read_fifo(u_int32_t address)
{
u_int32_t data = *((u_int32_t*)(DRAM + address));
return data;
}
unsigned int getL1SetID(u_int32_t address)
{
unsigned int setID = (address >> 4) & 0x1;
return setID;
}
unsigned int getL1Tag(u_int32_t address)
{
unsigned int tag = address >> 5;
return tag;
}
unsigned int getL2SetID(u_int32_t address)
{
unsigned int setID = ((address >> 4) & 3);
return setID;
}
unsigned int getL2Tag(u_int32_t address)
{
unsigned int tag = address >> 6;
return tag;
}
int L1lookup(u_int32_t address)
{
unsigned int setID = getL1SetID(address);
unsigned int tag = getL1Tag(address);
for(int i=0; i<2; i++)
{
if(L1_cache[setID][i].tag == getL1Tag(address)){
return 1;
}
}
return 0;
}
int L2lookup(u_int32_t address)
{
unsigned int setID = getL2SetID(address);
unsigned int tag = getL2Tag(address);
for(int i=0; i<4; i++)
{
if(L2_cache[setID][i].tag == getL2Tag(address))
return 1;
}
return 0;
}
void write(u_int32_t address, u_int32_t data)
{
unsigned int setID = getL1SetID(address);
unsigned int tag = getL1Tag(address);
//This is the extent of what I've done
}
这里还有一些结构函数可以帮助你理解上面使用的不同结构的参数:
#include<stdlib.h>
#include<stdio.h>
#define DRAM_SIZE 1048576
typedef struct cb_struct {
unsigned char data[16]; // One cache block is 16 bytes.
u_int32_t tag;
u_int32_t timeStamp; /// This is used to determine what to evict. You can update the timestamp using cycles.
}cacheBlock;
typedef struct access {
int readWrite; // 0 for read, 1 for write
u_int32_t address;
u_int32_t data; // If this is a read access, value here is 0
}cacheAccess;
// This is our dummy DRAM. You can initialize this in anyway you want to test.
unsigned char * DRAM;
cacheBlock L1_cache[2][2]; // Our 2-way, 64 byte cache
cacheBlock L2_cache[4][4]; // Our 4-way, 256 byte cache
我可以理解读取功能,但我不太明白如何执行写入功能,任何帮助将不胜感激。