📄 cache.h
字号:
#ifndef CACHE_H
#define CACHE_H
#include "STDAFX.h"
//Cache的最小存储单元
struct Cache_unit
{
bool valid;
bool changed;
sc_uint<12> mark;
sc_uint<32> data;
};
struct Cache_block
{
//每组cache
Cache_unit unit[4];
//标记各路数据的使用情况
sc_uint<6> lastused;
};
SC_MODULE(Cache)
{
//Cache数据 大小1KB
Cache_block cache_data[256];
//内存数据 大小4MB
sc_uint<32> mem_data[10000];
//要访问的内存地址
sc_in<sc_uint<32> > Cache_Mem_address;
//读操作
sc_in<bool> Cache_isRead;
//写操作
sc_in<bool> Cache_isWrite;
sc_in_clk clk;
//写的数据
sc_in<sc_uint<32> > Cache_Write_data;
//输出要访问的数据
sc_out<sc_uint<32> > Cache_Mem_dataout;
int read_times,write_times;
//LRU更新算法
//最近最少使用算法
void update_used(sc_uint<6> & last,unsigned int now)
{
if (last.range(1,0)==now) return;
last=last << 2;
last.range(1,0)=now;
}
//LRU寻找最远未使用的路编号
unsigned int not_used(sc_uint<6> last)
{
bool app[4];
memset(app,false,sizeof(app));
app[last.range(5,4).to_uint()]=true;
app[last.range(3,2).to_uint()]=true;
app[last.range(1,0).to_uint()]=true;
int i;
for (i=3;i>=0;--i) if (!app[i]) return i;
return 0;
}
//将内存地址address中的新数据加入cache编号为index的路中
void insert_newdata(unsigned int index,unsigned int mark,unsigned int address)
{
int i,j;
//寻找一组中是否有空位
for (i=0;i<=3;++i)
{
if (cache_data[index].unit[i].valid==false)
{
//从内存中读入数据到cache
read_from_mem(index,i,address);
cache_data[index].unit[i].valid=true;
cache_data[index].unit[i].mark=mark;
//更新LRU的值
update_used(cache_data[index].lastused,i);
Cache_Mem_dataout.write(cache_data[index].unit[i].data);
//cout<<"insert new data"<<endl;
return ;
}
}
//cout<<"Cache need update"<<endl;
//无空位时需要更新,采用LRU算法找出最近最少使用的数据
j=not_used(cache_data[index].lastused);
//如果原有数据已更改,需要执行写回操作
if (cache_data[index].unit[j].changed==true)
{
//计算原始地址
sc_uint<22> add;
add.range(21,10)=cache_data[index].unit[j].mark;
add.range(9,2)=index;
add.range(1,0)=0;
//写回
write_to_mem(cache_data[index].unit[j].data,add);
}
read_from_mem(index,j,address);
cache_data[index].unit[j].mark=mark;
cache_data[index].unit[j].changed=false;
update_used(cache_data[index].lastused,j);
Cache_Mem_dataout.write(cache_data[index].unit[j].data);
return ;
}
//读操作
void read()
{
if (Cache_isRead.read()==false) return;
unsigned int index=Cache_Mem_address.read().range(9,2);
unsigned int mark=Cache_Mem_address.read().range(21,10);
int i,j;
//判断cache是否命中
for (i=3;i>=0;--i)
{
if (cache_data[index].unit[i].mark==mark && cache_data[index].unit[i].valid==true)
{
//cout<<"Cache Found the data"<<endl;
Cache_Mem_dataout.write(cache_data[index].unit[i].data);
//更新LRU的值
update_used(cache_data[index].lastused,i);
return;
}
}
//Cache Miss 进行更新操作
//cout<<"Cache read Miss"<<endl;
unsigned int address=Cache_Mem_address.read();
insert_newdata(index,mark,address);
}
//写操作
void write()
{
if (Cache_isWrite.read()==false) return;
unsigned int index=Cache_Mem_address.read().range(9,2);
unsigned int mark=Cache_Mem_address.read().range(21,10);
unsigned int value=Cache_Write_data.read();
int i,j;
//判断cache是否命中
for (i=3;i>=0;--i)
{
if (cache_data[index].unit[i].mark==mark && cache_data[index].unit[i].valid==true)
{
cout<<"Cache Found the data which should be changed"<<endl;
cache_data[index].unit[i].changed=true;
cache_data[index].unit[i].data=value;
update_used(cache_data[index].lastused,i);
return;
}
}
//Cache Miss 进行更新操作
cout<<"Cache write Miss"<<endl;
insert_newdata(index,mark,value);
}
//从内存中读入数据
void read_from_mem(unsigned int index,unsigned int road,unsigned int address)
{
read_times++;
cache_data[index].unit[road].data=mem_data[address/4];
return;
}
//向内存中写入数据
void write_to_mem(unsigned int data,unsigned int address)
{
write_times++;
mem_data[address/4]=data;
return ;
}
SC_CTOR(Cache)
{
SC_METHOD(read);
sensitive<<Cache_Mem_address<<Cache_isRead<<Cache_isWrite<<Cache_Write_data;
dont_initialize();
SC_METHOD(write);
sensitive_neg<<clk;
//纪录内存访问次数初始化
read_times=write_times=0;
//内存数据初始化
int i,j;
for (i=0;i<10000;++i) mem_data[i]=i;
mem_data[0]=15;
mem_data[1]=100;
mem_data[2]=1000;
mem_data[3]=10000;
mem_data[4]=100000;
//cache数据初始化
for (i=0;i<256;++i)
{
cache_data[i].lastused=0;
for (j=0;j<4;++j)
{
cache_data[i].unit[j].valid=false;
cache_data[i].unit[j].changed=false;
}
}
}
//写回内容,仅用于仿真
void Write_back()
{
int i,j;
sc_uint<22> add;
//数据写回
for (i=0;i<256;++i)
for (j=0;j<4;++j)
{
if (cache_data[i].unit[j].valid==true)
{
cout<<i<<" "<<j<<endl;
//计算原始地址
add.range(21,10)=cache_data[i].unit[j].mark;
add.range(9,2)=i;
add.range(1,0)=0;
//写回
cout<<cache_data[i].unit[j].data<<" "<<add<<endl;
write_to_mem(cache_data[i].unit[j].data,add);
}
}
}
};
SC_MODULE(Cache_test)
{
sc_in_clk clk;
sc_in<sc_uint<32> > memdata;
sc_out<sc_uint<22> > memaddress;
sc_out<bool> isread;
int i;
void entry()
{
memaddress.write(i);
isread.write(true);
i+=4;
}
void getdata()
{
//cout<<sc_simulation_time()<<endl;
//Print(memdata.read(),cout);
}
SC_CTOR(Cache_test)
{
i=0;
SC_METHOD(entry);
sensitive_pos<<clk;
dont_initialize();
SC_METHOD(getdata);
sensitive<<memdata;
dont_initialize();
}
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -