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

📄 decoder_arm.v

📁 若干VHDL语言的源代码
💻 V
📖 第 1 页 / 共 5 页
字号:
						out_MEMTargetRegister=`Def_LinkRegister;
					else
						out_MEMTargetRegister=TargetRegisterNumber;


					//simple thread of mem stage
					out_SimpleMEMType=`MEMType_Null;
					out_SimpleMEMTargetRegister=`Def_LinkRegister;
				end
			end
			else
			begin
				//post index
				//perform alu but use origin base as address to load
				//in this mode the write back bit is always 1'b0
				//but the alu result must ALWAYS WRITE BACK to base register
				//because if you do not want to write back, you do not need this address mode,
				// a normal address mode with 0 offset will be enough
				//so main alu thread compute the result,main mem thread will load according to simple alu result
				//simple alu will pass leftoperand(base) to main mem,simple mem will pass main alu result to write
				out_SimpleALUType=`ALUType_Mvl;
				out_SimpleALUTargetRegister=`Def_LinkRegister;

				out_ALUTargetRegister=LeftRegisterNumber;

				//main thread of mem stage
				out_MEMEnable=1'b1;
				if(in_PipelineRegister_IFID[22]==1'b1)
					out_MEMType=`MEMType_LoadSimpleByte;
				else
					out_MEMType=`MEMType_LoadSimpleWord;

				if(TargetRegisterNumber==`Def_PCNumber)
					out_MEMTargetRegister=`Def_LinkRegister;
				else
					out_MEMTargetRegister=TargetRegisterNumber;


				//simple thread of mem stage
				out_SimpleMEMType=`MEMType_MovMain;
				out_SimpleMEMTargetRegister=LeftRegisterNumber;
			end
			out_IDOwnCanGo=1'b1;

			//when target register is pc,then this bit will tell mem stage to write loaded value to if
			if(TargetRegisterNumber==`Def_PCNumber)
				out_ALUMisc[7]=1'b1;

			Next_PrevOperationWantWriteRegisterFromMEM=1'b1;
			Next_PrevWriteRegister=TargetRegisterNumber;
		end//load instruction
		else if(`Def_IsStoreInstruction)
		begin
			//left source register can be direct read
			if(LeftRegisterNumber==`Def_PCNumber)
			begin
				//left register is pc
				//do not read register file
				//just send out pc on out_AddressGoWithInstruction2ALU
				out_AddressGoWithInstruction2ALU=PCAdder8or4Result;
				out_LeftReadRegisterEnable=1'b0;
				out_LeftReadRegisterNumber=LeftRegisterNumber;
				//left come from imm pc
				//do not forward
				out_ALULeftFromImm=1'b1;
			end
			else
			begin
				//left register is not pc
				out_LeftReadRegisterEnable=1'b1;
				out_LeftReadRegisterNumber=LeftRegisterNumber;
				//left operand are not from immediate
				out_ALULeftFromImm=1'b0;
			end

			//deal with the offset
			//right read bus
			if(in_PipelineRegister_IFID[25]==1'b1)
			begin
				//offset come from register and need a shift
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_RightReadRegisterEnable=1'b1;
				out_ALURightFromImm=1'b0;

				//imm is not need here
				out_ALUExtendedImmediateValue=`WordDontCare;

				//shift type
				out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
				//shift ammount
				//use out_ALUMisc to pass shift count
				// the third read register bus will be use as store value read
				out_ALUMisc[5:0]={in_PipelineRegister_IFID[11:7],1'b1};
			end
			else
			begin
				//offset come from imm in instruction
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_RightReadRegisterEnable=1'b0;
				out_ALURightFromImm=1'b1;

				//imm act as offset
				out_ALUExtendedImmediateValue={20'h00000,in_PipelineRegister_IFID[11:0]};

				out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
				//shift ammount is always 0
				//use out_ALUMisc to pass shift count
				// the third read register bus will be use as store value read
				out_ALUMisc[5:0]={6'b000001};
			end
		
			//third read bus will be use to read store value
			if(ThirdRegisterNumber==`Def_PCNumber)
			begin
				out_ALUSecondImmediateValue=PCAdder12or4Result;
				//do not read register
				out_ThirdReadRegisterEnable=1'b0;
				out_ThirdReadRegisterNumber=ThirdRegisterNumber;
				//can not be forward
				out_ALUThirdFromImm=1'b1;
			end
			else
			begin
				out_ALUSecondImmediateValue=`WordDontCare;
				out_ThirdReadRegisterEnable=1'b1;
				out_ThirdReadRegisterNumber=ThirdRegisterNumber;
				//can be forward
				out_ALUThirdFromImm=1'b0;
			end

			out_ALUEnable=1'b1;
			//add or sub the offset from base
			if(in_PipelineRegister_IFID[23]==1'b1)
			begin
				//add
				out_ALUType=`ALUType_Add;
			end
			else
			begin
				//sub
				out_ALUType=`ALUType_Sub;
			end
			
			//deal with the case of pre or post index
			if(in_PipelineRegister_IFID[24]==1'b1)
			begin
				//pre index
				//first perform alu then use result as the address to store
				out_SimpleALUType=`ALUType_Null;
				out_SimpleALUTargetRegister=`Def_LinkRegister;
				if(in_PipelineRegister_IFID[21]==1'b1)
				begin
					//write back alu result to base register
					out_ALUTargetRegister=LeftRegisterNumber;

					//main thread of mem stage
					out_MEMEnable=1'b1;
					if(in_PipelineRegister_IFID[22]==1'b1)
						out_MEMType=`MEMType_StoreMainByte;
					else
						out_MEMType=`MEMType_StoreMainWord;
					out_MEMTargetRegister=`Def_LinkRegister;

					//simple thread of mem stage
					out_SimpleMEMType=`MEMType_MovMain;
					out_SimpleMEMTargetRegister=LeftRegisterNumber;
				end
				else
				begin
					//no need to write back
					out_ALUTargetRegister=`Def_LinkRegister;

					//main thread of mem stage
					out_MEMEnable=1'b1;
					if(in_PipelineRegister_IFID[22]==1'b1)
						out_MEMType=`MEMType_StoreMainByte;
					else
						out_MEMType=`MEMType_StoreMainWord;
					out_MEMTargetRegister=`Def_LinkRegister;

					//simple thread of mem stage
					out_SimpleMEMType=`MEMType_Null;
					out_SimpleMEMTargetRegister=`Def_LinkRegister;
				end
			end
			else
			begin
				//post index
				//perform alu but use origin base as address to load
				//in this mode the write back bit is always 1'b0
				//but the alu result must ALWAYS WRITE BACK to base register
				//because if you do not want to write back, you do not need this address mode,
				// a normal address mode with 0 offset will be enough
				//so main alu thread compute the result,main mem thread will load according to simple alu result
				//simple alu will pass leftoperand(base) to main mem,simple mem will pass main alu result to write
				out_SimpleALUType=`ALUType_Mvl;
				out_SimpleALUTargetRegister=`Def_LinkRegister;

				out_ALUTargetRegister=LeftRegisterNumber;

				//main thread of mem stage
				out_MEMEnable=1'b1;
				if(in_PipelineRegister_IFID[22]==1'b1)
					out_MEMType=`MEMType_StoreSimpleByte;
				else
					out_MEMType=`MEMType_StoreSimpleWord;
				out_MEMTargetRegister=`Def_LinkRegister;

				//simple thread of mem stage
				out_SimpleMEMType=`MEMType_MovMain;
				out_SimpleMEMTargetRegister=LeftRegisterNumber;
			end
			out_IDOwnCanGo=1'b1;
		end
		else if(`Def_IsLDM)
		begin
			if(in_PipelineRegister_IFID[23]==1'b0)
			begin//down
			   if(DecRegNumber[7:4]==4'b1110)
			   begin
			   	//perform delayed branch
			   	//except delay branch signal, nothing is use
				out_LeftReadRegisterEnable=1'b0;
				out_LeftReadRegisterNumber=LeftRegisterNumber;
				out_ALULeftFromImm=1'b1;
				
				//deal with offset
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_RightReadRegisterEnable=1'b0;
				out_ALURightFromImm=1'b1;
	
				out_ALUExtendedImmediateValue=32'h0000_0000;
	
				out_ALURightShiftType=`Def_ShiftType_LogicLeft;
				//shift ammount is always 0
				out_ALUSecondImmediateValue=`WordZero;

				//third read bus will be use
				out_ThirdReadRegisterEnable=1'b0;
				out_ThirdReadRegisterNumber=ThirdRegisterNumber;
				out_ALUThirdFromImm=1'b1;

				//a valid ALU
				out_ALUEnable=1'b1;

				//sub 4 from current register
				out_ALUType=`ALUType_Sub;
				out_ALUTargetRegister=`Def_LinkRegister;

				out_SimpleALUType=`ALUType_Null;
				out_SimpleALUTargetRegister=`Def_LinkRegister;

				//main thread of mem stage
				out_MEMEnable=1'b1;
				//always load word
				out_MEMType=`MEMType_Null;
				out_MEMTargetRegister=`Def_LinkRegister;

				//simple thread of mem stage
				out_SimpleMEMType=`MEMType_Null;
				out_SimpleMEMTargetRegister=`Def_LinkRegister;

				out_IDOwnCanGo=1'b1;
				//out_ALUMisc[14] means delay branch
				if(in_PipelineRegister_IFID[15]==1'b1)
					out_ALUMisc[14]=1'b1;
				else
					out_ALUMisc[14]=1'b0;

				//out_ALUMisc[15] means store delay branch target
				out_ALUMisc[15]=1'b0;
				
				if(in_IsInPrivilegedMode==1'b1 && in_PipelineRegister_IFID[15]==1'b1 && in_PipelineRegister_IFID[22]==1'b1)
				begin
					//condition code valid in alu and mem stage
					out_ALUPSRType=`ALUPSRType_SPSR2CPSR;
					out_MEMPSRType=`MEMPSRType_WriteCPSR;
				end

				
				Next_IncRegNumber=`Def_RegisterSelectZero;
				Next_DecRegNumber=`Def_RegisterSelectAllOne;

				Next_PrevOperationWantWriteRegisterFromMEM=1'b0;
				Next_PrevWriteRegister=`Def_LinkRegister;

			   end//of DecRegNumber[7:4]==4'b1110
			   else
			   begin
				out_LeftReadRegisterEnable=1'b1;
				
				//if write back is need, then just read left register as base
				//if write back is not need and it is the first access ,also read left register as base
				// if write back is not need and it is not the first access, then just use LocalForwardRegister
				if(in_PipelineRegister_IFID[21]==1'b1 || IsFirstAccess==1'b1)
					out_LeftReadRegisterNumber=LeftRegisterNumber;
				else 
					out_LeftReadRegisterNumber=`Def_LocalForwardRegister;
					
				//left operand are not from immediate
				out_ALULeftFromImm=1'b0;
				
				//deal with offset
				//offset come from imm in instruction
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_RightReadRegisterEnable=1'b0;
				out_ALURightFromImm=1'b1;
	
				//imm act as offset
				if(IfCurrentRegAccessByLDMSTM==1'b1)
					out_ALUExtendedImmediateValue=32'h0000_0004;
				else
					out_ALUExtendedImmediateValue=32'h0000_0000;
	
				out_ALURightShiftType=`Def_ShiftType_LogicLeft;
				//shift ammount is always 0
				out_ALUSecondImmediateValue=`WordZero;

				//third read bus will be use
				out_ThirdReadRegisterEnable=1'b0;
				out_ThirdReadRegisterNumber=ThirdRegisterNumber;
				out_ALUThirdFromImm=1'b1;

				//a valid ALU
				out_ALUEnable=1'b1;

				//sub 4 from current register
				out_ALUType=`ALUType_Sub;

				//deal with the case of pre or post index
				if(in_PipelineRegister_IFID[24]==1'b1)
				begin
					//pre index
					//first perform alu then use result as the address to load
					out_SimpleALUType=`ALUType_Null;
					out_SimpleALUTargetRegister=`Def_LinkRegister;
					if(in_PipelineRegister_IFID[21]==1'b1)
					begin
						//write back alu result to base register
						out_ALUTargetRegister=LeftRegisterNumber;

						//main thread of mem stage
						out_MEMEnable=1'b1;

						//always load word
						if(IfCurrentRegAccessByLDMSTM==1'b1)
						begin
							out_MEMType=`MEMType_LoadMainWord;
							
							if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
								out_MEMTargetRegister=`Def_LinkRegister;
							else
								out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};
						end
						else
						begin
							out_MEMType=`MEMType_Null;
							out_MEMTargetRegister=`Def_LinkRegister;
						end


						//simple thread of mem stage
						out_SimpleMEMType=`MEMType_MovMain;
						out_SimpleMEMTargetRegister=LeftRegisterNumber;
					end
					else
					begin
						//no need to write back
						//so just write base value to Def_LocalForwardRegister 
						out_ALUTargetRegister=`Def_LocalForwardRegister;

						//main thread of mem stage
						out_MEMEnable=1'b1;
						
						//always load word
						if(IfCurrentRegAccessByLDMSTM==1'b1)
						begin
							out_MEMType=`MEMType_LoadMainWord;
							
							if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
								out_MEMTargetRegister=`Def_LinkRegister;
							else
								out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};
						end
						else
						begin
							out_MEMType=`MEMType_Null;
							out_MEMTargetRegister=`Def_LinkRegister;
						end


						//simple thread of mem stage
						//no need to write back, so just write the modified base to Def_LocalForwardRegister
						out_SimpleMEMType=`MEMType_MovMain;
						out_SimpleMEMTargetRegister=`Def_LocalForwardRegister;
					end
				end
				else
				begin
					//post index
					//perform alu but use origin base as address to load
					out_SimpleALUType=`ALUType_Mvl;
					out_SimpleALUTargetRegister=`Def_LinkRegister;

					if(in_PipelineRegister_IFID[21]==1'b1)
					begin
						out_ALUTargetRegister=LeftRegisterNumber;

						//main thread of mem stage
						out_MEMEnable=1'b1;

						//always load word
						if(IfCurrentRegAccessByLDMSTM==1'b1)
						begin
							out_MEMType=`MEMType_LoadSimpleWord;

							if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
								out_MEMTargetRegister=`Def_LinkRegister;
							else
								out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};

⌨️ 快捷键说明

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