⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.h

📁 SystemC 实现 MIPS 处理器 源代码
💻 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 + -