www.pudn.com > x86.rar > TaskSwitch.v, change:2007-12-05,size:31807b


 
`include "defenation.v" 
module TaskSwitch(clk,reset,enable,ack,TaskDesSel,context_in,oldPC,eflags_In,operation,ExceptionAck,context_out,address,flush,newPC,size,memData,memAddr,memRw,memEnable,mode,ExceptionEnable,Vect,eflags_out,TaskSwitchOver); 
 
input		enable; 
input	[271:0]	context_in; 
input		ack; 
input		clk; 
input		reset; 
input	[31:0]	oldPC; 
input	[31:0]	eflags_In; 
input	[10:0]	operation; 
input	[15:0]	TaskDesSel; 
input		ExceptionAck; 
 
inout	[31:0]	memData; 
 
output	[271:0]	context_out; 
output	[55:0]	address; 
output		flush; 
output	[31:0]	memAddr; 
output		memRw; 
output		memEnable; 
output		mode; 
output	[31:0]	eflags_out; 
output		TaskSwitchOver; 
output	[31:0]	newPC; 
output	[8:0]	size; 
 
output		ExceptionEnable; 
output	[7:0]	Vect; 
 
 
reg	[271:0]	context_out; 
reg	[55:0]	address; 
reg	[31:0]	newPC; 
reg		flush; 
reg		memRead; 
reg		memWrite; 
reg		mode; 
reg		TaskSwitchOver; 
reg	[31:0]	memAddr; 
reg	[8:0]	size; 
reg		ExceptionEnable; 
reg	[7:0]	Vect; 
reg	[31:0]	eflags_out; 
 
 
reg	[3:0]	State; 
reg	[2:0]	RegFetchState; 
reg	[2:0]	TaskSaveState; 
reg	[3:0]	RegUpdateState; 
reg	[2:0]	TaskReadState; 
reg	[3:0]	ReadNewDesState; 
reg	[3:0]	NextDesState; 
 
reg	[1:0]	bufferposition; 
reg	[31:0]	memAddrIndex; 
reg	[8:0]	memFetchCount; 
 
//Tempory register are declared here 
reg	[7:0]	buffer[100:0]; 
reg	[63:0]	tempShadow; 
reg	[63:0]	tempDesShadow; 
 
reg	[31:0]	tempAddress; 
 
reg	[31:0]	StackBuffer; 
reg	[31:0]	dataWr; 
 
reg	[15:0]	temptr; 
reg	[63:0]	temptrShadow; 
reg	[31:0]	temptrBase; 
 
reg	[15:0]	tempDestr; 
reg	[63:0]	tempDestrShadow; 
reg	[31:0]	memDatatempDestrBase; 
 
reg	[19:0]	Limit; 
reg	[15:0]	desSelector; 
reg	[47:0]	GDTRreg;	 
reg	[69:0]	LDTRreg; 
reg	[31:0]	BaseAddr; 
reg	[31:0]	Offset; 
reg	[1:0]	gateDPL; 
 
reg	[15:0]	tempcs; 
reg	[15:0]	tempss; 
reg	[15:0]	tempds; 
reg	[15:0]	tempes; 
reg	[15:0]	tempfs; 
reg	[15:0]	tempgs; 
 
reg	[31:0]	tempEAX; 
reg	[31:0]	tempEBX; 
reg	[31:0]	tempECX; 
reg	[31:0]	tempEDX; 
reg	[31:0]	tempESP; 
reg	[31:0]	tempEBP; 
reg	[31:0]	tempESI; 
reg	[31:0]	tempEDI; 
 
reg	[63:0]	tempcsShadow; 
reg	[63:0]	tempssShadow; 
reg	[63:0]	tempdsShadow; 
reg	[63:0]	tempesShadow; 
reg	[63:0]	tempfsShadow; 
reg	[63:0]	tempgsShadow; 
 
reg	[15:0]	templdtr; 
reg	[63:0]	templdtrShadow; 
reg	[31:0]	templdtrBase; 
 
 
reg	[31:0]	tempEflags; 
 
reg	[31:0]  tempPC; 
reg	[31:0]	tempPDBR; 
 
reg		getldtr; 
reg	[31:0]	TSSbuffer; 
 
 
assign memEnable	= memRead|memWrite; 
assign memRw		= memWrite? 1 : 0; 
assign memData		= memRw? dataWr:32'bz; 
 
 
 
parameter	FetchGDTR	= 4'b0000, 
		GetGDTR		= 4'b0001, 
		FetchTSS	= 4'b0010, 
		GetTSS		= 4'b0011, 
		GetTR		= 4'b0100, 
		FetchReg	= 4'b0101, 
		CheckValidity	= 4'b0110, 
		SaveTask	= 4'b0111, 
		FetchNewReg	= 4'b1000, 
		FetchNewDes	= 4'b1001, 
		UpdateTR	= 4'b1010, 
		UpdateReg	= 4'b1011, 
		SwitchOver	= 4'b1100, 
		ExceptionWait	= 4'b1101; 
 
parameter	FetchCSAXBX	= 3'b000, 
		FetchDSCXDX	= 3'b001, 
		FetchESBP	= 3'b010, 
		FetchSSSP	= 3'b011, 
		FetchFSSI	= 3'b100, 
		FetchGSDI	= 3'b101, 
		GetEflags	= 3'b110; 
 
parameter	UpdateCSAXBX	= 4'b0000, 
		UpdateDSCXDX	= 4'b0001, 
		UpdateESBP	= 4'b0010, 
		UpdateSSSP	= 4'b0011, 
		UpdateFSSI	= 4'b0100, 
		UpdateIPGSDI	= 4'b0101, 
		UpdateLDTR	= 4'b0110,	 
		UpdatePDBR	= 4'b0111; 
 
parameter	AddrCal		= 3'b000, 
		ReadTSS		= 3'b001, 
		WriteToTSS	= 3'b010; 
 
parameter	ReadAddrCal	= 3'b000, 
		ReadToBuffer	= 3'b001, 
		TempReg		= 3'b010; 
 
parameter	FetchLDTRDes	= 4'b0000, 
		GetLDTRDes	= 4'b0001, 
		GetCSDes	= 4'b0010, 
		GetDSDes	= 4'b0011, 
		GetESDes	= 4'b0100, 
		GetSSDes	= 4'b0101, 
		GetFSDes	= 4'b0110, 
		GetGSDes	= 4'b0111, 
		ReadFrommem	= 4'b1000; 
	 
 
parameter	ES		= 3'b000, 
		CS		= 3'b001, 
		SS		= 3'b010, 
		DS		= 3'b011, 
		FS		= 3'b100, 
		GS		= 3'b101; 
 
				 
always @ (posedge reset or posedge clk) 
begin 
	if(reset) 
	begin 
		State		<= FetchGDTR; 
		RegFetchState	<= FetchCSAXBX; 
		TaskSaveState	<= AddrCal; 
		RegUpdateState	<= UpdateCSAXBX; 
		TaskReadState	<= ReadAddrCal; 
		context_out = 272'b0; 
		ExceptionEnable = 1'b0; 
		TaskSwitchOver = 1'b0; 
		size = 9'b0; 
	end 
	else 
	begin 
		if(enable) 
		begin 
			case(State) 
			FetchGDTR: 
			begin 
				mode =1; 
				address [26:0] = 27'b0; 
				address [29] = 0; 
				address [28:27] =2'b10; 
				address [34:30] = 5'b11000;// for slecting  
				address [53:35] = 19'b0; 
				tempDestr = TaskDesSel; 
				State <= FetchGDTR; 
				if(tempDestr[2])// if the selector to be load is LDTR 
				begin 
					//raise exception 
				end 
				 
			end 
			GetGDTR: 
			begin 
				mode =0; 
				address [53:0] = 54'b0; 
				GDTRreg = {context_in[271:256],context_in [31:0]}; 
				tempAddress = context_in [31:0]; 
				memAddrIndex =  tempAddress + {tempDestr[15:3],3'b000}; 
				memAddr = {memAddrIndex[31:2],2'b00}; 
				bufferposition = memAddrIndex[1:0]; 
				memRead =1; 
				memFetchCount =0;	 
				State <= FetchTSS; 
 
			end 
			FetchTSS: 
			begin 
				//Fetching decriptors from memory 
				if(ack) 
				begin 
					buffer[memFetchCount+0] = memData[7:0]; 
					buffer[memFetchCount+1] = memData[15:8]; 
					buffer[memFetchCount+2] = memData[23:16]; 
					buffer[memFetchCount+3] = memData[31:24];							 
					memFetchCount = memFetchCount +4; 
					if((memFetchCount-bufferposition) >= 8) 
					begin 
						State <= GetTSS; 
					end 
					else 
					begin 
						memAddr = memAddr + 3'd4; 
					end 
				end 
 
			end	 
			GetTSS: 
			begin 
				tempDestrShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
				mode =1; 
				address [26:0] = 27'b0; 
				address [28:27] =2'b00;// for selecting TR register 
				address [29] = 0; 
				address [34:30] = 5'b11000;// for slecting  
				address [53:35] = 19'b0; 
				State <= GetTR; 
			end 
			GetTR: 
			begin 
				mode = 0; 
				address [53:0] = 54'b0; 
				temptr = context_in [271:256]; 
				temptrShadow = context_in [255:192]; 
				temptrBase = {temptrShadow[63:56],temptrShadow[37:16]}; 
				State <= FetchReg; 
			end 
			FetchReg: 
			begin 
				case(RegFetchState) 
				FetchCSAXBX: 
				begin 
					address [8:0]	= 9'b0; 
					address [11:9]	= `EBX; 
					address [15:12]	= 4'b0000; 
					address	[16]	= 1'b1; 
					address	[17]	= 1'b1; 
					address [20:18]	= `EAX;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting ESP in read mode 
					address	[25]	= 1'b1;	// 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= CS; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					size [4:3] = 2'b11; 
 
					RegFetchState	<= FetchDSCXDX; 
 
				end 
				FetchDSCXDX: 
				begin 
					tempEAX = context_in[31:0]; 
					tempEBX	= context_in[63:32]; 
					tempcs	= context_in[271:256]; 
 
					address [8:0]	= 9'b0; 
					address [11:9]	= `EDX; 
					address [15:12]	= 4'b0000; 
					address	[16]	= 1'b1; 
					address	[17]	= 1'b1; 
					address [20:18]	= `ECX;	//Selecting ECX in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting ECX in read mode 
					address	[25]	= 1'b1;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= DS; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					size [4:3] = 2'b11; 
 
					RegFetchState	<= FetchESBP; 
 
				end 
				FetchESBP: 
				begin 
					tempECX = context_in[31:0]; 
					tempEDX	= context_in[63:32]; 
					tempds	= context_in[271:256]; 
 
					address [17:0]	= 18'b0; 
					address [20:18]	= `EBP;	//Selecting EBP in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting EBP in read mode 
					address	[25]	= 1'b1;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= ES; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					RegFetchState	<= FetchSSSP; 
 
				end 
				FetchSSSP:  
				begin 
					tempEBP = context_in[31:0]; 
					tempes	= context_in[271:256]; 
 
					address [17:0]	= 18'b0; 
					address [20:18]	= `ESP;	//Selecting ESP in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting ESP in read mode 
					address	[25]	= 1'b1;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= SS; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					RegFetchState	<= FetchFSSI; 
 
				end 
				FetchFSSI: 
				begin 
					tempss	= context_in [271:256]; 
					tempESP	= context_in [31:0]; 
					address [17:0]	= 18'b0; 
					address [20:18]	= `ESI;	//Selecting ESI in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting ESI in read mode 
					address	[25]	= 1'b1;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= FS; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					RegFetchState	<= FetchGSDI; 
 
				end 
				FetchGSDI: 
				begin 
					tempESI = context_in[31:0]; 
					tempfs	= context_in[271:256]; 
					 
					address [17:0]	= 18'b0; 
					address [20:18]	= `EDI;	//Selecting EDI in general purpose registers 
					address	[24:21]	= 4'b0000; //Selecting EDI in read mode 
					address	[25]	= 1'b1;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= GS; // selecting proper segment register 
					address [35:30]	= 6'b010000;// Enabling segment and shadow registers in read mode				 
					address [38:36]	= 3'b101;// for Fetching Eflags 
					address	[53:39] = 15'b0; 
					size [7:6] = 2'b11; 
					RegFetchState	<= GetEflags; 
 
				end 
				GetEflags: 
				begin 
					tempEDI = context_in[31:0]; 
					tempgs	= context_in[271:256]; 
					tempEflags = eflags_In; 
					RegFetchState	<= FetchCSAXBX; 
 
					State <= CheckValidity; 
 
				end 
				endcase 
			end 
			CheckValidity: 
			begin		 
				if(tempDestrShadow[`Present] !=1) 
				begin 
					//raise exception 
					State <= ExceptionWait; 
				end 
				else 
				if(tempDestrShadow[`Busy] ==1) 
				begin 
					//raise exception 
					State <= ExceptionWait; 
				end 
				else 
				begin 
					if(operation == 11'd164) // IRET instruction 
					begin 
						tempEflags[`NT] = 1'b0; 
						State <= SaveTask; 
					end 
					if(operation == 11'd25 || operation == 11'd26 ) 
					begin 
						if(tempcs[1:0] <  temptrShadow [`DPL]) 
						begin 
							State <= ExceptionWait; 
						end 
						else  
							State <= SaveTask; 
						if(operation == 11'd25) 
						begin 
							temptrShadow[`Busy]= 1'b1; 
						end 
					end 
				end 
			end 
			 
			SaveTask: 
			begin 
				case(TaskSaveState) 
				AddrCal: 
				begin 
					buffer[0] = oldPC[0]; 
					buffer[1] = oldPC[1]; 
					buffer[2] = oldPC[2]; 
					buffer[3] = oldPC[3]; 
					buffer[4] = tempEflags[0]; 
					buffer[5] = tempEflags[1]; 
					buffer[6] = tempEflags[2]; 
					buffer[7] = tempEflags[3]; 
					buffer[8] = tempEAX[0]; 
					buffer[9] = tempEAX[1]; 
					buffer[10] = tempEAX[2]; 
					buffer[11] = tempEAX[3]; 
					buffer[12] = tempECX[0]; 
					buffer[13] = tempECX[1]; 
					buffer[14] = tempECX[2]; 
					buffer[15] = tempECX[3]; 
					buffer[16] = tempEDX[0]; 
					buffer[17] = tempEDX[1]; 
					buffer[18] = tempEDX[2]; 
					buffer[19] = tempEDX[3]; 
					buffer[20] = tempEBX[0]; 
					buffer[21] = tempEBX[1]; 
					buffer[22] = tempEBX[2]; 
					buffer[23] = tempEBX[3]; 
					buffer[24] = tempESP[0]; 
					buffer[25] = tempESP[1]; 
					buffer[26] = tempESP[2]; 
					buffer[27] = tempESP[3]; 
					buffer[28] = tempEBP[0]; 
					buffer[29] = tempEBP[1]; 
					buffer[30] = tempEBP[2]; 
					buffer[31] = tempEBP[3]; 
					buffer[32] = tempESI[0]; 
					buffer[33] = tempESI[1]; 
					buffer[34] = tempESI[2]; 
					buffer[35] = tempESI[3]; 
					buffer[36] = tempEDI[0]; 
					buffer[37] = tempEDI[1]; 
					buffer[38] = tempEDI[2]; 
					buffer[39] = tempEDI[3]; 
					buffer[40] = tempes[0]; 
					buffer[41] = tempes[1]; 
					buffer[42] = 8'b0; 
					buffer[43] = 8'b0; 
					buffer[44] = tempcs[0]; 
					buffer[45] = tempcs[1]; 
					buffer[46] = 8'b0; 
					buffer[47] = 8'b0; 
					buffer[48] = tempss[0]; 
					buffer[49] = tempss[1]; 
					buffer[50] = 8'b0; 
					buffer[51] = 8'b0; 
					buffer[52] = tempds[0]; 
					buffer[53] = tempds[1]; 
					buffer[54] = 8'b0; 
					buffer[55] = 8'b0; 
					buffer[56] = tempfs[0]; 
					buffer[57] = tempfs[1]; 
					buffer[58] = 8'b0; 
					buffer[59] = 8'b0; 
					buffer[60] = tempgs[0]; 
					buffer[61] = tempgs[1]; 
					buffer[62] = 8'b0; 
					buffer[63] = 8'b0; 
					 
					memAddrIndex =  temptrBase+32; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					if(!(|bufferposition)) 
					begin 
						memRead = 1'b1; 
						TaskSaveState <= ReadTSS; 
					end 
					else 
					begin 
						dataWr = { buffer[3],buffer[2],buffer[1],buffer[0]}; 
						memFetchCount = 4; 
						memWrite =1'b1; 
						getldtr = 1'b0; 
						TaskSaveState <= WriteToTSS; 
					end  
				end 
				ReadTSS: 
				begin 
					if(ack) 
					begin 
						case(bufferposition) 
						2'd1: 
						begin 
							dataWr = {buffer[2],buffer[1],buffer[0],memData[7:0]}; 
							memFetchCount =3; 
							memRead = 1'b0; 
							memWrite =1'b1; 
							TaskSaveState <= WriteToTSS; 
						end 
						2'd2: 
						begin 
							dataWr = {buffer[1],buffer[0],memData[15:0]}; 
							memFetchCount =2; 
							memRead = 1'b0; 
							memWrite =1'b1; 
							TaskSaveState <= WriteToTSS; 
 
						end 
						2'd3: 
						begin 
							if(!getldtr) 
							begin 
								TSSbuffer = memData; 
								memAddr = memAddr +60;  
								getldtr =1'b1; 
							end 
							else 
							begin 
								 
								buffer[64] = memData[15:7]; 
								buffer[65] = memData[23:16]; 
								dataWr = {buffer[0],TSSbuffer[24:0]};							 
								memFetchCount =1; 
								memAddr = memAddr-60; 
								memRead = 1'b0; 
								memWrite =1'b1; 
								TaskSaveState <= WriteToTSS; 
 
							end 
 
						end 
						endcase 
					end 
				end 
				WriteToTSS: 
				begin 
					if(ack) 
					begin 
						dataWr[7:0]   = buffer[memFetchCount]; 
						dataWr[15:8]  = buffer[memFetchCount+1]; 
						dataWr[23:16] = buffer[memFetchCount+2]; 
						dataWr[31:24] = buffer[memFetchCount+3]; 
						memFetchCount = memFetchCount +4; 
						if((memFetchCount-bufferposition)>= 62) 
						begin 
							memWrite = 1'b0; 
							TaskSaveState <= AddrCal; 
							State	<= FetchNewReg; 
							 
						end	 
						else 
						begin 
							memAddr = memAddr + 3'd4; 
							 
						end 
					end 
				end 
				endcase								 
			end 
			FetchNewReg: 
			begin 
				case(TaskReadState) 
				ReadAddrCal: 
				begin 
					memAddrIndex =  temptrBase+28; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead = 1'b1; 
					memFetchCount =0; 
					TaskReadState <= ReadToBuffer; 
				end 
				ReadToBuffer: 
				begin 
					if(ack) 
					begin 
						buffer[memFetchCount] = memData [7:0]; 
						buffer[memFetchCount+1] = memData[15:8]; 
						buffer[memFetchCount+2] = memData[23:16]; 
						buffer[memFetchCount+3] = memData[31:24]; 
						memFetchCount = memFetchCount +4; 
						if((memFetchCount-bufferposition)>= 70) 
						begin 
							memRead = 1'b0; 
							TaskReadState <= TempReg; 
														 
						end	 
						else 
						begin 
							memAddr = memAddr + 3'd4; 
							 
						end 
					end 
				end 
				TempReg: 
				begin 
					tempPDBR[0]	= buffer[bufferposition]; 
					tempPDBR[1]	= buffer[bufferposition+1]; 
					tempPDBR[2]	= buffer[bufferposition+2]; 
					tempPDBR[3]	= buffer[bufferposition+3]; 
					tempPC[0]	= buffer[bufferposition+4] ; 
					tempPC[1]	= buffer[bufferposition+5] ; 
					tempPC[2]	= buffer[bufferposition+6] ; 
					tempPC[3]	= buffer[bufferposition+7] ; 
					tempEflags[0]	= buffer[bufferposition+8] ; 
					tempEflags[1]	= buffer[bufferposition+9] ; 
					tempEflags[2]	= buffer[bufferposition+10] ; 
					tempEflags[3]	= buffer[bufferposition+11] ; 
					tempEAX[0]	= buffer[bufferposition+12] ; 
					tempEAX[1]	= buffer[bufferposition+13] ; 
					tempEAX[2]	= buffer[bufferposition+14] ; 
					tempEAX[3]	= buffer[bufferposition+15] ; 
					tempECX[0]	= buffer[bufferposition+16] ; 
					tempECX[1]	= buffer[bufferposition+17] ; 
					tempECX[2]	= buffer[bufferposition+18] ; 
					tempECX[3]	= buffer[bufferposition+19] ; 
					tempEDX[0]	= buffer[bufferposition+20] ; 
					tempEDX[1]	= buffer[bufferposition+21] ; 
					tempEDX[2]	= buffer[bufferposition+22] ; 
					tempEDX[3]	= buffer[bufferposition+23] ; 
					tempEBX[0]	= buffer[bufferposition+24] ; 
					tempEBX[1]	= buffer[bufferposition+25] ; 
					tempEBX[2]	= buffer[bufferposition+26] ; 
					tempEBX[3]	= buffer[bufferposition+27] ; 
					tempESP[0]	= buffer[bufferposition+28] ; 
					tempESP[1]	= buffer[bufferposition+29] ; 
					tempESP[2]	= buffer[bufferposition+30] ; 
					tempESP[3]	= buffer[bufferposition+31] ; 
					tempEBP[0]	= buffer[bufferposition+32] ; 
					tempEBP[1]	= buffer[bufferposition+33] ; 
					tempEBP[2]	= buffer[bufferposition+34] ; 
					tempEBP[3]	= buffer[bufferposition+35] ; 
					tempESI[0]	= buffer[bufferposition+36] ; 
					tempESI[1]	= buffer[bufferposition+37] ; 
					tempESI[2]	= buffer[bufferposition+38] ; 
					tempESI[3]	= buffer[bufferposition+39] ; 
					tempEDI[0]	= buffer[bufferposition+40] ; 
					tempEDI[1]	= buffer[bufferposition+41] ; 
					tempEDI[2]	= buffer[bufferposition+42] ; 
					tempEDI[3]	= buffer[bufferposition+43] ; 
 
					tempes[0]	= buffer[bufferposition+44] ;  
					tempes[1]	= buffer[bufferposition+45];  
 
					tempcs[0]	= buffer[bufferposition+48] ; 
					tempcs[1]	= buffer[bufferposition+49] ; 
                                                                 
					tempss[0]	= buffer[bufferposition+52] ; 
					tempss[1]	= buffer[bufferposition+53] ; 
 
 
					tempds[0]	= buffer[bufferposition+56] ; 
					tempds[1]	= buffer[bufferposition+57] ; 
 
					tempfs[0]	= buffer[bufferposition+60] ; 
					tempfs[1]	= buffer[bufferposition+61] ; 
 
					tempgs[0]	= buffer[bufferposition+64] ; 
					tempgs[1]	= buffer[bufferposition+65] ; 
 
					templdtr[0]	= buffer[68]; 
					templdtr[1]	= buffer[69]; 
					if(operation !=11'd25 && operation != 11'd164) 
					begin 
						tempEflags[`NT] = 1'b1; 
						if(operation != 11'd25) 
							tempDestrShadow[`Busy] = 1'b1; 
					end 
					TaskReadState <= TempReg; 
					State <= FetchNewDes; 
				end 
				endcase	 
			end 
			FetchNewDes: 
			begin 
				case(ReadNewDesState) 
				FetchLDTRDes: 
				begin 
					tempAddress =  GDTRreg[31:0]; 
					 
					memAddrIndex =  tempAddress + {templdtr[15:3],3'b000}; 
 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetLDTRDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetLDTRDes: 
				begin 
					templdtrShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					templdtrBase = { templdtrShadow[63:56],templdtrShadow[37:16]}; 
					if(templdtrShadow[`Type] != 4'b0010) 
					begin 
						 
						State <= ExceptionWait; 
					end 
					 
					if(tempcs[2]) 
						memAddrIndex =  templdtrBase + {tempcs[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempcs[15:3],3'b000}; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetCSDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetCSDes: 
				begin 
					tempcsShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					if(!tempcsShadow [`CodeSeg]) 
					begin 
						 
						State <= ExceptionWait; 
					end	 
					if(tempds[2]) 
						memAddrIndex =  templdtrBase + {tempds[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempds[15:3],3'b000}; 
 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetDSDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetDSDes: 
				begin 
					tempdsShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					if(tempdsShadow [`CodeSeg] && !tempdsShadow[`ReadSeg]) 
					begin 
						 
						State <= ExceptionWait; 
					end 
					if(tempss[2]) 
						memAddrIndex =  templdtrBase + {tempss[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempss[15:3],3'b000}; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetSSDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetSSDes: 
				begin 
					tempssShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					if(!tempssShadow [`CodeSeg] ) 
					begin 
						if(!tempssShadow[`WrSeg]) 
						begin 
							 
							State <= ExceptionWait; 
						end 
					end 
					else 
					begin 
						State <= ExceptionWait; 
					end 
					if(tempes[2]) 
						memAddrIndex =  templdtrBase + {tempes[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempes[15:3],3'b000}; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetESDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetESDes: 
				begin 
					tempesShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					if(tempesShadow [`CodeSeg] && !tempesShadow[`ReadSeg]) 
					begin 
						 
						State <= ExceptionWait; 
					end 
					if(tempfs[2]) 
						memAddrIndex =  templdtrBase + {tempfs[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempfs[15:3],3'b000}; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetFSDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetFSDes: 
				begin 
					tempfsShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					if(tempfsShadow [`CodeSeg] && !tempfsShadow[`ReadSeg]) 
					begin 
						 
						State <= ExceptionWait; 
					end 
					if(tempgs[2]) 
						memAddrIndex =  templdtrBase + {tempgs[15:3],3'b000}; 
 
					else 
						memAddrIndex =  tempAddress + {tempgs[15:3],3'b000}; 
					memAddr = {memAddrIndex[31:2],2'b00}; 
					bufferposition = memAddrIndex[1:0]; 
					memRead =1; 
					memFetchCount =0; 
					NextDesState <= GetGSDes; 
					ReadNewDesState <= ReadFrommem; 
				end 
				GetGSDes: 
				begin 
					tempgsShadow = {buffer[bufferposition+7],buffer[bufferposition+6],buffer[bufferposition+5],buffer[bufferposition+4],buffer[bufferposition+3],buffer[bufferposition+2],buffer[bufferposition+1],buffer[bufferposition]}; 
					State <= UpdateTR; 
					if(tempgsShadow [`CodeSeg] && !tempgsShadow[`ReadSeg]) 
					begin 
						 
						State <= ExceptionWait; 
					end 
					memFetchCount =0; 
					 
					ReadNewDesState <= ReadFrommem; 
				end 
				ReadFrommem: 
				begin 
					if(ack) 
					begin 
						buffer[memFetchCount] = memData [7:0]; 
						buffer[memFetchCount+1] = memData[15:8]; 
						buffer[memFetchCount+2] = memData[23:16]; 
						buffer[memFetchCount+3] = memData[31:24]; 
						memFetchCount = memFetchCount +4; 
						if((memFetchCount-bufferposition)>= 70) 
						begin 
							memRead = 1'b0; 
							ReadNewDesState <= NextDesState ; 
														 
						end	 
						else 
						begin 
							memAddr = memAddr + 3'd4; 
							 
						end 
					end 
 
				end 
				endcase 
 
				 
			end 
			UpdateTR: 
			begin 
				mode =1; 
				context_out[159:96] = tempDestr; 
				context_out[175:160] = tempDestrShadow; 
 
				address [26:0] = 37'b0; 
				address [28:27] =2'b00; //selecting LDTR 
				address [29] = 1;	//enabling write 
				address [34:30] = 6'b10000;// for slecting  
				address [53:35] = 19'b0; 
 
			end 
			UpdateReg: 
			begin 
				case(RegUpdateState) 
				UpdateCSAXBX: 
				begin 
				mode =1'b0; 
				address [53:0] = 54'b0; 
				State		<= FetchGDTR; 
				RegFetchState	<= FetchCSAXBX; 
				TaskSaveState	<= AddrCal; 
				RegUpdateState	<= UpdateCSAXBX; 
				TaskReadState	<= ReadAddrCal; 
				ExceptionEnable = 1'b0; 
				TaskSwitchOver = 1'b0;	context_out[31:0] = tempEAX ; 
					context_out[95:64] = tempEBX; 
					context_out[159:96] = tempcs; 
					context_out[175:160] = tempcsShadow; 
					address [8:0]	= 9'b0; 
					address [11:9]	= `EBX; 
					address [15:12]	= 4'b1000; 
					address	[16]	= 1'b0; 
					address	[17]	= 1'b1; 
					address [20:18]	= `EAX;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= CS; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					size [4:3] = 2'b11; 
 
					RegUpdateState	<= UpdateDSCXDX; 
 
				end 
				UpdateDSCXDX: 
				begin 
					 
					context_out[31:0] = tempECX ; 
					context_out[95:64] = tempEDX; 
					context_out[159:96] = tempds; 
					context_out[175:160] = tempdsShadow; 
					address [8:0]	= 9'b0; 
					address [11:9]	= `EDX; 
					address [15:12]	= 4'b1000; 
					address	[16]	= 1'b0; 
					address	[17]	= 1'b1; 
					address [20:18]	= `ECX;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= DS; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					size [4:3] = 2'b11; 
 
					RegUpdateState	<= UpdateESBP; 
 
				end 
				UpdateESBP: 
				begin 
					context_out[31:0] = tempEBP ; 
					context_out[159:96] = tempes; 
					context_out[175:160] = tempesShadow; 
 
					address [17:0]	= 18'b0; 
					address [20:18]	= `EBP;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making read bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= ES; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
 
					RegUpdateState	<= UpdateSSSP; 
 
				end 
				UpdateSSSP:  
				begin 
					context_out[31:0] = tempESP ; 
					context_out[159:96] = tempss; 
					context_out[175:160] = tempssShadow; 
 
					address [17:0]	= 18'b0; 
					address [20:18]	= `ESP;	//Selecting ESP in general purpose registers 
address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making read bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= SS; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					RegUpdateState	<= UpdateFSSI; 
 
				end 
				UpdateFSSI: 
				begin 
					context_out[31:0] = tempESI ; 
					context_out [159:96] = tempfs; 
					context_out [175:160] = tempfsShadow; 
					address [17:0]	= 18'b0; 
					address [20:18]	= `ESI;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making read bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= FS; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [53:36]	= 18'b0; 
					size [7:6] = 2'b11; 
					RegUpdateState	<= UpdateIPGSDI; 
 
				end 
				UpdateIPGSDI: 
				begin 
					context_out[31:0] = tempEDI ; 
					context_out[159:96] = tempgs; 
					context_out[175:160] = tempgsShadow; 
					eflags_out = tempEflags; 
					address [17:0]	= 18'b0; 
					address [20:18]	= `EDI;	//Selecting EAX in general purpose registers 
					address	[24:21]	= 4'b1000; //Selecting ESP in read mode 
					address	[25]	= 1'b0;	// making write bit as zero 
					address [26]	= 1'b1; // make memory  addrss mode 
					address [29:27]	= GS; // selecting proper segment register 
					address [35:30]	= 6'b001000;// Enabling segment and shadow registers in read mode				 
					address [38:36]	= 3'b110;// for updating Eflags 
					address	[53:39] = 15'b0; 
					size [7:6] = 2'b11; 
 
					newPC = tempPC; 
					flush = 1'b1; 
 
					RegUpdateState	<= UpdateLDTR; 
 
				end 
				UpdateLDTR: 
				begin 
					flush = 1'b0; 
					mode =1; 
					context_out[159:96] = templdtr; 
					context_out[175:160] = templdtrShadow; 
 
					address [26:0] = 37'b0; 
					address [28:27] =2'b01; //selecting LDTR 
					address [29] = 1;	//enabling write 
					address [34:30] = 5'b10000;// for slecting  
					address [53:35] = 19'b0; 
				end 
				UpdatePDBR: 
				begin 
					mode =1; 
					context_out[127:96] = tempPDBR; 
					address	[53:27] = 27'b0; 
					address [26]=1'b1; 
					address [25] = 1'b0; 
					address [24:21]= 4'b1000;// enabling write 
					address [20:18]= 3'b011; 
					address	[17:0]= 18'b0; 
					TaskSwitchOver= 1'b1; 
				end 
				endcase 
 
			end 
			SwitchOver: 
			begin 
				mode =1'b0; 
				State		<= FetchGDTR; 
				RegFetchState	<= FetchCSAXBX; 
				TaskSaveState	<= AddrCal; 
				RegUpdateState	<= UpdateCSAXBX; 
				TaskReadState	<= ReadAddrCal; 
				ExceptionEnable = 1'b0; 
				TaskSwitchOver = 1'b0; 
				size = 9'b0; 
				context_out = 271'b0; 
			end 
			ExceptionWait: 
			begin 
				if(ExceptionAck) 
				begin 
					mode =1'b0; 
					State		<= FetchGDTR; 
					RegFetchState	<= FetchCSAXBX; 
					TaskSaveState	<= AddrCal; 
					RegUpdateState	<= UpdateCSAXBX; 
					TaskReadState	<= ReadAddrCal; 
					ExceptionEnable = 1'b0; 
					TaskSwitchOver = 1'b0; 
					context_out = 272'b0; 
					size =9'b0; 
				end 
			end 
			endcase 
		end 
	end 
end 
endmodule