module FP_STAT_REG ( BCLK, BRESET, LFSR, UP_SP, UP_DP, TT_SP, TT_DP, WREN, WRADR, DIN, FSR, TWREN, FPU_TRAP, SAVE_PC);
	
	input			BCLK;
	input			BRESET;
	input			LFSR;	// Load by LFSR opcode
	input			UP_SP,UP_DP;	// update if calculation operation
	input 	 [4:0]	TT_SP,TT_DP;
	input			WREN;	// for RMB and LFSR
	input	 [5:4]	WRADR;
	input 	[16:0] 	DIN;	// Data for LFSR opcode
	
	output	[31:0] 	FSR;
	output			TWREN;
	output	reg		FPU_TRAP;
	output			SAVE_PC;
	
	reg		 [4:3]	trap_d;
	reg				update_d;
	reg				set_rm_d;
	reg		[10:0]	set_bits;
	reg		 [4:0]	flags;
	reg				rm_bit;
	
	wire			load_fsr;
	wire			update,update_i;
	wire	 [4:0]	trap;
	wire			uflag,iflag,rmflag;

	assign load_fsr = LFSR & WREN;
	
	assign trap = UP_SP ? TT_SP : TT_DP;
	
	// This signal suppresses write into registers if FPU Trap, timing critical signal !
	assign TWREN = ~((UP_SP & (TT_SP[2:0] != 3'b0)) | (UP_DP & (TT_DP[2:0] != 3'b0)));
	
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) FPU_TRAP <= 1'b0;
		  else FPU_TRAP <= ~FPU_TRAP & ~TWREN;	// one pulse of one cycle informs the Opcode Decoder
				
	assign update_i = (UP_SP | UP_DP) & ~FPU_TRAP;	// unfortunately one FPU opcode may follow !
	always @(posedge BCLK) update_d	<= update_i;
	always @(posedge BCLK) trap_d	<= trap[4:3];
	always @(posedge BCLK) set_rm_d	<= WREN & (WRADR == 2'b10);
	assign update = update_d & ~FPU_TRAP;
	
	// The Flags are set and stay "1" 
	assign iflag  = (update & trap_d[4]) | flags[4];	// Inexact Result
	assign uflag  = (update & trap_d[3]) | flags[3];	// Underflow
	assign rmflag = (set_rm_d & ~FPU_TRAP) | rm_bit;	// Register Modify

	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) flags[4:3] <= 2'b0;	// Inexact = Bit6, Underflow = Bit4
		  else
		  begin
			if (load_fsr) flags[4:3] <= {DIN[6],DIN[4]};
			  else
				if (update) flags[4:3] <= {iflag,uflag};
		  end
		  
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) flags[2:0] <= 3'b0;	// TT Field = Bit2-0
		  else
		  begin
			if (load_fsr) flags[2:0] <= DIN[2:0];
			  else
				if (update_i) flags[2:0] <= trap[2:0];
		  end
		  
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) rm_bit <= 1'b0;	// Register Modify Bit
		  else
		  begin
			if (load_fsr) rm_bit <= DIN[16];
			  else
				if (set_rm_d & ~FPU_TRAP) rm_bit <= 1'b1;	// in case of TRAP there is no writing to Register
		  end
		
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) set_bits <= 11'b0;	// all other Bits
		  else
			if (load_fsr) set_bits <= {DIN[15:7],DIN[5],DIN[3]};

	assign FSR = {15'h0,rmflag,set_bits[10:2],iflag,set_bits[1],uflag,set_bits[0],flags[2:0]};
	
	assign SAVE_PC = (UP_SP | UP_DP) & ~FPU_TRAP;	// Store the correct PC for FPU Trap
	
endmodule