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

📄 decoder_arm.v

📁 若干VHDL语言的源代码
💻 V
📖 第 1 页 / 共 5 页
字号:
			begin
				//write right operand to spsr
				out_ALUPSRType=`ALUPSRType_Right2SPSR;
				out_MEMPSRType=`MEMPSRType_WriteSPSR;
			end
			else
			begin
				//write right to cpsr
				out_ALUPSRType=`ALUPSRType_Right2CPSR;
				out_MEMPSRType=`MEMPSRType_WriteCPSR;
			end
		end
		else if(`Def_IsMSRCondition)
		begin
			out_ALUEnable=1'b1;
			// i want to add alu result to imm to form new psr
			out_ALUType=`ALUType_Mov;

			if(in_PipelineRegister_IFID[22]==1'b0)
			begin
				out_ALUPSRType=`ALUPSRType_ALUResultAsConditionCode2CPSR;
				out_MEMPSRType=`MEMPSRType_WriteCPSR;
			end
			else
			begin
				out_ALUPSRType=`ALUPSRType_ALUResultAsConditionCode2SPSR;
				out_MEMPSRType=`MEMPSRType_WriteSPSR;
			end
			
			//deal with right operand
			if(in_PipelineRegister_IFID[25]==1'b0)
			begin
				//right operand come from register
				out_RightReadRegisterEnable=1'b1;
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_ALURightFromImm=1'b0;
				
				//shift type and count
				out_ALURightShiftType=2'b00;
				out_ALUThirdFromImm=1'b1;
				out_ALUSecondImmediateValue=`WordZero;
			end
			else
			begin
				//right operand come from imm
				out_RightReadRegisterEnable=1'b0;
				out_RightReadRegisterNumber=RightRegisterNumber;
				out_ALURightFromImm=1'b1;
				out_ALUExtendedImmediateValue={24'h000000,in_PipelineRegister_IFID[7:0]};
				
				//shift type and count
				out_ALURightShiftType=`Def_ShiftType_RotateRight;
				out_ALUThirdFromImm=1'b1;
				out_ALUSecondImmediateValue={27'b0000_0000_0000_0000_0000_0000_000,in_PipelineRegister_IFID[11:8],1'b0};
			end
		end
		else if(`Def_IsALUInstruction)
		begin
		//ALU operation
			if(in_PipelineRegister_IFID[25]==1'b0)
			begin
				// op two register together
				//19:16 is the first operand
				//3:0 is the second source operand
				//$monitor($time,"go to two reg ALU");
				//deal with left operand

				//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
					if(in_PipelineRegister_IFID[4]==1'b1)
						out_AddressGoWithInstruction2ALU=PCAdder12or4Result;
					else
						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
				
				//right source register can be direct read
				out_RightReadRegisterEnable=1'b1;
				out_RightReadRegisterNumber=RightRegisterNumber;
				//right operand are not from immediate
				out_ALURightFromImm=1'b0;

				//you have deal with the unshifted right operand
				//but you must deal with shift type and shift count
				out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
				//shift count
				if(in_PipelineRegister_IFID[4]==1'b0)
				begin
					//shift count given in instruction
					//no need to read shift count from register file
					out_ThirdReadRegisterEnable=1'b0;
					out_ThirdReadRegisterNumber=`Def_RegisterSelectZero;
					//ALU must open to read in shift count
					//shift count is a immediate
					out_ALUThirdFromImm=1'b1;
					out_ALUSecondImmediateValue={27'b0000_0000_0000_0000_0000_0000_000,in_PipelineRegister_IFID[11:7]};
				end
				else
				begin
					//the shift count given in a register
					out_ALUSecondImmediateValue=`WordDontCare;
					
					//this register can be direct read
					out_ThirdReadRegisterEnable=1'b1;
					out_ThirdReadRegisterNumber=ThirdRegisterNumber;
					//shift count is not imm
					out_ALUThirdFromImm=1'b0;
				end
				
				
				out_ALUExtendedImmediateValue=`WordDontCare;
				//a valid ALU
				out_ALUEnable=1'b1;
				out_ALUType=ALUTypeMapped;
				//these instruction will not write result,just set status psr
				if(`Def_IsNoResultWritenInstruction)
				begin
					out_ALUTargetRegister=`Def_LinkRegister;
					out_MEMEnable=1'b0;
					out_MEMType=`MEMType_Null;
					out_MEMTargetRegister=`Def_LinkRegister;
				end
				else if(TargetRegisterNumber==`Def_PCNumber)//pc will not be forward or write to register file by mem stage
				begin
					out_ALUTargetRegister=`Def_LinkRegister;
					out_MEMEnable=1'b0;
					out_MEMType=`MEMType_Null;
					out_MEMTargetRegister=`Def_LinkRegister;
				end
				else
				begin
					out_ALUTargetRegister=TargetRegisterNumber;
					out_MEMEnable=1'b1;
					out_MEMType=`MEMType_MovMain;
					out_MEMTargetRegister=TargetRegisterNumber;
				end
				out_IDOwnCanGo=1'b1;

				//simple thread will not be use in write to R15 or other register
				out_SimpleALUType=`ALUType_Null;
				//simple lu thread will not attend forwarding
				out_SimpleALUTargetRegister=`Def_LinkRegister;

				//simple MEM thread will not be use in write to r15 or other register
				out_SimpleMEMType=`MEMType_Null;
				//simple mem thread will not attend forwarding
				out_SimpleMEMTargetRegister=`Def_LinkRegister;
				
				out_ALUMisc=`WordZero;
				out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];
				//main thread result must be used to change pc
				//output new pc to IF using main alu
				if(TargetRegisterNumber==`Def_PCNumber)
					out_ALUMisc[6]=1'b1;
				else
					out_ALUMisc[6]=1'b0;

				
				//default is come from register
				out_CPSRFromImm=1'b0;
				out_SPSRFromImm=1'b0;

			end//the second operand come from register
			else
			begin
				//the second operand is a immediate value

				//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
					

				//right read bus here will not be use
				out_RightReadRegisterNumber=RightRegisterNumber;
				//right register will not be use
				out_RightReadRegisterEnable=1'b0;
				//ALU must read extended immediate value from RightReadBus
				//the value come from the decoder
				out_ALURightFromImm=1'b1;
				//send out imediate value
				out_ALUExtendedImmediateValue={24'h000000,in_PipelineRegister_IFID[7:0]};
				
				//third read bus will be use
				out_ThirdReadRegisterEnable=1'b0;
				out_ThirdReadRegisterNumber=ThirdRegisterNumber;
				out_ALUThirdFromImm=1'b1;
				
				//shift type and count
				//rotate at twice the value of rotate field
				out_ALURightShiftType=`Def_ShiftType_RotateRight;
				out_ALUSecondImmediateValue={24'h000000,3'b000,in_PipelineRegister_IFID[11:8],1'b0};
				
				
				//a valid ALU
				out_ALUEnable=1'b1;
				out_ALUType=ALUTypeMapped;
				//these instruction will not write result,just set status psr
				if(`Def_IsNoResultWritenInstruction)
				begin
					out_ALUTargetRegister=`Def_LinkRegister;
					out_MEMEnable=1'b0;
					out_MEMType=`MEMType_Null;
					out_MEMTargetRegister=`Def_LinkRegister;
				end
				else if(TargetRegisterNumber==`Def_PCNumber)//pc will not be forward or write to register file by mem stage
				begin
					out_ALUTargetRegister=`Def_LinkRegister;
					out_MEMEnable=1'b0;
					out_MEMType=`MEMType_Null;
					out_MEMTargetRegister=`Def_LinkRegister;
				end
				else
				begin
					out_ALUTargetRegister=TargetRegisterNumber;
					out_MEMEnable=1'b1;
					out_MEMType=`MEMType_MovMain;
					out_MEMTargetRegister=TargetRegisterNumber;
				end
				out_IDOwnCanGo=1'b1;

				//simple thread will not be use in write to R15 or other register
				out_SimpleALUType=`ALUType_Null;
				out_SimpleALUTargetRegister=`Def_LinkRegister;

				//simple MEM thread will not be use in write to r15 or other register
				out_SimpleMEMType=`MEMType_Null;
				out_SimpleMEMTargetRegister=`Def_LinkRegister;

				out_ALUMisc=`WordZero;
				out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];
				//main thread result must be used to change pc
				//output new pc to IF using main alu
				if(TargetRegisterNumber==`Def_PCNumber)
					out_ALUMisc[6]=1'b1;
				else
					out_ALUMisc[6]=1'b0;
				
				
				//default is come from register
				out_CPSRFromImm=1'b0;
				out_SPSRFromImm=1'b0;
			end//the second operand come from imm
			
			//now deal with the status bit of psr 
			if(in_PipelineRegister_IFID[20]==1'b1)
			begin
				//set condition code in psr
				if(TargetRegisterNumber!=`Def_PCNumber)
				begin
					//just set condition code
					out_ALUPSRType=`ALUPSRType_WriteConditionCode;
					out_MEMPSRType=`MEMPSRType_WriteConditionCode;
				end
				else
				begin
					//restore spsr to cpsr
					out_ALUPSRType=`ALUPSRType_SPSR2CPSR;
					out_MEMPSRType=`MEMPSRType_WriteCPSR;
				end
			end
			else
			begin
				out_ALUPSRType=`ALUPSRType_Null;
				out_MEMPSRType=`MEMPSRType_Null;
			end
		end//alu instruction
		else if(`Def_IsLoadInstruction)
		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 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
				out_ALUSecondImmediateValue={24'h000000,3'b000,in_PipelineRegister_IFID[11:7]};
			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
				out_ALUSecondImmediateValue=`WordZero;
			end
				
			//third read bus will be use
			out_ThirdReadRegisterEnable=1'b0;
			out_ThirdReadRegisterNumber=ThirdRegisterNumber;
			out_ALUThirdFromImm=1'b1;
				
			//a valid ALU
			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 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;
					if(in_PipelineRegister_IFID[22]==1'b1)
						out_MEMType=`MEMType_LoadMainByte;
					else
						out_MEMType=`MEMType_LoadMainWord;

					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
				else
				begin
					//no need to write back
					//only when now can the base register be r15
					//because the r15 can not be 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_LoadMainByte;
					else
						out_MEMType=`MEMType_LoadMainWord;

					if(TargetRegisterNumber==`Def_PCNumber)

⌨️ 快捷键说明

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