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

📄 decoder_arm.v

📁 若干VHDL语言的源代码
💻 V
📖 第 1 页 / 共 5 页
字号:
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//i assume that there is at most 32 function component, each 	//
// at most have 8 entry	outstand operation entry,so a byte will	//
//be enough for the tomasulo source operand that come from 	//
//function component,if a source come from register file entry	//
//then i will direct read it from register file and tag it as 	//
//ready								//
//a all zero component entry means null device,and you can not	//
//treat it like normal device					//
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
`include "Def_StructureParameter.v"
`include "Def_RegisterFile.v"
`include "Def_ARMALU.v"
//`include "Def_ComponentEntry.v"
`include "Def_ALUType.v"
`include "Def_Decoder.v"
`include "Def_BarrelShift.v"
`include "Def_ALUType.v"
`include "Def_mem.v"
`include "Def_psr.v"
`include "Def_Mode.v"
`include "Def_Exception.v"

module Decoder_ARM(	in_ValidInstruction_IFID,
			in_PipelineRegister_IFID,
			in_AddressGoWithInstruction,
			in_NextInstructionAddress,
			out_IDOwnCanGo,
			//signal for register file
			out_LeftReadRegisterEnable,
			out_LeftReadRegisterNumber,
			out_RightReadRegisterEnable,
			out_RightReadRegisterNumber,
			//use to read the shift count stored in register
			out_ThirdReadRegisterEnable,
			out_ThirdReadRegisterNumber,
			//signal for register file
			//signal for ALU
			out_ALUEnable,
			out_ALUType,
			out_ALULeftRegister,
			out_ALURightRegister,
			out_ALUThirdRegister,
			out_ALULeftFromImm,
			out_ALURightFromImm,
			out_ALUThirdFromImm,
			out_CPSRFromImm,
			out_SPSRFromImm,
			out_ALUTargetRegister,
			out_ALUExtendedImmediateValue,	//extended 32bit immediate value ,go to right bus
			out_ALURightShiftType,
			out_ALUSecondImmediateValue,	//serve as the shift count
			out_SimpleALUType,		//serve for the pre index mode of load/store
			out_SimpleALUTargetRegister,
			out_ALUMisc,			//some special signal
			out_ALUPSRType,
			out_AddressGoWithInstruction2ALU,
			out_NextAddressGoWithInstruction2ALU,
			//signal for mem stage
			out_MEMEnable,
			out_MEMType,
			out_MEMTargetRegister,
			out_SimpleMEMType,
			out_SimpleMEMTargetRegister,
			out_MEMPSRType,
			//Thumb state
			in_ThumbState,
			in_IsInPrivilegedMode,
			//interrupt signal
			in_TrueFiq,
			in_TrueIrq,
			//can AUL go
			in_ALUCanGo,
			//clear internal state
			in_ChangePC,
			in_MEMChangePC,
			clock,
			reset
			);


//////////////////////////////////////////////////
//////////////////////////////////////////////////
//	input and output declaration		//
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//signal come from if register
input 							in_ValidInstruction_IFID;
input 	[`InstructionWidth-1:0]			in_PipelineRegister_IFID;
input	[`AddressBusWidth-1:0]			in_AddressGoWithInstruction,in_NextInstructionAddress;

//can id its own go
output							out_IDOwnCanGo;

//the three read register signal
output							out_LeftReadRegisterEnable,
								out_RightReadRegisterEnable,
								out_ThirdReadRegisterEnable;
output	[`Def_RegisterSelectWidth-1:0]	out_LeftReadRegisterNumber,
								out_RightReadRegisterNumber,
								out_ThirdReadRegisterNumber;
								

//signal go to alu execute stage
output							out_ALUEnable;		//only when there is space for new operation and a known valid instruction can it be 1'b1
output	[`ByteWidth-1:0]				out_ALUType;		//what type of main alu thread 
//the source operand register,the alu will use it to enable forwarding
output	[`Def_RegisterSelectWidth-1:0]	out_ALULeftRegister,
								out_ALURightRegister,
								out_ALUThirdRegister;
//if the source operand come from immediate value,then forwording will be disable
output							out_ALULeftFromImm,
								out_ALURightFromImm,
								out_ALUThirdFromImm,
								out_CPSRFromImm,
								out_SPSRFromImm;
//target register of the main alu result,will be use to enable forwarding and write back
output	[`Def_RegisterSelectWidth-1:0]	out_ALUTargetRegister;
//the immediate value go to right operand of alu
output	[`WordWidth-1:0]				out_ALUExtendedImmediateValue;
//shift type of right operand
output	[`Def_ShiftTypeWidth-1:0]		out_ALURightShiftType;
//the shift count specify in immediate field,will go to the third read bus
output	[`WordWidth-1:0]				out_ALUSecondImmediateValue;

//simple thread operation type ad target register
output	[`ByteWidth-1:0]				out_SimpleALUType;
//will be use to write back and enable forwarding
output	[`Def_RegisterSelectWidth-1:0]	out_SimpleALUTargetRegister;
//some special signal
output	[`WordWidth-1:0]		out_ALUMisc;
output	[`ByteWidth-1:0]		out_ALUPSRType;
output	[`AddressBusWidth-1:0]		out_AddressGoWithInstruction2ALU,out_NextAddressGoWithInstruction2ALU;
reg	[`AddressBusWidth-1:0]		out_AddressGoWithInstruction2ALU,out_NextAddressGoWithInstruction2ALU;


//the operations for main mem and simple mem thread
//the alu stage will hold these information untill this instruction reach mem stage
output							out_MEMEnable;
output	[`ByteWidth-1:0]				out_MEMType;
output	[`Def_RegisterSelectWidth-1:0]	out_MEMTargetRegister;

output	[`ByteWidth-1:0]				out_SimpleMEMType;
output	[`Def_RegisterSelectWidth-1:0]	out_SimpleMEMTargetRegister;
output	[`ByteWidth-1:0]				out_MEMPSRType;


//thumb state
input	in_ThumbState;

input	in_IsInPrivilegedMode;

//interrupt signal
input	in_TrueFiq,in_TrueIrq;

//the decoder need to know if alu can go
//if not, decoder will not send out useful information
input								in_ALUCanGo;

//branch signal
input			in_ChangePC,in_MEMChangePC;

//global signal
input clock,reset;

//reg style declaration of output signal
reg								out_IDOwnCanGo;
reg								out_LeftReadRegisterEnable,
								out_RightReadRegisterEnable,
								out_ThirdReadRegisterEnable;
reg		[`Def_RegisterSelectWidth-1:0]	out_LeftReadRegisterNumber,
								out_RightReadRegisterNumber,
								out_ThirdReadRegisterNumber;
reg								out_ALUEnable;
reg		[`ByteWidth-1:0]				out_ALUType;
reg								out_ALULeftFromImm,
								out_ALURightFromImm,
								out_ALUThirdFromImm,
								out_CPSRFromImm,
								out_SPSRFromImm;
reg		[`Def_RegisterSelectWidth-1:0]	out_ALUTargetRegister;
reg		[`WordWidth-1:0]				out_ALUExtendedImmediateValue;
reg		[`Def_ShiftTypeWidth-1:0]		out_ALURightShiftType;
reg		[`WordWidth-1:0]				out_ALUSecondImmediateValue;

reg		[`ByteWidth-1:0]				out_SimpleALUType;
reg		[`Def_RegisterSelectWidth-1:0]	out_SimpleALUTargetRegister;
reg		[`WordWidth-1:0]				out_ALUMisc;
reg		[`ByteWidth-1:0]		out_ALUPSRType;

reg								out_MEMEnable;
reg		[`ByteWidth-1:0]				out_MEMType;
reg		[`Def_RegisterSelectWidth-1:0]	out_MEMTargetRegister;

reg		[`ByteWidth-1:0]				out_SimpleMEMType;
reg		[`Def_RegisterSelectWidth-1:0]	out_SimpleMEMTargetRegister;
reg		[`ByteWidth-1:0]				out_MEMPSRType;


//these register will not be infer
//left right third read register
//main and simple thread target register
reg		[`Def_RegisterSelectWidth-1:0]	LeftRegisterNumber,
								RightRegisterNumber,
								ThirdRegisterNumber,
								TargetRegisterNumber,
								SecondTargetRegisterNumber;

//these register will not be infer

//if current register number will be access in LDM or STM
reg	[`Def_RegisterSelectWidth-1:0]	RegCountInLDMSTM;
reg	IfCurrentRegAccessByLDMSTM;
reg	IsFirstAccess;

//map ARM alu type to independante alu type
reg [`ByteWidth-1:0] ALUTypeMapped;

//in fact this three wire is exclusive to each other
//there will not use at the same time
//so some type of share method must be found to share the same adder
wire	[`WordWidth-1:0]		PCAdder4Result;
wire	[`WordWidth-1:0]		PCAdder8or4Result;
wire	[`WordWidth-1:0]		PCAdder12or4Result;

//pipeline register
//previous operation will write register from MEM
reg	PrevOperationWantWriteRegisterFromMEM;
reg	Next_PrevOperationWantWriteRegisterFromMEM;
reg	[`Def_RegisterSelectWidth-1:0]	PrevWriteRegister;
reg	[`Def_RegisterSelectWidth-1:0]	Next_PrevWriteRegister;

//use in block transfer for register number
reg	[`Def_RegisterSelectWidth-1:0]	IncRegNumber,DecRegNumber;
reg	[`Def_RegisterSelectWidth-1:0]	Next_IncRegNumber,Next_DecRegNumber;

wire	[`Def_RegisterSelectWidth-1:0]	IncRegNumberAdd1,DecRegNumberSub1;

wire	[`WordWidth-1:0]	Inc8or4,Inc12or4;


always	@(in_PipelineRegister_IFID	or
	DecRegNumber			or
	IncRegNumber
	)
begin
	if(in_PipelineRegister_IFID[23]==1'b0)
	begin//down
		RegCountInLDMSTM=DecRegNumber;
		if(DecRegNumber==`Def_RegisterSelectAllOne)
			IsFirstAccess=1'b1;
		else
			IsFirstAccess=1'b0;
	end
	else
	begin//up
		RegCountInLDMSTM=IncRegNumber;
		if(IncRegNumber==`Def_RegisterSelectZero)
			IsFirstAccess=1'b1;
		else
			IsFirstAccess=1'b0;
	end
end

always	@(RegCountInLDMSTM	or
	in_PipelineRegister_IFID
	)
begin
	IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[0];
	case (RegCountInLDMSTM[3:0])
	4'b0000:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[0];
	4'b0001:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[1];
	4'b0010:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[2];
	4'b0011:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[3];
	4'b0100:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[4];
	4'b0101:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[5];
	4'b0110:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[6];
	4'b0111:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[7];
	4'b1000:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[8];
	4'b1001:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[9];
	4'b1010:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[10];
	4'b1011:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[11];
	4'b1100:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[12];
	4'b1101:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[13];
	4'b1110:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[14];
	4'b1111:
		IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[15];
	endcase
end



always	@(posedge clock or negedge reset)
begin
	if(reset==1'b0)
	begin
		PrevOperationWantWriteRegisterFromMEM=1'b0;
		PrevWriteRegister=`Def_RegisterSelectZero;
		IncRegNumber=`Def_RegisterSelectZero;
		DecRegNumber=`Def_RegisterSelectAllOne;
	end
	else
	begin
		PrevOperationWantWriteRegisterFromMEM=Next_PrevOperationWantWriteRegisterFromMEM;
		PrevWriteRegister=Next_PrevWriteRegister;
		IncRegNumber=Next_IncRegNumber;
		DecRegNumber=Next_DecRegNumber;
	end
end

assign	IncRegNumberAdd1=IncRegNumber+1;
assign	DecRegNumberSub1=DecRegNumber-1;

//exclusive to each other, must found a method to share this adder
assign	PCAdder4Result=in_AddressGoWithInstruction+32'h0000_0004;
assign	Inc8or4=(in_ThumbState==1'b1)?32'h0000_0004:32'h0000_0008;
//STM in thumb state do not store pc, so use PCAdder12or4Result for stm pc will be ok
assign	Inc12or4=(in_ThumbState==1'b1)?32'h0000_0004:32'h0000_000C;

assign	PCAdder8or4Result=in_AddressGoWithInstruction+Inc8or4;
assign	PCAdder12or4Result=in_AddressGoWithInstruction+Inc12or4;

//output 
always @(in_ValidInstruction_IFID	or
	in_PipelineRegister_IFID	or
	in_ALUCanGo			or
	in_ThumbState			or
	in_TrueFiq			or
	in_TrueIrq			or
	in_NextInstructionAddress	or
	ALUTypeMapped			or
	LeftRegisterNumber		or
	RightRegisterNumber		or
	ThirdRegisterNumber		or
	TargetRegisterNumber		or
	SecondTargetRegisterNumber	or
	in_AddressGoWithInstruction	or
	PCAdder4Result	or
	PCAdder8or4Result	or
	PCAdder12or4Result	or
	PrevOperationWantWriteRegisterFromMEM	or
	PrevWriteRegister	or
	IncRegNumber		or
	IncRegNumberAdd1	or
	DecRegNumber		or
	DecRegNumberSub1	or
	IfCurrentRegAccessByLDMSTM
)
begin
	//to prevent latch to be infer
	//invalid instruction
	out_LeftReadRegisterEnable=1'b0;
	out_LeftReadRegisterNumber=`Def_RegisterSelectZero;
	out_ALULeftFromImm=1'b0;

	out_RightReadRegisterEnable=1'b0;
	out_RightReadRegisterNumber=`Def_RegisterSelectZero;
	out_ALURightFromImm=1'b0;
		
	//third read bus will not be use
	out_ThirdReadRegisterEnable=1'b0;
	out_ThirdReadRegisterNumber=ThirdRegisterNumber;
	out_ALUThirdFromImm=1'b0;

	out_ALUEnable=1'b0;
	out_ALUType=`ALUType_Null;
	out_ALUTargetRegister=`Def_LinkRegister;

	//no use here
	out_ALURightShiftType=2'b00;
		
	out_ALUExtendedImmediateValue=`WordDontCare;
	out_ALUSecondImmediateValue=`WordDontCare;
	out_IDOwnCanGo=1'b1;

	//mem not enable
	out_MEMEnable=1'b0;
	out_MEMType=`MEMType_Null;
	out_MEMTargetRegister=`Def_LinkRegister;

	//simple alu will not be use
	out_SimpleALUType=`ALUType_Null;
	out_SimpleALUTargetRegister=`Def_LinkRegister;
	out_ALUMisc=`WordZero;
	//send out the condition code
	out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];

	//simple MEM thread
	out_SimpleMEMType=`MEMType_Null;
	out_SimpleMEMTargetRegister=`Def_LinkRegister;

	//condition code valid in alu and mem stage
	out_ALUPSRType=`ALUPSRType_Null;
	out_MEMPSRType=`MEMPSRType_Null;

	//default is come from register
	out_CPSRFromImm=1'b0;
	out_SPSRFromImm=1'b0;
	
	//only a branch or alu/load/store use pc as base will send address on this port 
	//out to LeftReadBus
	out_AddressGoWithInstruction2ALU=`WordDontCare;
	out_NextAddressGoWithInstruction2ALU=`WordZero;

⌨️ 快捷键说明

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