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

📄 datacachecontroller.v

📁 若干VHDL语言的源代码
💻 V
📖 第 1 页 / 共 2 页
字号:
`include "Def_StructureParameter.v"
`include "Def_DataCacheController.v"


module DataCacheController(	//signal between mem and DataCacheController
			in_DataCacheAddress,		//data address
			io_DataCacheBus,		//data value for write and read
			in_DataCacheAccessEnable,	//enable access
			in_DataCacheBW,			//1 means byte,0 means word
			in_DataCacheRW,			//1 means read,0 means write
			out_DataCacheWait,		//wait for free
			//signal between DataCacheController and MemoryCotroller
			out_DataMemoryAddress,		//address goto memory
			io_DataMemoryBus,	//data value for write to memory
			out_DataMemoryEnable,		//enable accesss
			out_DataMemoryRW,			//1 means read, 0 means write
			in_DataMemoryWait,		//wait for memory
			//signal for clock and reset
			clock,
			reset
			);
//signal between mem and DataCacheController
input	[`AddressBusWidth-1:0]			in_DataCacheAddress;
inout	[`WordWidth-1:0]			io_DataCacheBus;
input						in_DataCacheAccessEnable;
input						in_DataCacheBW;
input						in_DataCacheRW;
output						out_DataCacheWait;

reg						out_DataCacheWait;


//signal between DataCacheController and MemoryCotroller
output		[`AddressBusWidth-1:0]		out_DataMemoryAddress;
inout		[`WordWidth-1:0]		io_DataMemoryBus;
output						out_DataMemoryEnable;
output						out_DataMemoryRW;
input						in_DataMemoryWait;

reg		[`AddressBusWidth-1:0]		out_DataMemoryAddress;
reg						out_DataMemoryEnable;
reg						out_DataMemoryRW;

input		clock,
		reset;

//use to deal with inout port
reg	[`WordWidth-1:0]			DCacheOutTmp;
reg						DCacheOutTmp2Bus;
reg	[`WordWidth-1:0]			MemoryOutTmp;
reg						MemoryOutTmp2Bus;

//the memory of cache
reg	[`ByteWidth-1:0]	Mem	[255:0];

reg	[`AddressBusWidth-1:6]	Tag	[15:0];

reg	[15:0]	Dirty;

reg	[15:0]	Valid;

//state machine of cache controller
reg	[`ByteWidth-1:0]	State;

//this reg will not be infer
//just as a wire
//have a match in cam?
reg				CAMMatch;
//which entry match
reg	[1:0]			CAMEntry;
//what is the previous access line of each section
reg	[1:0]		PrevAccess [3:0];
//what is the current replacable line of each section
reg	[1:0]		ReplaceEntry [3:0];
//content of replacable CAM entry 
reg	[`AddressBusWidth-1:6]	ReplaceContent	[3:0];

//write back word count
reg	[1:0]			WBWordCount,Next_WBWordCount;
//read in word count
reg	[1:0]			RIWordCount,Next_RIWordCount;

//write back address
reg	[`AddressBusWidth-1:0]	WBAddress;

//read in address
reg	[`AddressBusWidth-1:0]	RIAddress;

//have see the wait signal from memory?
reg	HaveWait;

//just for debug
wire	[1:0] PrevAccess0,PrevAccess1,PrevAccess2,PrevAccess3;
wire	[1:0] ReplaceEntry0,ReplaceEntry1,ReplaceEntry2,ReplaceEntry3;
wire	[`AddressBusWidth-1:6] Tag0,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8,Tag9,Tag10,Tag11,Tag12,Tag13,Tag14,Tag15;

assign	PrevAccess0=PrevAccess[0];
assign	PrevAccess1=PrevAccess[1];
assign	PrevAccess2=PrevAccess[2];
assign	PrevAccess3=PrevAccess[3];

assign	ReplaceEntry0=ReplaceEntry[0];
assign	ReplaceEntry1=ReplaceEntry[1];
assign	ReplaceEntry2=ReplaceEntry[2];
assign	ReplaceEntry3=ReplaceEntry[3];

assign	Tag0=Tag[0];
assign	Tag1=Tag[1];
assign	Tag2=Tag[2];
assign	Tag3=Tag[3];
assign	Tag4=Tag[4];
assign	Tag5=Tag[5];
assign	Tag6=Tag[6];
assign	Tag7=Tag[7];
assign	Tag8=Tag[8];
assign	Tag9=Tag[9];
assign	Tag10=Tag[10];
assign	Tag11=Tag[11];
assign	Tag12=Tag[12];
assign	Tag13=Tag[13];
assign	Tag14=Tag[14];
assign	Tag15=Tag[15];

//use to deal with io_DataCacheBus
assign	io_DataCacheBus=(DCacheOutTmp2Bus==1'b1)?DCacheOutTmp:`WordZ;

//use to deal with io_DataMemoryBus
assign	io_DataMemoryBus=(MemoryOutTmp2Bus==1'b1)?MemoryOutTmp:`WordZ;

integer ssycnt;
always @(posedge clock or negedge reset)
begin
	$monitor($time,"%x %x %x %x",Valid[ReplaceEntry[in_DataCacheAddress[5:4]]],ReplaceEntry[in_DataCacheAddress[5:4]],in_DataCacheAddress[5:4],Dirty[ReplaceEntry[in_DataCacheAddress[5:4]]]);
	if(reset==1'b0)
	begin
		//init memory
		for(ssycnt=0;ssycnt<=255;ssycnt=ssycnt+1)
		begin
			Mem[ssycnt]=`ByteZero;
		end

		for(ssycnt=0;ssycnt<=15;ssycnt=ssycnt+1)
		begin
			Tag[ssycnt]=26'b0000_0000_0000_0000_0000_0000_00;
			Dirty[ssycnt]=1'b0;
			Valid[ssycnt]=1'b0;
		end

		PrevAccess[2'b00]=2'b00;
		PrevAccess[2'b01]=2'b00;
		PrevAccess[2'b10]=2'b00;
		PrevAccess[2'b11]=2'b00;
		//$monitor($time,"%x",PrevAccess[2'b10]);

		//state machine
		State=`DCacheState_Idel;

		//inout manage
		DCacheOutTmp=`WordZ;
		DCacheOutTmp2Bus=1'b0;

		MemoryOutTmp=`WordZ;
		MemoryOutTmp2Bus=1'b0;

		//up to pipeline
		out_DataCacheWait=1'b0;

		//down to memory
		out_DataMemoryAddress=`WordZ;
		out_DataMemoryEnable=1'b0;
		out_DataMemoryRW=1'b0;

		//write and read word count
		WBWordCount=2'b00;
		RIWordCount=2'b00;

		//write back and read in address
		WBAddress=`AddressBusZero;
		RIAddress=`AddressBusZero;

		HaveWait=1'b0;
	end
	else
	begin
		//is not reset
		//normal operation
		case	(State)
		`DCacheState_Idel:
		begin
			if(in_DataCacheAccessEnable==1'b1)
			begin
				//a new access come
				if(CAMMatch==1'b1)
				begin
					//match up
					//state machine
					State=`DCacheState_Idel;
	
					if(in_DataCacheRW==1'b1)
					begin
						//read hit
						//inout manage
						if(in_DataCacheBW==1'b1)
						begin
							//read hit byte
							DCacheOutTmp={4{Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:0]}]}};
							DCacheOutTmp2Bus=1'b1;
						end
						else
						begin
							//read hit word
							DCacheOutTmp={Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b11}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b10}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b01}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b00}]};
							DCacheOutTmp2Bus=1'b1;
						end
					end
					else
					begin
						//write hit
						if(in_DataCacheBW==1'b1)
						begin
							//write hit byte
							DCacheOutTmp=`WordZ;
							DCacheOutTmp2Bus=1'b0;
							Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:0]}]=io_DataCacheBus[7:0];
						end
						else
						begin
							//write hit word
							DCacheOutTmp=`WordZ;
							DCacheOutTmp2Bus=1'b0;
							{Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b11}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b10}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b01}],Mem[{in_DataCacheAddress[5:4],CAMEntry,in_DataCacheAddress[3:2],2'b00}]}=io_DataCacheBus;
						end
						//set dirty bits
						Dirty[{in_DataCacheAddress[5:4],CAMEntry}]=1'b1;
					end

					MemoryOutTmp=`WordZ;
					MemoryOutTmp2Bus=1'b0;

					//up to pipeline
					out_DataCacheWait=1'b0;

					//down to memory
					out_DataMemoryAddress=`AddressBusZ;
					out_DataMemoryEnable=1'b0;
					out_DataMemoryRW=1'b0;

					//write and read word count
					WBWordCount=2'b00;
					RIWordCount=2'b00;

					//write back and read in address
					WBAddress=`AddressBusZero;
					RIAddress=`AddressBusZero;

					HaveWait=1'b0;
				end
				else
				begin
					//miss
					if(Valid[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]]}]==1'b0 || (Valid[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]]}]==1'b1 && Dirty[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]]}]==1'b0))
					begin
						//not valid or is not dirty
						//no need to write back
						//just go to read in
						State=`DCacheState_ReadIn;

						//inout manage
						DCacheOutTmp=`WordZ;
						DCacheOutTmp2Bus=1'b0;
					
						//write  word count
						WBWordCount=2'b00;
						
						//write back address
						WBAddress={Tag[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]]}],in_DataCacheAddress[5:4],WBWordCount,2'b00};

						//send out read address
						RIWordCount=2'b00;
						RIAddress={in_DataCacheAddress[`AddressBusWidth-1:4],RIWordCount,2'b00};

						//out put the first word to be write back
						MemoryOutTmp=`WordZero;
						MemoryOutTmp2Bus=1'b0;

						//up to pipeline
						out_DataCacheWait=1'b1;

						//down to memory
						out_DataMemoryAddress=RIAddress;
						out_DataMemoryEnable=1'b1;
						out_DataMemoryRW=1'b1;
					
						HaveWait=1'b0;
					end
					else
					begin
						//valid and dirty
						//must write back first
						State=`DCacheState_WriteBack;

						//inout manage
						DCacheOutTmp=`WordZero;
						DCacheOutTmp2Bus=1'b0;
					
						//write  word count
						WBWordCount=2'b00;
						
						//write back address
						WBAddress={Tag[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]]}],in_DataCacheAddress[5:4],WBWordCount,2'b00};

						//send out read address
						RIWordCount=2'b00;
						RIAddress={in_DataCacheAddress[`AddressBusWidth-1:4],RIWordCount,2'b00};

						//out put the first word to be write back
						MemoryOutTmp={Mem[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]],WBWordCount,2'b11}],Mem[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]],WBWordCount,2'b10}],Mem[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]],WBWordCount,2'b01}],Mem[{in_DataCacheAddress[5:4],ReplaceEntry[in_DataCacheAddress[5:4]],WBWordCount,2'b00}]};
						MemoryOutTmp2Bus=1'b1;

						//up to pipeline
						out_DataCacheWait=1'b1;

						//down to memory
						out_DataMemoryAddress=WBAddress;
						out_DataMemoryEnable=1'b1;
						out_DataMemoryRW=1'b0;
					
						HaveWait=1'b0;
					end
				end
			end
			else
			begin
				//no new access
				//state machine
				State=`DCacheState_Idel;

				//inout manage
				DCacheOutTmp=`WordZ;
				DCacheOutTmp2Bus=1'b0;

				MemoryOutTmp=`WordZ;
				MemoryOutTmp2Bus=1'b0;

				//up to pipeline
				out_DataCacheWait=1'b0;

				//down to memory
				out_DataMemoryAddress=`AddressBusZ;
				out_DataMemoryEnable=1'b0;
				out_DataMemoryRW=1'b0;

				//write and read word count
				WBWordCount=2'b00;
				RIWordCount=2'b00;

				//write back and read in address
				WBAddress=`AddressBusZero;
				RIAddress=`AddressBusZero;

				HaveWait=1'b0;
			end
		end//DCacheState_Idel

		`DCacheState_ReadIn:
		begin
			//miss and read in
			if(in_DataMemoryWait==1'b1)
			begin
				//memory is busy
				HaveWait=1'b1;
			end//in_DataMemoryWait==1'b1
			else
			begin
				//in_DataMemoryWait!=1'b1
				if(HaveWait==1'b1)
				begin
					//read in previous request memory element
					{Mem[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]],RIWordCount,2'b11}],Mem[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]],RIWordCount,2'b10}],Mem[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]],RIWordCount,2'b01}],Mem[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]],RIWordCount,2'b00}]}=io_DataMemoryBus;
					if(Next_RIWordCount==2'b00)
					begin
						//read in end
						//record the current accessed entry
						PrevAccess[RIAddress[5:4]]=ReplaceEntry[RIAddress[5:4]];
						Valid[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]]}]=1'b1;
						Dirty[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]]}]=1'b0;
						Tag[{RIAddress[5:4],ReplaceEntry[RIAddress[5:4]]}]=RIAddress[`AddressBusWidth-1:6];

						State=`DCacheState_Idel;

						DCacheOutTmp=`WordZ;
						DCacheOutTmp2Bus=1'b0;

						MemoryOutTmp=`WordZ;
						MemoryOutTmp2Bus=1'b0;

						//up to pipeline
						//now i will not release the cache
						//because if there have been a write miss
						//then at the next posedge there must be a write hit
						//if i release the cache now, then the pipeline will think that the write have finish
						//and pipeline will not continue to send the write request at next cycle,
						//so if i make the wait signal high will make the pipeline continue to send out write request next cycle
						//and the hold time of cache will be satisfy
						out_DataCacheWait=1'b1;

						//down to memory
						out_DataMemoryAddress=`AddressBusZ;
						out_DataMemoryEnable=1'b0;
						out_DataMemoryRW=1'b0;

						//write and read word count
						WBWordCount=2'b00;
						RIWordCount=2'b00;

						//write back and read in address
						WBAddress=`AddressBusZero;
						RIAddress=`AddressBusZero;

						HaveWait=1'b0;
					end
					else
					begin
						//read in not end yet
						//state machine
						State=`DCacheState_ReadIn;

						//inout manage
						DCacheOutTmp=`WordZ;
						DCacheOutTmp2Bus=1'b0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -