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

📄 if.v

📁 若干VHDL语言的源代码
💻 V
字号:
`include "Def_StructureParameter.v"
`include "Def_RegisterFile.v"

module IF(//Instruction fetch
		in_Instruction,		//input from instruction prefetched buffer
		in_InstructionWait,	//wait for the prefetch buffer 
		out_InstructionAddress,	//output to instruction prefetched buffer,this address is always word align even in thumb state
		//use to read pc
		out_FourthReadRegisterEnable,
		out_FourthReadRegisterNumber,
		in_FourthReadBus,
		//use to write pc
		out_SecondWriteRegisterEnable,
		out_SecondWriteRegisterNumber,
		out_SecondWriteBus,
		//can decoder go
		in_IDCanGo,
		//fetched instruction
		out_Instruction,
		out_ValidInstruction,
		out_AddressGoWithInstruction,
		out_NextInstructionAddress,//it is just the current PC value
		//signal relate to pc change in branch instruction
		in_ChangePC,
		in_NewPC,
		//signal send out by mem to update pc
		in_MEMChangePC,
		in_MEMNewPC,
		//thumb state
		in_ThumbState,
		clock,
		reset
		);

//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//		input and output declaration			//
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
input [`InstructionWidth-1:0] in_Instruction;
input in_InstructionWait;

output [`AddressBusWidth-1:0] out_InstructionAddress;
output	[`AddressBusWidth-1:0]	out_NextInstructionAddress;

output out_FourthReadRegisterEnable,out_SecondWriteRegisterEnable;
output [`Def_RegisterSelectWidth-1:0] out_FourthReadRegisterNumber,out_SecondWriteRegisterNumber;
input [`WordWidth-1:0] in_FourthReadBus;
output [`WordWidth-1:0] out_SecondWriteBus;

output	[`InstructionWidth-1:0]	out_Instruction;
output					out_ValidInstruction;
output	[`AddressBusWidth-1:0]		out_AddressGoWithInstruction;
reg	[`AddressBusWidth-1:0]		out_AddressGoWithInstruction,Next_out_AddressGoWithInstruction;

input in_IDCanGo;

input					in_ChangePC;
input	[`AddressBusWidth-1:0]		in_NewPC;

input					in_MEMChangePC;
input	[`AddressBusWidth-1:0]		in_MEMNewPC;

input					in_ThumbState;

input clock,reset;

//pipeline register
//if current FetchedInstruction valid?
reg					ValidInstruction;
reg					Next_ValidInstruction;
//fetched back instruction
reg	[`InstructionWidth-1:0]		FetchedInstruction;
reg	[`InstructionWidth-1:0]		Next_FetchedInstruction;
//the address send out to prefetch buffer
reg	[`AddressBusWidth-1:0]		FetchAddress;
reg	[`AddressBusWidth-1:0]		Next_FetchAddress;

//wire that read in pc
wire	[`AddressBusWidth-1:0]		PC;
//the next pc out to register file
reg	[`AddressBusWidth-1:0]		Next_PC;
//the pc+4 value
wire	[`AddressBusWidth-1:0]		PCAdd4or2;
wire	[`AddressBusWidth-1:0]		PCInc;

//this is the fetch address, always word align even in thumb state
assign	out_InstructionAddress={FetchAddress[`AddressBusWidth-1:2],2'b00};

//always read pc
assign	out_FourthReadRegisterEnable=1'b1;
assign	out_FourthReadRegisterNumber=`Def_PCNumber;

//always write to pc 
assign	out_SecondWriteRegisterEnable=1'b1;
assign	out_SecondWriteRegisterNumber=`Def_PCNumber;
assign	out_SecondWriteBus=Next_PC;

//output the fetched instruction
assign	out_Instruction=FetchedInstruction;
assign	out_ValidInstruction=ValidInstruction;
assign	out_NextInstructionAddress=PC;

//the readed pc
assign	PC=in_FourthReadBus;

//the pc+4 or PC+2
assign	PCInc={29'b0000_0000_0000_0000_0000_0000_0000_0,~in_ThumbState,in_ThumbState,1'b0};
assign	PCAdd4or2=PC+PCInc;


//decide the next state
always @(in_MEMChangePC	or
	in_MEMNewPC	or
	in_ChangePC	or
	in_NewPC	or
	in_IDCanGo	or
	in_InstructionWait	or
	in_ThumbState	or
	FetchAddress	or
	PC		or
	in_Instruction	or
	PCAdd4or2		or
	ValidInstruction	or
	FetchedInstruction	or
	out_AddressGoWithInstruction
)
begin
	if(in_MEMChangePC==1'b1)
	begin
		//in this case,all computation between if and mem will be clear
		//so just fetch and go
		Next_ValidInstruction=1'b0;
		Next_FetchedInstruction=`InstructionZero;
		Next_FetchAddress={in_MEMNewPC[`AddressBusWidth-1:1],1'b0};
		Next_PC=Next_FetchAddress;
		Next_out_AddressGoWithInstruction=PC;
	end
	else if(in_ChangePC==1'b1)
	begin
		//in this case,all computation between if and alu will be clear
		//so just fetch
		Next_ValidInstruction=1'b0;
		Next_FetchedInstruction=`InstructionZero;
		Next_FetchAddress={in_NewPC[`AddressBusWidth-1:1],1'b0};
		Next_PC=Next_FetchAddress;
		Next_out_AddressGoWithInstruction=PC;
	end
	else
	begin
		//no jump,just a normal case
		//take account of the in_InstructionWait
		if(in_IDCanGo==1'b1)
		begin
			//id can go
			if(in_InstructionWait==1'b1)
			begin
				//id can go,but prefetch can not go
				//make a blank in if
				Next_ValidInstruction=1'b0;
				Next_FetchedInstruction=`InstructionZero;
				//but the two address must preserve to serve the prefetch
				Next_FetchAddress=FetchAddress;
				Next_PC=PC;
				Next_out_AddressGoWithInstruction=PC;
			end
			else
			begin
				//id can go,and prefetch can also go
				Next_ValidInstruction=1'b1;
				Next_FetchedInstruction=in_Instruction;
				Next_FetchAddress=PCAdd4or2;
				Next_PC=PCAdd4or2;
				Next_out_AddressGoWithInstruction=PC;
			end
		end
		else
		begin
			//id can not go,preserve current state
			Next_ValidInstruction=ValidInstruction;
			Next_FetchedInstruction=FetchedInstruction;
			Next_FetchAddress=FetchAddress;
			Next_PC=PC;
			Next_out_AddressGoWithInstruction=out_AddressGoWithInstruction;
		end
	end
end

always @(posedge clock or negedge reset)
begin
	if(reset==1'b0)
	begin
		ValidInstruction=1'b0;
		FetchedInstruction=`InstructionZero;
		FetchAddress=PC;
		out_AddressGoWithInstruction=`AddressBusZero;

	end
	else
	begin
		ValidInstruction=Next_ValidInstruction;
		FetchedInstruction=Next_FetchedInstruction;
		FetchAddress=Next_FetchAddress;
		out_AddressGoWithInstruction=Next_out_AddressGoWithInstruction;
	end
end

endmodule

⌨️ 快捷键说明

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