--
--  File: Ctrl_unit.vhd
--  created by Design Wizard: 01/08/02 04:55:53
--

--{{ Section below this comment is automatically maintained
--   and may be overwritten
--{entity {Ctrl_unit} architecture {Ctrl_unit_bh}}

library IEEE;
use IEEE.std_logic_1164.all;		   
use ieee.numeric_std.all;  
--use IEEE.std_logic_arith.CONV_STD_LOGIC_VECTOR;

entity Ctrl_unit is
	port (		
		-- Inputs
		-- From IFDR stage	 
				IR_Opcode_L : in STD_LOGIC_VECTOR (5 downto 0);
				IR_Subopsw_L: in STD_LOGIC_VECTOR (7 downto 0);
				IR_Rd_L   : in STD_LOGIC_VECTOR (4 downto 0);
				IR_Rs1_L  : in STD_LOGIC_VECTOR (4 downto 0);
                IR_Rs2_L  : in STD_LOGIC_VECTOR (4 downto 0);
                IR_imm_L  : in STD_LOGIC_VECTOR (63 downto 0);
                IR_we_RF_L: in STD_LOGIC_VECTOR (0 downto 0);
				IR_wr_pred_addr1_L: in std_logic_vector (2 downto 0);
				IR_wr_pred_addr2_L: in std_logic_vector (2 downto 0);
				IR_we_pred_L : in STD_LOGIC_VECTOR (0 downto 0);	   
				IR_pred_L : in STD_LOGIC_VECTOR (2 downto 0);
				IR_pred_imm4_L : in STD_LOGIC_VECTOR (3 downto 0);
				IR_pred_imm8_L : in STD_LOGIC_VECTOR (7 downto 0);   
				IR_we_Dcache_L: in STD_LOGIC_VECTOR (0 downto 0);
                IR_we_RF_M_L  : in STD_LOGIC_VECTOR (0 downto 0);
				IR_Rd_M_L     : in STD_LOGIC_VECTOR (4 downto 0); 
				IR_PC_L     : in STD_LOGIC_VECTOR (31 downto 0);
				----
                IR_Opcode_R : in STD_LOGIC_VECTOR (5 downto 0);
                IR_Subopsw_R: in STD_LOGIC_VECTOR (7 downto 0);
                IR_Rd_R   : in STD_LOGIC_VECTOR (4 downto 0);
                IR_Rs1_R  : in STD_LOGIC_VECTOR (4 downto 0);
                IR_Rs2_R  : in STD_LOGIC_VECTOR (4 downto 0);
                IR_imm_R  : in STD_LOGIC_VECTOR (63 downto 0);
                IR_we_RF_R: in STD_LOGIC_VECTOR (0 downto 0);
				IR_wr_pred_addr1_R: in std_logic_vector (2 downto 0);	  
				IR_wr_pred_addr2_R: in std_logic_vector (2 downto 0);
				IR_we_pred_R : in STD_LOGIC_VECTOR (0 downto 0);	
				IR_pred_R : in STD_LOGIC_VECTOR (2 downto 0);
				IR_pred_imm4_R : in STD_LOGIC_VECTOR (3 downto 0);  
				IR_pred_imm8_R : in STD_LOGIC_VECTOR (7 downto 0);  
				IR_we_Dcache_R: in STD_LOGIC_VECTOR (0 downto 0);
                IR_we_RF_M_R  : in STD_LOGIC_VECTOR (0 downto 0);
                IR_Rd_M_R     : in STD_LOGIC_VECTOR (4 downto 0); 
				IR_PC_R     : in STD_LOGIC_VECTOR (31 downto 0);
				IR_banksel: in STD_LOGIC_VECTOR (3 downto 0);	 
				IR_pred_d_L: in STD_LOGIC;
				IR_pred_d_R: in STD_LOGIC;	 
				IR_Instr_type_L : in STD_LOGIC_VECTOR (8 downto 0);
				IR_Instr_type_R : in STD_LOGIC_VECTOR (8 downto 0);
				--=========================================================
				-- From DRE
				-- left part
				DRE_Opcode_L : in STD_LOGIC_VECTOR (5 downto 0);
				DRE_Subopsw_L: in STD_LOGIC_VECTOR (7 downto 0);
				DRE_Rd_L   : in STD_LOGIC_VECTOR (4 downto 0);
				DRE_Rs1_L  : in STD_LOGIC_VECTOR (4 downto 0);
        		DRE_Rs2_L  : in STD_LOGIC_VECTOR (4 downto 0); 
				DRE_st_L   : in STD_LOGIC_VECTOR (63 downto 0);
                DRE_imm_L  : in STD_LOGIC_VECTOR (63 downto 0);
                DRE_we_RF_L: in STD_LOGIC_VECTOR (0 downto 0);	 
				DRE_we_Dcache_L: in STD_LOGIC_VECTOR (0 downto 0);
                DRE_we_RF_M_L  : in STD_LOGIC_VECTOR (0 downto 0);
                DRE_Rd_M_L     : in STD_LOGIC_VECTOR (4 downto 0);	
				DRE_wr_pred_addr1_L: in std_logic_vector (2 downto 0);
				DRE_wr_pred_addr2_L: in std_logic_vector (2 downto 0);	
				DRE_we_pred_L : in STD_LOGIC_VECTOR (0 downto 0);
				DRE_valid_L  : in STD_LOGIC_VECTOR (0 downto 0);  
				DRE_PC_L     : in STD_LOGIC_VECTOR (31 downto 0);
				DRE_pred_L	 : in STD_LOGIC_VECTOR (2 downto 0);   
    			-- right part            
				DRE_Opcode_R : in STD_LOGIC_VECTOR (5 downto 0);
                DRE_Subopsw_R: in STD_LOGIC_VECTOR (7 downto 0);
                DRE_Rd_R   : in STD_LOGIC_VECTOR (4 downto 0);
                DRE_Rs1_R  : in STD_LOGIC_VECTOR (4 downto 0);
                DRE_Rs2_R  : in STD_LOGIC_VECTOR (4 downto 0); 
				DRE_st_R   : in STD_LOGIC_VECTOR (63 downto 0);
                DRE_imm_R  : in STD_LOGIC_VECTOR (63 downto 0);
                DRE_we_RF_R: in STD_LOGIC_VECTOR (0 downto 0);
				DRE_we_Dcache_R: in STD_LOGIC_VECTOR (0 downto 0);
                DRE_we_RF_M_R  : in STD_LOGIC_VECTOR (0 downto 0);
                DRE_Rd_M_R     : in STD_LOGIC_VECTOR (4 downto 0);	
				DRE_wr_pred_addr1_R: in std_logic_vector (2 downto 0);	
				DRE_wr_pred_addr2_R: in std_logic_vector (2 downto 0);	
				DRE_we_pred_R : in STD_LOGIC_VECTOR (0 downto 0); 
				DRE_valid_R  : in STD_LOGIC_VECTOR (0 downto 0);  
				DRE_PC_R     : in STD_LOGIC_VECTOR (31 downto 0);
				DRE_pred_R	 : in STD_LOGIC_VECTOR (2 downto 0);   
				DRE_Instr_type_L : in STD_LOGIC_VECTOR (8 downto 0);
				DRE_Instr_type_R : in STD_LOGIC_VECTOR (8 downto 0);
				DRE_unknown	 : in  STD_LOGIC;	 -- '0' is false,i.e., known and '1' is true, i.e., unknown.
				DRE_banksel  : in STD_LOGIC_VECTOR (3 downto 0);
				-- =====================================================
       			-- From EDF
				EDF_Opcode_L : in STD_LOGIC_VECTOR (5 downto 0);
				EDF_Subopsw_L: in STD_LOGIC_VECTOR (7 downto 0);
				EDF_Rd_L   : in STD_LOGIC_VECTOR (4 downto 0);
				EDF_Rs1_L  : in STD_LOGIC_VECTOR (4 downto 0);
        		EDF_Rs2_L  : in STD_LOGIC_VECTOR (4 downto 0);
                EDF_imm_L  : in STD_LOGIC_VECTOR (63 downto 0);
                EDF_we_RF_L: in STD_LOGIC_VECTOR (0 downto 0);	 
				EDF_we_Dcache_L: in STD_LOGIC_VECTOR (0 downto 0);
                EDF_we_RF_M_L  : in STD_LOGIC_VECTOR (0 downto 0);
                EDF_Rd_M_L     : in STD_LOGIC_VECTOR (4 downto 0);	
				EDF_wr_pred_addr1_L: in std_logic_vector (2 downto 0);
				EDF_wr_pred_addr2_L: in std_logic_vector (2 downto 0);	
				EDF_we_pred_L : in STD_LOGIC_VECTOR (0 downto 0);
				EDF_valid_L  : in STD_LOGIC_VECTOR (0 downto 0);  
				EDF_PC_L     : in STD_LOGIC_VECTOR (31 downto 0);
				EDF_pred_L	 : in STD_LOGIC_VECTOR (2 downto 0);  
				EDF_data_L   : in STD_LOGIC_VECTOR (63 downto 0);
    			-- right part            
				EDF_Opcode_R : in STD_LOGIC_VECTOR (5 downto 0);
                EDF_Subopsw_R: in STD_LOGIC_VECTOR (7 downto 0);
                EDF_Rd_R   : in STD_LOGIC_VECTOR (4 downto 0);
                EDF_Rs1_R  : in STD_LOGIC_VECTOR (4 downto 0);
                EDF_Rs2_R  : in STD_LOGIC_VECTOR (4 downto 0);
                EDF_imm_R  : in STD_LOGIC_VECTOR (63 downto 0);
                EDF_we_RF_R: in STD_LOGIC_VECTOR (0 downto 0);
				EDF_we_Dcache_R: in STD_LOGIC_VECTOR (0 downto 0);
                EDF_we_RF_M_R  : in STD_LOGIC_VECTOR (0 downto 0);
                EDF_Rd_M_R     : in STD_LOGIC_VECTOR (4 downto 0);	
				EDF_wr_pred_addr1_R: in std_logic_vector (2 downto 0);	
				EDF_wr_pred_addr2_R: in std_logic_vector (2 downto 0);	
				EDF_we_pred_R : in STD_LOGIC_VECTOR (0 downto 0); 
				EDF_valid_R  : in STD_LOGIC_VECTOR (0 downto 0);  
				EDF_PC_R     : in STD_LOGIC_VECTOR (31 downto 0);
				EDF_pred_R	 : in STD_LOGIC_VECTOR (2 downto 0);
				EDF_banksel  : in STD_LOGIC_VECTOR(3 downto 0);		
				EDF_pred_d_L: in STD_LOGIC;
				EDF_pred_d_R: in STD_LOGIC;
				EDF_Instr_type_L : in STD_LOGIC_VECTOR (8 downto 0);
				EDF_Instr_type_R : in STD_LOGIC_VECTOR (8 downto 0);
				EDF_data_R   : in STD_LOGIC_VECTOR (63 downto 0);  
				MULEDF_L     : in STD_LOGIC_VECTOR (5 downto 0);
				MULEDF_R     : in STD_LOGIC_VECTOR (5 downto 0);
				--======================================================
				-- From DFW	stage
				DFW_Opcode_L : in STD_LOGIC_VECTOR (5 downto 0);
				DFW_Subopsw_L: in STD_LOGIC_VECTOR (7 downto 0);
				DFW_Rd_L   : in STD_LOGIC_VECTOR (4 downto 0);
				DFW_Rs1_L  : in STD_LOGIC_VECTOR (4 downto 0);
        		DFW_Rs2_L  : in STD_LOGIC_VECTOR (4 downto 0);
                DFW_imm_L  : in STD_LOGIC_VECTOR (63 downto 0);
                DFW_we_RF_L: in STD_LOGIC_VECTOR (0 downto 0);	 
				DFW_we_Dcache_L: in STD_LOGIC_VECTOR (0 downto 0);
                DFW_we_RF_M_L  : in STD_LOGIC_VECTOR (0 downto 0);
                DFW_Rd_M_L     : in STD_LOGIC_VECTOR (4 downto 0);	
				DFW_wr_pred_addr1_L: in std_logic_vector (2 downto 0);
				DFW_wr_pred_addr2_L: in std_logic_vector (2 downto 0);	
				DFW_we_pred_L : in STD_LOGIC_VECTOR (0 downto 0);
				DFW_valid_L  : in STD_LOGIC_VECTOR (0 downto 0);  
				DFW_PC_L     : in STD_LOGIC_VECTOR (31 downto 0);
				DFW_pred_L	 : in STD_LOGIC_VECTOR (2 downto 0); 
				DFW_cache_L	 : in STD_LOGIC_VECTOR (63 downto 0); 
				DFW_data_L	 : in STD_LOGIC_VECTOR (63 downto 0);
    			-- right part            
				DFW_Opcode_R : in STD_LOGIC_VECTOR (5 downto 0);
                DFW_Subopsw_R: in STD_LOGIC_VECTOR (7 downto 0);
                DFW_Rd_R   : in STD_LOGIC_VECTOR (4 downto 0);
                DFW_Rs1_R  : in STD_LOGIC_VECTOR (4 downto 0);
                DFW_Rs2_R  : in STD_LOGIC_VECTOR (4 downto 0);
                DFW_imm_R  : in STD_LOGIC_VECTOR (63 downto 0);
                DFW_we_RF_R: in STD_LOGIC_VECTOR (0 downto 0);
				DFW_we_Dcache_R: in STD_LOGIC_VECTOR (0 downto 0);
                DFW_we_RF_M_R  : in STD_LOGIC_VECTOR (0 downto 0);
                DFW_Rd_M_R     : in STD_LOGIC_VECTOR (4 downto 0);	
				DFW_wr_pred_addr1_R: in std_logic_vector (2 downto 0);	
				DFW_wr_pred_addr2_R: in std_logic_vector (2 downto 0);	
				DFW_we_pred_R : in STD_LOGIC_VECTOR (0 downto 0); 
				DFW_valid_R  : in STD_LOGIC_VECTOR (0 downto 0);  
				DFW_PC_R     : in STD_LOGIC_VECTOR (31 downto 0);
				DFW_pred_R	 : in STD_LOGIC_VECTOR (2 downto 0);
				DFW_banksel  : in STD_LOGIC_VECTOR (3 downto 0);	 
				DFW_cache_R	 : in STD_LOGIC_VECTOR (63 downto 0); 
				DFW_data_R	 : in STD_LOGIC_VECTOR (63 downto 0);
				DFW_pred_d_L: in STD_LOGIC;
				DFW_pred_d_R: in STD_LOGIC;
				DFW_Instr_type_L : in STD_LOGIC_VECTOR (8 downto 0);
				DFW_Instr_type_R : in STD_LOGIC_VECTOR (8 downto 0); 
				MULDFW_L     : in STD_LOGIC_VECTOR (5 downto 0);
				MULDFW_R     : in STD_LOGIC_VECTOR (5 downto 0);
				--				
				DR_Rs1_L     : in STD_LOGIC_VECTOR (63 downto 0);
				DR_Rs2_L     : in STD_LOGIC_VECTOR (63 downto 0);
				DR_Rs1_R     : in STD_LOGIC_VECTOR (63 downto 0);
				DR_Rs2_R     : in STD_LOGIC_VECTOR (63 downto 0);
				Dcacheout    : in STD_LOGIC_VECTOR (63 downto 0); 
				MUL_L     : in STD_LOGIC_VECTOR (63 downto 0);
				MUL_R     : in STD_LOGIC_VECTOR (63 downto 0);
				SHF_L     : in STD_LOGIC_VECTOR (63 downto 0);
				SHF_R     : in STD_LOGIC_VECTOR (63 downto 0);
				ALU_L     : in STD_LOGIC_VECTOR (63 downto 0);
				ALU_R     : in STD_LOGIC_VECTOR (63 downto 0);	  
				reset     : in STD_LOGIC;
				--------------------------------------------------------
				-- output ports
				--------------------------------------------------------
				DR_valid_L: out STD_LOGIC;
				DR_valid_R: out STD_LOGIC;
				E_valid_R:  out STD_LOGIC;
				DR_unknown: out STD_LOGIC;
				JMP_disp :  out STD_LOGIC_VECTOR (31 downto 0);	 
				JMPvalidL:  out STD_LOGIC;
				JMPvalidR:  out STD_LOGIC;
				DRMUX1_L :  out STD_LOGIC_VECTOR (63 downto 0);
				DRMUX2_L :  out STD_LOGIC_VECTOR (63 downto 0);	
				DRMUX1_R :  out STD_LOGIC_VECTOR (63 downto 0);
				DRMUX2_R :  out STD_LOGIC_VECTOR (63 downto 0);
				E_st_addr:  out STD_LOGIC_VECTOR (31 downto 0);
				E_st_data:  out	STD_LOGIC_VECTOR (63 downto 0);
				pred_imm8:  out STD_LOGIC_VECTOR (7 downto 0);
				pred_we8b:  out STD_LOGIC;
				Dcache_we:  out STD_LOGIC;
				ALUoutL  :  out STD_LOGIC_VECTOR (63 downto 0);
				ALUoutR  :  out STD_LOGIC_VECTOR (63 downto 0);
				chpr_valid: out STD_LOGIC;
				chpr_imm4:  out STD_LOGIC_VECTOR (3 downto 0);
				CMPresuL :  out STD_LOGIC;
				CMPresuR :  out STD_LOGIC;
				MULpipe_L:  out STD_LOGIC_VECTOR (5 downto 0);
				MULpipe_R:  out STD_LOGIC_VECTOR (5 downto 0);
				RF_we_L  :  out STD_LOGIC;
				RF_we_R  :  out STD_LOGIC;
				RF_we_M  :  out STD_LOGIC;
				RF_data_L:  out STD_LOGIC_VECTOR (63 downto 0);
				RF_data_R:  out STD_LOGIC_VECTOR (63 downto 0);
				RF_data_M:  out STD_LOGIC_VECTOR (63 downto 0);
				RF_Rd_L:    out STD_LOGIC_VECTOR (4 downto 0);
				RF_Rd_R:    out STD_LOGIC_VECTOR (4 downto 0);
				RF_Rd_M:    out STD_LOGIC_VECTOR (4 downto 0);
				stallL :    out STD_LOGIC;
				stallR :    out STD_LOGIC;
				PCstall:	out STD_LOGIC;
				pred_we_L:  out STD_LOGIC;
				pred_we_R:  out STD_LOGIC
				

	);
end Ctrl_unit;

--}} End of automatically maintained section

architecture Ctrl_unit_bh of Ctrl_unit is
begin
	process	 (
			  IR_Opcode_L ,
				IR_Subopsw_L,
				IR_Rd_L  ,
				IR_Rs1_L  ,
                IR_Rs2_L ,
                IR_imm_L  ,
                IR_we_RF_L,
				IR_wr_pred_addr1_L,
				IR_wr_pred_addr2_L,
				IR_we_pred_L ,   
				IR_pred_L,
				IR_pred_imm4_L,
				IR_pred_imm8_L ,  
				IR_we_Dcache_L,
                IR_we_RF_M_L ,
				IR_Rd_M_L    ,
				IR_PC_L    ,
				----
                IR_Opcode_R ,
                IR_Subopsw_R,
                IR_Rd_R  ,
                IR_Rs1_R ,
                IR_Rs2_R  ,
                IR_imm_R  ,
                IR_we_RF_R,
				IR_wr_pred_addr1_R, 
				IR_wr_pred_addr2_R,
				IR_we_pred_R,
				IR_pred_R,
				IR_pred_imm4_R,
				IR_pred_imm8_R ,
				IR_we_Dcache_R,
                IR_we_RF_M_R ,
                IR_Rd_M_R ,
				IR_PC_R ,
				IR_banksel,
				IR_pred_d_L,
				IR_pred_d_R,
				IR_Instr_type_L,
				IR_Instr_type_R,
				--=========================================================
				-- From DRE
				-- left part
				DRE_Opcode_L ,
				DRE_Subopsw_L,
				DRE_Rd_L  ,
				DRE_Rs1_L ,
        		DRE_Rs2_L,
				DRE_st_L   ,
                DRE_imm_L ,
                DRE_we_RF_L,
				DRE_we_Dcache_L,
                DRE_we_RF_M_L ,
                DRE_Rd_M_L ,	
				DRE_wr_pred_addr1_L,
				DRE_wr_pred_addr2_L,
				DRE_we_pred_L ,
				DRE_valid_L,
				DRE_PC_L  ,
				DRE_pred_L, 
    			-- right part            
				DRE_Opcode_R,
                DRE_Subopsw_R,
                DRE_Rd_R  ,
                DRE_Rs1_R ,
                DRE_Rs2_R  ,
				DRE_st_R  ,
                DRE_imm_R ,
                DRE_we_RF_R,
				DRE_we_Dcache_R,
                DRE_we_RF_M_R ,
                DRE_Rd_M_R   ,
				DRE_wr_pred_addr1_R,
				DRE_wr_pred_addr2_R,	
				DRE_we_pred_R,
				DRE_valid_R ,
				DRE_PC_R   ,
				DRE_pred_R	,
				DRE_Instr_type_L,
				DRE_Instr_type_R,
				DRE_unknown	,
				DRE_banksel ,
				-- =====================================================
       			-- From EDF
				EDF_Opcode_L,
				EDF_Subopsw_L,
				EDF_Rd_L  ,
				EDF_Rs1_L ,
        		EDF_Rs2_L ,
                EDF_imm_L ,
                EDF_we_RF_L,
				EDF_we_Dcache_L,
                EDF_we_RF_M_L ,
                EDF_Rd_M_L  ,
				EDF_wr_pred_addr1_L,
				EDF_wr_pred_addr2_L,	
				EDF_we_pred_L ,
				EDF_valid_L  ,
				EDF_PC_L    ,
				EDF_pred_L	,
				EDF_data_L  ,
    			-- right part            
				EDF_Opcode_R,
                EDF_Subopsw_R,
                EDF_Rd_R  ,
                EDF_Rs1_R ,
                EDF_Rs2_R ,
                EDF_imm_R  ,
                EDF_we_RF_R,
				EDF_we_Dcache_R,
                EDF_we_RF_M_R ,
                EDF_Rd_M_R    ,	
				EDF_wr_pred_addr1_R,
				EDF_wr_pred_addr2_R,	
				EDF_we_pred_R ,
				EDF_valid_R  ,
				EDF_PC_R   ,
				EDF_pred_R	,
				EDF_banksel ,		
				EDF_pred_d_L,
				EDF_pred_d_R,
				EDF_Instr_type_L,
				EDF_Instr_type_R,
				EDF_data_R   ,
				MULEDF_L   ,
				MULEDF_R   ,
				-- From DFW	stage
				DFW_Opcode_L,
				DFW_Subopsw_L,
				DFW_Rd_L  ,
				DFW_Rs1_L ,
        		DFW_Rs2_L  ,
                DFW_imm_L ,
                DFW_we_RF_L, 
				DFW_we_Dcache_L,
                DFW_we_RF_M_L ,
                DFW_Rd_M_L   ,
				DFW_wr_pred_addr1_L,
				DFW_wr_pred_addr2_L,
				DFW_we_pred_L,
				DFW_valid_L,
				DFW_PC_L    ,
				DFW_pred_L	 ,
				DFW_cache_L	,
				DFW_data_L	,
    			-- right part            
				DFW_Opcode_R ,
                DFW_Subopsw_R,
                DFW_Rd_R  ,
                DFW_Rs1_R ,
                DFW_Rs2_R ,
                DFW_imm_R  ,
                DFW_we_RF_R,
				DFW_we_Dcache_R,
                DFW_we_RF_M_R ,
                DFW_Rd_M_R   ,
				DFW_wr_pred_addr1_R,
				DFW_wr_pred_addr2_R,
				DFW_we_pred_R ,
				DFW_valid_R ,
				DFW_PC_R    ,
				DFW_pred_R	,
				DFW_banksel ,
				DFW_cache_R	,
				DFW_data_R	,
				DFW_pred_d_L,
				DFW_pred_d_R,
				DFW_Instr_type_L ,
				DFW_Instr_type_R , 
				MULDFW_L    ,
				MULDFW_R    ,
				--				
				DR_Rs1_L    ,
				DR_Rs2_L    ,
				DR_Rs1_R    ,
				DR_Rs2_R     ,
				Dcacheout   ,
				MUL_L    ,
				MUL_R   ,
				SHF_L  ,
				SHF_R ,
				ALU_L   ,
				ALU_R)  							  
	-- If the instr is CMP, Testbit, CMPi, Chpr.upd, Is_CMP is set to be true
	variable IRL_IS_CMP, DREL_IS_CMP, DRER_IS_CMP, EDFL_IS_CMP, EDFR_IS_CMP, DFWL_IS_CMP, DFWR_IS_CMP : Boolean; 							   
	-- Boolean variables for address-equality checking, including validbit test
	variable DRELT_IRLS, DRERT_IRLS, DRELT_DRERS, EDFLT_IRLS, EDFRT_IRLS, DFWLT_IRLS, DFWRT_IRLS,
			 DRELT_IRRS, DRERT_IRRS, IRLT_IRRS  , EDFLT_IRRS, EDFRT_IRRS, DFWLT_IRRS, DFWRT_IRRS : Boolean;
	variable inter_DRvalidL, inter_DRvalidR, inter_EvalidR, inter_DRunknown : Boolean;
	variable IFDR_stallL, IFDR_stallR, IFDR_cancelL, IFDR_cancelR, inter_stallL, inter_stallR, inter_cancelL, 
			 inter_cancelR : Boolean;
	variable JMP_validL, JMP_validR, inter_JMPvalidL, inter_JMPvalidR: Boolean;
	variable CMP_resu_L, CMP_resu_R : STD_LOGIC;	
	variable chpr_imm8, tmpimm8 : STD_LOGIC_VECTOR (7 downto 0);		
	variable IR_ALU_inst_L,IR_CMP_inst_L,IR_CHPR_inst_L,IR_JMP_inst_L,IR_JMPreg_inst_L,IR_MUL_inst_L,IR_LD_inst_L,IR_LDI_inst_L,IR_ST_inst_L: STD_LOGIC;
 	variable IR_ALU_inst_R,IR_CMP_inst_R,IR_CHPR_inst_R,IR_JMP_inst_R,IR_JMPreg_inst_R,IR_MUL_inst_R,IR_LD_inst_R,IR_LDI_inst_R,IR_ST_inst_R: STD_LOGIC;
	variable DRE_ALU_inst_L,DRE_CMP_inst_L,DRE_CHPR_inst_L,DRE_JMP_inst_L,DRE_JMPreg_inst_L,DRE_MUL_inst_L,DRE_LD_inst_L,DRE_LDI_inst_L,DRE_ST_inst_L: STD_LOGIC;
 	variable DRE_ALU_inst_R,DRE_CMP_inst_R,DRE_CHPR_inst_R,DRE_JMP_inst_R,DRE_JMPreg_inst_R,DRE_MUL_inst_R,DRE_LD_inst_R,DRE_LDI_inst_R,DRE_ST_inst_R: STD_LOGIC;
	variable EDF_ALU_inst_L,EDF_CMP_inst_L,EDF_CHPR_inst_L,EDF_JMP_inst_L,EDF_JMPreg_inst_L,EDF_MUL_inst_L,EDF_LD_inst_L,EDF_LDI_inst_L,EDF_ST_inst_L: STD_LOGIC;
 	variable EDF_ALU_inst_R,EDF_CMP_inst_R,EDF_CHPR_inst_R,EDF_JMP_inst_R,EDF_JMPreg_inst_R,EDF_MUL_inst_R,EDF_LD_inst_R,EDF_LDI_inst_R,EDF_ST_inst_R: STD_LOGIC;	
	variable DFW_ALU_inst_L,DFW_CMP_inst_L,DFW_CHPR_inst_L,DFW_JMP_inst_L,DFW_JMPreg_inst_L,DFW_MUL_inst_L,DFW_LD_inst_L,DFW_LDI_inst_L,DFW_ST_inst_L: STD_LOGIC;
 	variable DFW_ALU_inst_R,DFW_CMP_inst_R,DFW_CHPR_inst_R,DFW_JMP_inst_R,DFW_JMPreg_inst_R,DFW_MUL_inst_R,DFW_LD_inst_R,DFW_LDI_inst_R,DFW_ST_inst_R: STD_LOGIC;
	variable IFDRLT_IFDRRS1, IFDRLT_IFDRRS2, DRELT_IFDRRS1, DRELT_IFDRRS2, EDFLT_IFDRRS1, EDFLT_IFDRRS2, 
			 DRERT_IFDRRS1, DRERT_IFDRRS2, EDFRT_IFDRRS1, EDFRT_IFDRRS2 , DFWLT_IFDRRS1, DFWLT_IFDRRS2, DFWRT_IFDRRS1, DFWRT_IFDRRS2 : Boolean;
	variable DRELT_IFDRLS1, DRELT_IFDRLS2, EDFLT_IFDRLS1, EDFLT_IFDRLS2, 
			 DRERT_IFDRLS1, DRERT_IFDRLS2, EDFRT_IFDRLS1, EDFRT_IFDRLS2, DFWLT_IFDRLS1, DFWLT_IFDRLS2, DFWRT_IFDRLS1, DFWRT_IFDRLS2: Boolean;
	variable inter_forwL1, inter_forwL2, inter_forwR1, inter_forwR2 : STD_LOGIC_VECTOR (63 downto 0);
	variable inter_st : STD_LOGIC_VECTOR (63 downto 0);
	variable Dcache_address: STD_LOGIC_VECTOR (31 downto 0);	
	variable inter_cache_we: STD_LOGIC;
	variable ALUout_L, ALUout_R: STD_LOGIC_VECTOR (63 downto 0);  
	variable inter_JMPdisp : STD_LOGIC_VECTOR (31 downto 0); 
	variable inter_chprvalid, inter_pred_we8b : STD_LOGIC;
	variable inter_chprimm4 :  STD_LOGIC_VECTOR (3 downto 0); 
	variable inter_chprimm8 :  STD_LOGIC_VECTOR (7 downto 0);	  
	variable R_IS_ST, L_IS_ST: Boolean;		
	variable inter_MULL, inter_MULR: STD_LOGIC_VECTOR (5 downto 0);		
	variable inter_we_RF_L, inter_we_RF_R, inter_we_RF_M : STD_LOGIC;
	variable inter_Rd_L, inter_Rd_R, inter_Rd_M : STD_LOGIC_VECTOR (4 downto 0);
	variable inter_data_L, inter_data_R, inter_data_M : STD_LOGIC_VECTOR (63 downto 0);
	
	begin																													
		--==============================================================================
		--Temporary Data Initialization
		--==============================================================================
		IR_ALU_inst_L := IR_Instr_type_L(8);
		IR_CMP_inst_L := IR_Instr_type_L(7);
		IR_CHPR_inst_L := IR_Instr_type_L(6);	 
		IR_JMP_inst_L := IR_Instr_type_L(5);
		IR_JMPreg_inst_L := IR_Instr_type_L(4);
		IR_MUL_inst_L := IR_Instr_type_L(3);
		IR_LD_inst_L := IR_Instr_type_L(2);
		IR_LDI_inst_L := IR_Instr_type_L(1);
		IR_ST_inst_L := IR_Instr_type_L(0);	 
		IR_ALU_inst_R := IR_Instr_type_R(8);
		IR_CMP_inst_R := IR_Instr_type_R(7);
		IR_CHPR_inst_R := IR_Instr_type_R(6);	 
		IR_JMP_inst_R := IR_Instr_type_R(5);
		IR_JMPreg_inst_R := IR_Instr_type_R(4);
		IR_MUL_inst_R := IR_Instr_type_R(3);
		IR_LD_inst_R := IR_Instr_type_R(2);
		IR_LDI_inst_R := IR_Instr_type_R(1);		
		IR_ST_inst_R := IR_Instr_type_R(0);
		--	  
		DRE_ALU_inst_L := DRE_Instr_type_L(8);
		DRE_CMP_inst_L := DRE_Instr_type_L(7);
		DRE_CHPR_inst_L := DRE_Instr_type_L(6);	 
		DRE_JMP_inst_L := DRE_Instr_type_L(5);
		DRE_JMPreg_inst_L := DRE_Instr_type_L(4);
		DRE_MUL_inst_L := DRE_Instr_type_L(3);
		DRE_LD_inst_L := DRE_Instr_type_L(2);
		DRE_LDI_inst_L := DRE_Instr_type_L(1);
		DRE_ST_inst_L := DRE_Instr_type_L(0);	 
		DRE_ALU_inst_R := DRE_Instr_type_R(8);
		DRE_CMP_inst_R := DRE_Instr_type_R(7);
		DRE_CHPR_inst_R := DRE_Instr_type_R(6);	 
		DRE_JMP_inst_R := DRE_Instr_type_R(5);
		DRE_JMPreg_inst_R := DRE_Instr_type_R(4);
		DRE_MUL_inst_R := DRE_Instr_type_R(3);
		DRE_LD_inst_R := DRE_Instr_type_R(2);
		DRE_LDI_inst_R := DRE_Instr_type_R(1);
		DRE_ST_inst_R := DRE_Instr_type_R(0);	   
		--
		EDF_ALU_inst_L := EDF_Instr_type_L(8);
		EDF_CMP_inst_L := EDF_Instr_type_L(7);
		EDF_CHPR_inst_L := EDF_Instr_type_L(6);	 
		EDF_JMP_inst_L := EDF_Instr_type_L(5);
		EDF_JMPreg_inst_L := EDF_Instr_type_L(4);
		EDF_MUL_inst_L := EDF_Instr_type_L(3);
		EDF_LD_inst_L := EDF_Instr_type_L(2);
		EDF_LDI_inst_L := EDF_Instr_type_L(1);
		EDF_ST_inst_L := EDF_Instr_type_L(0);	 
		EDF_ALU_inst_R := EDF_Instr_type_R(8);
		EDF_CMP_inst_R := EDF_Instr_type_R(7);
		EDF_CHPR_inst_R := EDF_Instr_type_R(6);	 
		EDF_JMP_inst_R := EDF_Instr_type_R(5);
		EDF_JMPreg_inst_R := EDF_Instr_type_R(4);
		EDF_MUL_inst_R := EDF_Instr_type_R(3);
		EDF_LD_inst_R := EDF_Instr_type_R(2);
		EDF_LDI_inst_R := EDF_Instr_type_R(1);
		EDF_ST_inst_R := EDF_Instr_type_R(0);	
		--
		DFW_ALU_inst_L := DFW_Instr_type_L(8);
		DFW_CMP_inst_L := DFW_Instr_type_L(7);
		DFW_CHPR_inst_L := DFW_Instr_type_L(6);	 
		DFW_JMP_inst_L := DFW_Instr_type_L(5);
		DFW_JMPreg_inst_L := DFW_Instr_type_L(4);
		DFW_MUL_inst_L := DFW_Instr_type_L(3);
		DFW_LD_inst_L := DFW_Instr_type_L(2);
		DFW_LDI_inst_L := DFW_Instr_type_L(1);
		DFW_ST_inst_L := DFW_Instr_type_L(0);	 
		DFW_ALU_inst_R := DFW_Instr_type_R(8);
		DFW_CMP_inst_R := DFW_Instr_type_R(7);
		DFW_CHPR_inst_R := DFW_Instr_type_R(6);	 
		DFW_JMP_inst_R := DFW_Instr_type_R(5);
		DFW_JMPreg_inst_R := DFW_Instr_type_R(4);
		DFW_MUL_inst_R := DFW_Instr_type_R(3);
		DFW_LD_inst_R := DFW_Instr_type_R(2);
		DFW_LDI_inst_R := DFW_Instr_type_R(1);
		DFW_ST_inst_R := DFW_Instr_type_R(0);
		--==============================================================================
		--variable calculation and assigning
		--==============================================================================
		-- DRELT_IRLS
		if (DRE_Opcode_L="001100" or (DRE_banksel=IR_banksel and (DRE_wr_pred_addr1_L=IR_pred_L or DRE_wr_pred_addr2_L=IR_pred_L))) and DRE_valid_L="1" then
			DRELT_IRLS := true;
		else
			DRELT_IRLS := false;
		end if;	 
		-- DRERT_IRLS
		if ((DRE_banksel=IR_banksel and (DRE_wr_pred_addr1_R=IR_pred_L or DRE_wr_pred_addr2_R=IR_pred_L)) 
			or DRE_Opcode_R="001100") and DRE_valid_R="1" then
			DRERT_IRLS := true;
		else
			DRERT_IRLS := false;
		end if;	 																									  
		-- DRELT_DRERS
		if ((DRE_banksel=DRE_banksel and (DRE_wr_pred_addr1_L=DRE_pred_R or DRE_wr_pred_addr2_L=DRE_pred_R))
			or DRE_Opcode_L="001100") and DRE_valid_L="1" then
			DRELT_DRERS := true;
		else
			DRELT_DRERS := false;
		end if;	 	  
		-- EDFLT_IRLS
		if ((EDF_banksel=IR_banksel and (EDF_wr_pred_addr1_L=IR_pred_L or EDF_wr_pred_addr2_L=IR_pred_L) )
			or EDF_Opcode_L="001100") and EDF_valid_L="1" then
			EDFLT_IRLS := true;
		else
			EDFLT_IRLS := false;
		end if;	
		-- EDFRT_IRLS
		if ((EDF_banksel=IR_banksel and (EDF_wr_pred_addr1_R=IR_pred_L or EDF_wr_pred_addr2_R=IR_pred_L) )
			or EDF_Opcode_R="001100") and EDF_valid_R="1" then
			EDFRT_IRLS := true;
		else
			EDFRT_IRLS := false;
		end if;	
		-- DFWLT_IRLS
		if ((DFW_banksel=IR_banksel and (DFW_wr_pred_addr1_L=IR_pred_L or DFW_wr_pred_addr2_L=IR_pred_L))
			or DFW_Opcode_L="001100") and DFW_valid_L="1" then
			DFWLT_IRLS := true;
		else
			DFWLT_IRLS := false;
		end if;				   
		-- DFWRT_IRLS
		if ((DFW_banksel=IR_banksel and (DFW_wr_pred_addr1_R=IR_pred_L or DFW_wr_pred_addr2_R=IR_pred_L)) 
			or DFW_Opcode_R="001100") and DFW_valid_R="1" then
			DFWRT_IRLS := true;
		else
			DFWRT_IRLS := false;
		end if;
		--==============================================================================
		-- DRELT_IRRS
		if ((DRE_banksel=IR_banksel and (DRE_wr_pred_addr1_L=IR_pred_R or DRE_wr_pred_addr2_L=IR_pred_R)) 
			or DRE_Opcode_L="001100") and DRE_valid_L="1" then
			DRELT_IRRS := true;
		else
			DRELT_IRRS := false;
		end if;	 
		-- DRERT_IRRS
		if ((DRE_banksel=IR_banksel and (DRE_wr_pred_addr1_R=IR_pred_R or DRE_wr_pred_addr2_R=IR_pred_R)) 
			or DRE_Opcode_R="001100") and DRE_valid_R="1" then
			DRERT_IRRS := true;
		else
			DRERT_IRRS := false;
		end if;	 																									  
		-- IRLT_IRRS
		if (IR_banksel=IR_banksel and (IR_wr_pred_addr1_L=IR_pred_R or IR_wr_pred_addr2_L=IR_pred_R) )
			or IR_Opcode_L="001100" then
			IRLT_IRRS := true;
		else
			IRLT_IRRS := false;
		end if;	 	  
		-- EDFLT_IRRS
		if ((EDF_banksel=IR_banksel and (EDF_wr_pred_addr1_L=IR_pred_R or EDF_wr_pred_addr2_L=IR_pred_R)) 
			or EDF_Opcode_L="001100") and EDF_valid_L="1" then
			EDFLT_IRRS := true;
		else
			EDFLT_IRRS := false;
		end if;	
		-- EDFRT_IRRS
		if ((EDF_banksel=IR_banksel and (EDF_wr_pred_addr1_R=IR_pred_R or EDF_wr_pred_addr2_R=IR_pred_R)) 
			or EDF_Opcode_R="001100") and EDF_valid_R="1" then
			EDFRT_IRRS := true;
		else
			EDFRT_IRRS := false;
		end if;	
		-- DFWLT_IRRS
		if ((DFW_banksel=IR_banksel and (DFW_wr_pred_addr1_L=IR_pred_R or DFW_wr_pred_addr2_L=IR_pred_R)) 
			or DFW_Opcode_L="001100") and DFW_valid_L="1" then
			DFWLT_IRRS := true;
		else
			DFWLT_IRRS := false;
		end if;				   
		-- DFWRT_IRRS
		if ((DFW_banksel=IR_banksel and (DFW_wr_pred_addr1_R=IR_pred_R or DFW_wr_pred_addr2_R=IR_pred_R)) 
			or DFW_Opcode_R="001100") and DFW_valid_R="1" then
			DFWRT_IRRS := true;
		else
			DFWRT_IRRS := false;
		end if;		
		--=============================================================================================
		-- IRL_IS_CMP
		if IR_Opcode_L="001000" or IR_Opcode_L="001001"	or IR_Opcode_L="001010"	or IR_Opcode_L="001100"	then
			IRL_IS_CMP := true;
		else
			IRL_IS_CMP := false;
		end if;	
		-- DREL_IS_CMP
		if DRE_Opcode_L="001000" or DRE_Opcode_L="001001"	or DRE_Opcode_L="001010" or DRE_Opcode_L="001100"	then
			DREL_IS_CMP := true;
		else
			DREL_IS_CMP := false;
		end if;
		-- DRER_IS_CMP
		if DRE_Opcode_R="001000" or DRE_Opcode_R="001001"	or DRE_Opcode_R="001010" or DRE_Opcode_R="001100"	then
			DRER_IS_CMP := true;
		else
			DRER_IS_CMP := false;
		end if;	
		-- EDFL_IS_CMP
		if EDF_Opcode_L="001000" or EDF_Opcode_L="001001"	or EDF_Opcode_L="001010" or EDF_Opcode_L="001100"	then
			EDFL_IS_CMP := true;
		else
			EDFL_IS_CMP := false;
		end if;	   
		-- EDFR_IS_CMP
		if EDF_Opcode_R="001000" or EDF_Opcode_R="001001"	or EDF_Opcode_R="001010" or EDF_Opcode_R="001100"	then
			EDFR_IS_CMP := true;
		else
			EDFR_IS_CMP := false;
		end if;	   
		-- DFWL_IS_CMP
		if DFW_Opcode_L="001000" or DFW_Opcode_L="001001"	or DFW_Opcode_L="001010" or DFW_Opcode_L="001100"	then
			DFWL_IS_CMP := true;
		else
			DFWL_IS_CMP := false;
		end if;	   
		-- DFWR_IS_CMP
		if DFW_Opcode_R="001000" or DFW_Opcode_R="001001"	or DFW_Opcode_R="001010" or DFW_Opcode_R="001100"	then
			DFWR_IS_CMP := true;
		else
			DFWR_IS_CMP := false;
		end if;	   
		--============================================================================================================
		-- IFDRLT_IFDRRS1, IFDRLT_IFDRRS2, DRELT_IDFRRS1, DRELT_IDFRRS2, EDFLT_IDFRRS1, EDFLT_IDFRRS2, 
		--	 DRERT_IDFRRS1, DRERT_IDFRRS2, EDFRT_IDFRRS1, EDFRT_IDFRRS2 : Boolean;
		-- DRELT_IDFRLS1, DRELT_IDFRLS2, EDFLT_IDFRLS1, EDFLT_IDFRLS2, 
		--	 DRERT_IDFRLS1, DRERT_IDFRLS2, EDFRT_IDFRLS1, EDFRT_IDFRLS2 : Boolean;									  
		-- IFDRLT_IFDRRS1
		if (IR_Rd_L /= "00000" and IR_Rd_L = IR_Rs1_R) or (IR_Rd_M_L /= "00000" and IR_Rd_M_L = IR_Rs1_R) then
			IFDRLT_IFDRRS1 := true;
		else
			IFDRLT_IFDRRS1 := false;
		end if;
		-- IFDRLT_IFDRRS2
		if (IR_Rd_L /= "00000" and IR_Rd_L = IR_Rs2_R) or (IR_Rd_M_L /= "00000" and IR_Rd_M_L = IR_Rs2_R) then
			IFDRLT_IFDRRS2 := true;
		else
			IFDRLT_IFDRRS2 := false;
		end if;			  
		-- DRELT_IFDRRS1
		if (DRE_Rd_L /= "00000" and DRE_Rd_L = IR_Rs1_R) or (DRE_Rd_M_L /= "00000" and DRE_Rd_M_L = IR_Rs1_R) then
			DRELT_IFDRRS1 := true;
		else
			DRELT_IFDRRS1 := false;
		end if;	
		-- DRELT_IFDRRS2
		if (DRE_Rd_L /= "00000" and DRE_Rd_L = IR_Rs2_R) or (DRE_Rd_M_L /= "00000" and DRE_Rd_M_L = IR_Rs2_R) then
			DRELT_IFDRRS2 := true;
		else
			DRELT_IFDRRS2 := false;
		end if;			 
		-- EDFLT_IFDRRS1
		if (EDF_Rd_L /= "00000" and EDF_Rd_L = IR_Rs1_R) or (EDF_Rd_M_L /= "00000" and EDF_Rd_M_L = IR_Rs1_R) then
			EDFLT_IFDRRS1 := true;
		else
			EDFLT_IFDRRS1 := false;
		end if;
		-- EDFLT_IFDRRS2
		if (EDF_Rd_L /= "00000" and EDF_Rd_L = IR_Rs2_R) or (EDF_Rd_M_L /= "00000" and EDF_Rd_M_L = IR_Rs2_R) then
			EDFLT_IFDRRS2 := true;
		else
			EDFLT_IFDRRS2 := false;
		end if;				
		-- DRERT_IFDRRS1
		if (DRE_Rd_R /= "00000" and DRE_Rd_R = IR_Rs1_R) or (DRE_Rd_M_R /= "00000" and DRE_Rd_M_R = IR_Rs1_R) then
			DRERT_IFDRRS1 := true;
		else
			DRERT_IFDRRS1 := false;
		end if;	
		-- DRERT_IFDRRS2
		if (DRE_Rd_R /= "00000" and DRE_Rd_R = IR_Rs2_R) or (DRE_Rd_M_R /= "00000" and DRE_Rd_M_R = IR_Rs2_R) then
			DRERT_IFDRRS2 := true;
		else
			DRERT_IFDRRS2 := false;
		end if;			 
		-- EDFRT_IFDRRS1
		if (EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs1_R) or (EDF_Rd_M_R /= "00000" and EDF_Rd_M_R = IR_Rs1_R) then
			EDFRT_IFDRRS1 := true;
		else
			EDFRT_IFDRRS1 := false;
		end if;
		-- EDFRT_IFDRRS2
		if (EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs2_R) or (EDF_Rd_M_R /= "00000" and EDF_Rd_M_R = IR_Rs2_R) then
			EDFRT_IFDRRS2 := true;
		else
			EDFRT_IFDRRS2 := false;
		end if;
		-- DRELT_IFDRLS1
		if (DRE_Rd_L /= "00000" and DRE_Rd_L = IR_Rs1_L) or (DRE_Rd_M_L /= "00000" and DRE_Rd_M_L = IR_Rs1_L) then
			DRELT_IFDRLS1 := true;
		else
			DRELT_IFDRLS1 := false;
		end if;	
		-- DRELT_IFDRLS2
		if (DRE_Rd_L /= "00000" and DRE_Rd_L = IR_Rs2_L) or (DRE_Rd_M_L /= "00000" and DRE_Rd_M_L = IR_Rs2_L) then
			DRELT_IFDRLS2 := true;
		else
			DRELT_IFDRLS2 := false;
		end if;			 
		-- EDFLT_IFDRLS1
		if (EDF_Rd_L /= "00000" and EDF_Rd_L = IR_Rs1_L) or (EDF_Rd_M_L /= "00000" and EDF_Rd_M_L = IR_Rs1_L) then
			EDFLT_IFDRLS1 := true;
		else
			EDFLT_IFDRLS1 := false;
		end if;
		-- EDFLT_IFDRLS2
		if (EDF_Rd_L /= "00000" and EDF_Rd_L = IR_Rs2_L) or (EDF_Rd_M_L /= "00000" and EDF_Rd_M_L = IR_Rs2_L) then
			EDFLT_IFDRLS2 := true;
		else
			EDFLT_IFDRLS2 := false;
		end if;				  
		-- DRERT_IFDRLS1
		if (DRE_Rd_R /= "00000" and DRE_Rd_R = IR_Rs1_L) or (DRE_Rd_M_R /= "00000" and DRE_Rd_M_R = IR_Rs1_L) then
			DRERT_IFDRLS1 := true;
		else
			DRERT_IFDRLS1 := false;
		end if;	
		-- DRERT_IFDRLS2
		if (DRE_Rd_R /= "00000" and DRE_Rd_R = IR_Rs2_L) or (DRE_Rd_M_R /= "00000" and DRE_Rd_M_R = IR_Rs2_L) then
			DRERT_IFDRLS2 := true;
		else
			DRERT_IFDRLS2 := false;
		end if;			 
		-- EDFRT_IFDRLS1
		if (EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs1_L) or (EDF_Rd_M_R /= "00000" and EDF_Rd_M_R = IR_Rs1_L) then
			EDFRT_IFDRLS1 := true;
		else
			EDFRT_IFDRLS1 := false;
		end if;
		-- EDFRT_IFDRLS2
		if (EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs2_L) or (EDF_Rd_M_R /= "00000" and EDF_Rd_M_R = IR_Rs2_L) then
			EDFRT_IFDRLS2 := true;
		else
			EDFRT_IFDRLS2 := false;
		end if;			   
		-- DFWLT_IFDRLS1
		if (DFW_Rd_L /= "00000" and DFW_Rd_L = IR_Rs1_L) or (DFW_Rd_M_L /= "00000" and DFW_Rd_M_L = IR_Rs1_L) then
			DFWLT_IFDRLS1 := true;
		else
			DFWLT_IFDRLS1 := false;
		end if;
		-- DFWLT_IFDRLS2
		if (DFW_Rd_L /= "00000" and DFW_Rd_L = IR_Rs2_L) or (DFW_Rd_M_L /= "00000" and DFW_Rd_M_L = IR_Rs2_L) then
			DFWLT_IFDRLS2 := true;
		else
			DFWLT_IFDRLS2 := false;
		end if;	 
		-- DFWRT_IFDRLS1
		if (DFW_Rd_R /= "00000" and DFW_Rd_R = IR_Rs1_L) or (DFW_Rd_M_R /= "00000" and DFW_Rd_M_R = IR_Rs1_L) then
			DFWRT_IFDRLS1 := true;
		else
			DFWRT_IFDRLS1 := false;
		end if;
		-- DFWRT_IFDRLS2
		if (DFW_Rd_R /= "00000" and DFW_Rd_R = IR_Rs2_L) or (DFW_Rd_M_R /= "00000" and DFW_Rd_M_R = IR_Rs2_L) then
			DFWRT_IFDRLS2 := true;
		else
			DFWRT_IFDRLS2 := false;
		end if;	
		-- DFWLT_IFDRRS1
		if (DFW_Rd_L /= "00000" and DFW_Rd_L = IR_Rs1_R) or (DFW_Rd_M_L /= "00000" and DFW_Rd_M_L = IR_Rs1_R) then
			DFWLT_IFDRRS1 := true;
		else
			DFWLT_IFDRRS1 := false;
		end if;
		-- DFWLT_IFDRRS2
		if (DFW_Rd_L /= "00000" and DFW_Rd_L = IR_Rs2_R) or (DFW_Rd_M_L /= "00000" and DFW_Rd_M_L = IR_Rs2_R) then
			DFWLT_IFDRRS2 := true;
		else
			DFWLT_IFDRRS2 := false;
		end if;	 
		-- DFWRT_IFDRRS1
		if (DFW_Rd_R /= "00000" and DFW_Rd_R = IR_Rs1_R) or (DFW_Rd_M_R /= "00000" and DFW_Rd_M_R = IR_Rs1_R) then
			DFWRT_IFDRRS1 := true;
		else
			DFWRT_IFDRRS1 := false;
		end if;
		-- DFWRT_IFDRRS2
		if (DFW_Rd_R /= "00000" and DFW_Rd_R = IR_Rs2_R) or (DFW_Rd_M_R /= "00000" and DFW_Rd_M_R = IR_Rs2_R) then
			DFWRT_IFDRRS2 := true;
		else
			DFWRT_IFDRRS2 := false;
		end if;	  
		
		--============================================================================================================
		-- ALU/SHF/MUL output selection	 MUX
		--============================================================================================================
		-- left way MUX	
		if DRE_Opcode_L="110001" or (DFW_Opcode_L="110001" and DFW_valid_L="1") then --MUL
			ALUout_L := MUL_L;
		else				 -- 25-2A, 32,33
			if DRE_Opcode_L="100101" or DRE_Opcode_L="100110" or DRE_Opcode_L="100111" or DRE_Opcode_L="101000"	or
				DRE_Opcode_L="101001" or DRE_Opcode_L="101010" or DRE_Opcode_L="110010"	or DRE_Opcode_L="110011" then
				ALUout_L := SHF_L;
			else
				ALUout_L := ALU_L;
			end if;
		end if;	   
		
		-- right way MUX	
		if DRE_Opcode_R="110001" or (DFW_Opcode_R="110001" and DFW_valid_R="1") then --MUL
			ALUout_R := MUL_R;
		else				 -- 25-2A, 32,33
			if DRE_Opcode_R="100101" or DRE_Opcode_R="100110" or DRE_Opcode_R="100111" or DRE_Opcode_R="101000"	or
				DRE_Opcode_R="101001" or DRE_Opcode_R="101010" or DRE_Opcode_R="110010"	or DRE_Opcode_R="110011" then
				ALUout_R := SHF_R;
			else
				ALUout_R := ALU_R;
			end if;
		end if;
		
		--============================================================================================================
		-- MUL pipeline set
		--============================================================================================================
		if DFW_Opcode_L="110001" and DFW_valid_L="1" then --MUL
			inter_MULL(0) :='1';
			inter_MULL(5 downto 1) := DFW_Rd_L;
		else
			inter_MULL := "000000";
		end if;		  
		if DFW_Opcode_R="110001" and DFW_valid_R="1" then --MUL
			inter_MULR(0) :='1';
			inter_MULR(5 downto 1) := DFW_Rd_R;
		else
			inter_MULR := "000000";
		end if;		  
		
		--============================================================================================================
		-- CMP result judgement caluculation
		-- CMP result from L way
		case DRE_Opcode_L is
			when "001000" | "001001" => --- CMP or CMPi
			case DRE_imm_L(3 downto 0) is
				when "0000" => -- eq
				if to_integer(signed(ALUout_L))=0 then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;	   
				when "0001" => -- neq
				if to_integer(signed(ALUout_L)) /= 0 then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;	   
				when "0010" => --lower than signed
				if to_integer(signed(ALUout_L)) < 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;	
				when "0011" => --lower or equal than signed	
				if to_integer(signed(ALUout_L)) <= 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;											   
				when "0100" => --greater than signed
				if to_integer(signed(ALUout_L)) > 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;	  
				when "0101" => --greater or euqal than signed
				if to_integer(signed(ALUout_L)) >= 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;							  
				when "0110" => --lower than unsigned
				if to_integer(signed(ALUout_L)) < 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;										
				when "0111" => --lower or equal than unsigned
				if to_integer(signed(ALUout_L)) <= 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;										
				when "1000" => --greater than unsigned
				if to_integer(signed(ALUout_L)) > 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;							   
				when "1001" => --greater or equal than unsigned
				if to_integer(signed(ALUout_L)) >= 0	then
					CMP_resu_L := '1';
				else
					CMP_resu_L := '0';
				end if;								
				when others =>		
					CMP_resu_L := '0';
				assert (false) -- assert always
               		report "Invalid CMP type specification!"
                	severity WARNING;					  
			end case;	
			when "001010" => -- testbit	  
			CMP_resu_L := '0';
			assert (false) -- assert always
				report "Testbit is not supported upto now!"
				severity WARNING;
			when "001100" => -- changepr.load
			CMP_resu_L := '0';
			when others => 	  
			CMP_resu_L := '0';
			assert (false) -- assert always
				report "Non CMP instructions!"
                severity WARNING;	
		end case;		
	-- CMP result from R way	
		case DRE_Opcode_R is
			when "001000" | "001001" => --- CMP or CMPi
			case DRE_imm_R(3 downto 0) is
				when "0000" => -- eq
				if to_integer(signed(ALUout_R))=0 then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;	   
				when "0001" => -- neq
				if to_integer(signed(ALUout_R)) /= 0 then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;	   
				when "0010" => --lower than signed
				if to_integer(signed(ALUout_R)) < 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;	
				when "0011" => --lower or equal than signed	
				if to_integer(signed(ALUout_R)) <= 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;											   
				when "0100" => --greater than signed
				if to_integer(signed(ALUout_R)) > 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;	  
				when "0101" => --greater or euqal than signed
				if to_integer(signed(ALUout_R)) >= 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;							  
				when "0110" => --lower than unsigned
				if to_integer(signed(ALUout_R)) < 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;										
				when "0111" => --lower or equal than unsigned
				if to_integer(signed(ALUout_R)) <= 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;										
				when "1000" => --greater than unsigned
				if to_integer(signed(ALUout_R)) > 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;							   
				when "1001" => --greater or equal than unsigned
				if to_integer(signed(ALUout_R)) >= 0	then
					CMP_resu_R := '1';
				else
					CMP_resu_R := '0';
				end if;								
				when others =>		
					CMP_resu_R := '0';
				assert (false) -- assert always
               		report "Invalid CMP type specification!"
                	severity WARNING;					  
			end case;	
			when "001010" => -- testbit	  
			CMP_resu_R := '0';
			assert (false) -- assert always
				report "Testbit is not supported upto now!"
				severity WARNING;
			when "001100" => -- changepr.load
			CMP_resu_R := '0';
			when others => 	  
			CMP_resu_R := '0';
			assert (false) -- assert always
				report "Non CMP instructions!"
                severity WARNING;	
		end case;
		--======================================================================================
		--inter_valid value calculation
		--======================================================================================
		-- for MUX1
		if DRELT_DRERS and DREL_IS_CMP and DRE_unknown='1' then
			if DRE_Opcode_L="001100" then --changpr.load
				tmpimm8 := DRE_imm_L(17 downto 10);
				if tmpimm8(to_integer(unsigned(DRE_pred_R)))='1' then
					inter_EvalidR := true;
				else
					inter_EvalidR := false;
				end if;
			else
				if CMP_resu_L='1' then 
					if DRE_wr_pred_addr1_L=DRE_pred_R then
						inter_EvalidR := true;
					else
						inter_EvalidR := false;
					end if;
				else	   
					if DRE_wr_pred_addr1_L=DRE_pred_R then
						inter_EvalidR := false;	
					else
						inter_EvalidR := true;
					end if;
				end if;
			end if;		
		else
			if DRE_valid_R="1" then
				inter_EvalidR := true;
			else
				inter_EvalidR := false;
			end if;
		end if;	 
		-- for MUX2
		if IR_pred_L = "000" then
			inter_DRvalidL := true;
		else
			if DRER_IS_CMP=true and DRERT_IRLS=true and DRE_unknown='0' and DRE_valid_R="1" then
				if DRE_Opcode_R="001100" then  -- changepr.load
					tmpimm8 := DRE_imm_R(17 downto 10);
					if tmpimm8(to_integer(unsigned(IR_pred_L)))='1' then
						inter_DRvalidL := true;
					else
						inter_DRvalidL := false;
					end if;
				else  
					if CMP_resu_R='1' then	 
						if DRE_wr_pred_addr1_R=IR_pred_L then
							inter_DRvalidL := true;
						else
							inter_DRvalidL := false;
						end if;
					else	   
						if DRE_wr_pred_addr1_R=IR_pred_L then
							inter_DRvalidL := false;
						else
							inter_DRvalidL := true;
						end if;
					end if;
				end if;
			else 																					   
				if DREL_IS_CMP=true and DRER_IS_CMP=true and DRELT_DRERS=true and DRERT_IRLS and	 --
					(not(DRE_unknown='0' and DRE_valid_R="0")) and inter_EvalidR = true then
				--	if DRE_Opcode_L="001100" and DRE_Opcode_R="001100" then -- changepr.load   --old code
					if DRE_Opcode_R="001100" then -- changepr.load
						tmpimm8 := DRE_imm_R(17 downto 10);
						if tmpimm8(to_integer(unsigned(IR_pred_L)))='1' then
							inter_DRvalidL := true;
						else
							inter_DRvalidL := false;
						end if; 
					else
				--		if DRE_Opcode_L="001100" and DRE_Opcode_R /= "001100" then
				--			tmpimm8 := DRE_imm_L(17 downto 10);
				--			if tmpimm8(to_integer(unsigned(IR_pred_L)))='1' and CMP_resu_R='1' then
				--				inter_DRvalidL := true;
				--			else
				--				inter_DRvalidL := false;
				--			end if;
				--		else
				--			if DRE_Opcode_L /= "001100" and DRE_Opcode_R="001100" then
				--				tmpimm8 := DRE_imm_R(17 downto 10);
				--				if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'and CMP_resu_L='1' then 
				--					inter_DRvalidL := true;
				--				else
				--					inter_DRvalidL := false;
				--				end if;
				--			else
				--				if CMP_resu_L='1' and CMP_resu_R='1' then 
								if CMP_resu_R='1' then
									--inter_DRvalidL := true;
									if DRE_wr_pred_addr1_R=IR_pred_L then
										inter_DRvalidL := true;
									else
										inter_DRvalidL := false;
									end if;
								else  
									if DRE_wr_pred_addr1_R=IR_pred_L then
										inter_DRvalidL := false;
									else
										inter_DRvalidL := true;
									end if;
									--inter_DRvalidL := false;
								end if;	
				--			end if;	
				--		end if;
					end if;
				else  
					if DREL_IS_CMP and DRELT_IRLS then
						if DRE_Opcode_L = "001100" then
							tmpimm8 := DRE_imm_L(17 downto 10);
							if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'then 
								inter_DRvalidL := true;
							else
								inter_DRvalidL := false;
							end if;										   
						else
							if CMP_resu_L='1' then	  
								if DRE_wr_pred_addr1_L=IR_pred_L then
									inter_DRvalidL := true;
								else
									inter_DRvalidL := false;
								end if;
							else 
								if DRE_wr_pred_addr1_L=IR_pred_L then
									inter_DRvalidL := false;
								else
									inter_DRvalidL := true;
								end if;
							end if;
						end if;
					else
						if EDFR_IS_CMP and EDFRT_IRLS then
							if EDF_Opcode_R = "001100" then
								tmpimm8 := EDF_imm_R(17 downto 10);
								if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'then 
									inter_DRvalidL := true;
								else
									inter_DRvalidL := false;
								end if;										   
							else
								if EDF_pred_d_R='1' then  
									if EDF_wr_pred_addr1_R=IR_pred_L then
										inter_DRvalidL := true;
									else
										inter_DRvalidL := false;
									end if;
								else	   
									if EDF_wr_pred_addr1_R=IR_pred_L then
										inter_DRvalidL := false;
									else
										inter_DRvalidL := true;
									end if;
								end if;
							end if;
						else
							if EDFL_IS_CMP and EDFLT_IRLS then
								if EDF_Opcode_L = "001100" then
									tmpimm8 := EDF_imm_L(17 downto 10);
									if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'then 
										inter_DRvalidL := true;
									else
										inter_DRvalidL := false;
									end if;										   
								else
									if EDF_pred_d_L='1' then  
										if EDF_wr_pred_addr1_L=IR_pred_L then
											inter_DRvalidL := true;
										else
											inter_DRvalidL := false;
										end if;
									else
										if EDF_wr_pred_addr1_L=IR_pred_L then
											inter_DRvalidL := false;
										else
											inter_DRvalidL := true;
										end if;
									end if;
								end if;
							else
								if DFWR_IS_CMP and DFWRT_IRLS then
									if DFW_Opcode_R = "001100" then
										tmpimm8 := DFW_imm_R(17 downto 10);
										if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'then 
											inter_DRvalidL := true;
										else
											inter_DRvalidL := false;
										end if;										   
									else
										if DFW_pred_d_R='1' then   
											if DFW_wr_pred_addr1_R=IR_pred_L then
												inter_DRvalidL := true;
											else
												inter_DRvalidL := false;
											end if;
										else		
											if DFW_wr_pred_addr1_R=IR_pred_L then
												inter_DRvalidL := false;
											else
												inter_DRvalidL := true;
											end if;
										end if;
									end if;
								else
									if DFWL_IS_CMP and DFWLT_IRLS then
										if DFW_Opcode_R = "001100" then
											tmpimm8 := DFW_imm_L(17 downto 10);
											if tmpimm8(to_integer(unsigned(IR_pred_L)))='1'then 
												inter_DRvalidL := true;
											else
												inter_DRvalidL := false;
											end if;										   
										else
											if DFW_pred_d_L='1' then 
												if DFW_wr_pred_addr1_L=IR_pred_L then
													inter_DRvalidL := true;
												else
													inter_DRvalidL := false;
												end if;
											else   
												if DFW_wr_pred_addr1_L=IR_pred_L then
													inter_DRvalidL := false;
												else
													inter_DRvalidL := true;
												end if;
											end if;
										end if;
									else
										if IR_pred_d_L='1' then
											inter_DRvalidL := true;
										else
											inter_DRvalidL := false;
										end if;
									end if;
								end if;
							end if;
						end if;	
					end if;
				end if;				   
			end if;
		end if;		
		-- below need modifications!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
		-- For MUX3	
		if IR_pred_R = "000" then
			inter_DRvalidR := true;
			inter_DRunknown:= false;
		else
			if IRL_IS_CMP and IRLT_IRRS and inter_DRvalidL=true then
				inter_DRunknown := true;
				inter_DRvalidR  := true;
			else						
				if DRER_IS_CMP=true and DRERT_IRRS=true and DRE_unknown='0' and DRE_valid_R="1" then
				if DRE_Opcode_R="001100" then  -- changepr.load
					tmpimm8 := DRE_imm_R(17 downto 10);
					if tmpimm8(to_integer(unsigned(IR_pred_R)))='1' then
						inter_DRvalidR := true;
					else
						inter_DRvalidR := false;
					end if;
				else  
					if CMP_resu_R='1' then	
						if DRE_wr_pred_addr1_R=IR_pred_R then
							inter_DRvalidR := true;
						else
							inter_DRvalidR := false;
						end if;
					else	   
						if DRE_wr_pred_addr1_R=IR_pred_R then
							inter_DRvalidR := false;
						else
							inter_DRvalidR := true;
						end if;
					end if;
				end if;
			else 
				if DREL_IS_CMP=true and DRER_IS_CMP=true and DRELT_DRERS=true and DRERT_IRRS and
					(not(DRE_unknown='0' and DRE_valid_R="0")) and inter_EvalidR = true then
				--	if DRE_Opcode_L="001100" and DRE_Opcode_R="001100" then -- changepr.load	  
					if DRE_Opcode_R="001100" then -- changepr.load
						tmpimm8 := DRE_imm_R(17 downto 10);
						if tmpimm8(to_integer(unsigned(IR_pred_R)))='1' then
							inter_DRvalidR := true;
						else
							inter_DRvalidR := false;
						end if; 
					else
				--		if DRE_Opcode_L="001100" and DRE_Opcode_R /= "001100" then
				--			tmpimm8 := DRE_imm_L(17 downto 10);
				--			if tmpimm8(to_integer(unsigned(IR_pred_R)))='1' and CMP_resu_R='1' then
				--				inter_DRvalidR := true;
				--			else
				--				inter_DRvalidR := false;
				--			end if;
				--		else
				--			if DRE_Opcode_L /= "001100" and DRE_Opcode_R="001100" then
				--				tmpimm8 := DRE_imm_R(17 downto 10);
				--				if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'and CMP_resu_L='1' then 
				--					inter_DRvalidR := true;
				--				else
				--					inter_DRvalidR := false;
				--				end if;
				--			else
								if CMP_resu_R='1' then	 
									if DRE_wr_pred_addr1_R=IR_pred_R then
										inter_DRvalidR := true;			 
									else
										inter_DRvalidR := false;
									end if;
								else	   
									if DRE_wr_pred_addr1_R=IR_pred_R then
										inter_DRvalidR := false;
									else
										inter_DRvalidR := true;
									end if;
								end if;	
				--			end if;	
				--		end if;
					end if;
				else
					if DREL_IS_CMP and DRELT_IRRS then
						if DRE_Opcode_L = "001100" then
							tmpimm8 := DRE_imm_L(17 downto 10);
							if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'then 
								inter_DRvalidR := true;
							else
								inter_DRvalidR := false;
							end if;										   
						else
							if CMP_resu_L='1' then	  
								if DRE_wr_pred_addr1_L=IR_pred_R then
									inter_DRvalidR := true;
								else
									inter_DRvalidR := false;
								end if;
							else	   
								if DRE_wr_pred_addr1_L=IR_pred_R then
									inter_DRvalidR := false;
								else
									inter_DRvalidR := true;
								end if;
							end if;
						end if;
					else
						if EDFR_IS_CMP and EDFRT_IRRS then
							if EDF_Opcode_R = "001100" then
								tmpimm8 := EDF_imm_R(17 downto 10);
								if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'then 
									inter_DRvalidR := true;
								else
									inter_DRvalidR := false;
								end if;										   
							else
								if EDF_pred_d_R='1' then  
									if EDF_wr_pred_addr1_R=IR_pred_R then
										inter_DRvalidR := true;
									else
										inter_DRvalidR := false;
									end if;
								else 
									if EDF_wr_pred_addr1_R=IR_pred_R then
										inter_DRvalidR := false;
									else
										inter_DRvalidR := true;
									end if;
								end if;
							end if;
						else
							if EDFL_IS_CMP and EDFLT_IRRS then
								if EDF_Opcode_L = "001100" then
									tmpimm8 := EDF_imm_L(17 downto 10);
									if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'then 
										inter_DRvalidR := true;
									else
										inter_DRvalidR := false;
									end if;										   
								else
									if EDF_pred_d_L='1' then   
										if EDF_wr_pred_addr1_L=IR_pred_R then
											inter_DRvalidR := true;
										else
											inter_DRvalidR := false;
										end if;
									else	   
										if EDF_wr_pred_addr1_L=IR_pred_R then
											inter_DRvalidR := false;
										else
											inter_DRvalidR := true;
										end if;
									end if;
								end if;
							else
								if DFWR_IS_CMP and DFWRT_IRRS then
									if DFW_Opcode_R = "001100" then
										tmpimm8 := DFW_imm_R(17 downto 10);
										if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'then 
											inter_DRvalidR := true;
										else
											inter_DRvalidR := false;
										end if;										   
									else
										if DFW_pred_d_R='1' then	
											if DFW_wr_pred_addr1_R=IR_pred_R then
												inter_DRvalidR := true;
											else
												inter_DRvalidR := false;
											end if;
										else	   
											if DFW_wr_pred_addr1_R=IR_pred_R then
												inter_DRvalidR := false;
											else
												inter_DRvalidR := true;
											end if;
										end if;
									end if;
								else
									if DFWL_IS_CMP and DFWLT_IRRS then
										if DFW_Opcode_R = "001100" then
											tmpimm8 := DFW_imm_L(17 downto 10);
											if tmpimm8(to_integer(unsigned(IR_pred_R)))='1'then 
												inter_DRvalidR := true;
											else
												inter_DRvalidR := false;
											end if;										   
										else
											if DFW_pred_d_L='1' then	
												if DFW_wr_pred_addr1_L=IR_pred_R then
													inter_DRvalidR := true;
												else
													inter_DRvalidR := false;
												end if;
											else		
												if DFW_wr_pred_addr1_L=IR_pred_R then
													inter_DRvalidR := false;
												else
													inter_DRvalidR := true;
												end if;
											end if;
										end if;
									else
										if IR_pred_d_R='1' then
											inter_DRvalidR := true;
										else
											inter_DRvalidR := false;
										end if;
									end if;
								end if;
							end if;
						end if;	
					end if;
				end if;				   
			end if;
			end if;
		end if;
		--=============================================================================================
		--stall calculation
		--=============================================================================================
		--IF/DR_R stall conditions:
		if 	-------------------------IFDR_L: ALU/MUL/LD/LDI/ST.upd   vs.	 IFDR_R: ALU/LD/ST/JMPreg/CMP/CHPR
			(
			 (
			  (
			   (IR_ALU_inst_L or IR_MUL_inst_L or IR_LD_inst_L or IR_LDI_inst_L or IR_ST_inst_L)='1' and 
			   (IR_ALU_inst_R or IR_MUL_inst_R or IR_LD_inst_R or IR_ST_inst_R or IR_CMP_inst_R or IR_JMPreg_inst_R)='1'
			  ) 
			  or 
			  (
			   IR_ST_inst_L='1' and (IR_LD_inst_R or IR_ST_inst_R)='1'
			  )
			 ) 
			 and (inter_DRvalidL and inter_DRvalidR) and (IFDRLT_IFDRRS1 or IFDRLT_IFDRRS2)
			)																		 
			-------------------------or       ST/LD              vs.    LD/ST 
			or 
			  ((
			   (IR_LD_inst_R or IR_ST_inst_L)='1' and (IR_LD_inst_R or IR_ST_inst_R)='1'
			  ) and inter_DRvalidL and inter_DRvalidR)
			
			-----------------------IFDR_L: CMP/CHPR    vs. 	 IFDR_R: JMP/JMPreg/CHPR
			or
			(
			 (
			  (IR_CMP_inst_L or IR_CHPR_inst_L)='1' and (IR_JMP_inst_R or IR_JMPreg_inst_R or IR_CHPR_inst_R)='1'
			 )
			 and inter_DRvalidL and IRLT_IRRS --(IFDRLT_IFDRRS1 or IFDRLT_IFDRRS2)
			)			  
			-----------------------IFDR_L: CHPR       vs.   IFDR_R: any instructions
			or
			(IR_CHPR_inst_L='1' and inter_DRvalidL and inter_DRvalidR)
			-----------------------DRE_L : LD/MUL     vs.   IFDR_R: ALU/LD/ST/JMPreg/MUL/CMP
			----------------------- or     CMP/CHPR   vs.   CHPR       
			or
			(
			 (
			  (
			   ((DRE_LD_inst_L='1' and (DRE_Rd_M_L = IR_Rs1_R or DRE_Rd_M_L = IR_Rs2_R))or DRE_MUL_inst_L='1') and 
			   (IR_ALU_inst_R or IR_MUL_inst_R or IR_LD_inst_R or IR_ST_inst_R or IR_CMP_inst_R or IR_JMPreg_inst_R)='1'
			  )	and (DRE_valid_L="1" and inter_DRvalidR and (DRELT_IFDRRS1 or DRELT_IFDRRS2)))
			 or
			  ((DRE_CMP_inst_L or DRE_CHPR_inst_L)='1' and IR_CHPR_inst_R='1'
			  and DRELT_IRRS and DRE_valid_L="1" and inter_DRvalidR )
			)
			----------------------DRE_R : LD/MUL   vs.  IFDR_R: ALU/LD/ST/JMPreg/CMP/MUL
			or
			(
			 (
			  ((DRE_LD_inst_R='1' and (DRE_Rd_M_R = IR_Rs1_R or DRE_Rd_M_R = IR_Rs2_R)) or DRE_MUL_inst_R='1') and 
			  (IR_ALU_inst_R or IR_MUL_inst_R or IR_LD_inst_R or IR_ST_inst_R or IR_CMP_inst_R or IR_JMPreg_inst_R)='1'
			 )
			 and 
			 ( 
			  (DRE_valid_R="1" and DRE_unknown='0' and inter_DRvalidR and (DRERT_IFDRRS1 or DRERT_IFDRRS2)) 
			 or (DRE_valid_R="1" and DRE_unknown='1' and inter_DRvalidR and (DRERT_IFDRRS1 or DRERT_IFDRRS2) and inter_EvalidR)
			 )
			) 
			----------------------DRE_R : CMP/CHPR  vs. IFDR_R: CHPR
			or 
			(
			 ((DRE_CMP_inst_R or DRE_CHPR_inst_R)='1' and IR_CHPR_inst_R='1') and
			 (
			  (
			   (DRE_valid_R="1" and DRE_unknown='0' and inter_DRvalidR and DRERT_IRRS) 
			 or (DRE_valid_R="1" and DRE_unknown='1' and inter_DRvalidR and DRERT_IRRS and inter_EvalidR)
			  )
			 )
			)																		  
			---------------------EDF_L : MUL       vs. IFDR_R: ALU/LD/ST/JMPreg/CMP/MUL	   !!! ST should not be stalled!!!
			or 
			(
			 (EDF_MUL_inst_L='1' and 
			 (IR_ALU_inst_R or IR_MUL_inst_R or IR_LD_inst_R or IR_CMP_inst_R or IR_JMPreg_inst_R)='1')
			 and EDF_valid_L="1" and inter_DRvalidR and (EDFLT_IFDRRS1 or EDFLT_IFDRRS2)
			)	
			---------------------EDF_L: MUL       vs  IFDR_R: ST
			or 
			(EDF_MUL_inst_L='1' and IR_ST_inst_R='1' and EDF_valid_L="1" and inter_DRvalidR and EDFLT_IFDRRS1)
			---------------------EDF_R: MUL       vs. IFDR_R: any instructions with regfile writing
			or					 
			(EDF_MUL_inst_R='1' and	EDF_valid_R="1" and inter_DRvalidR and IR_we_RF_R="1")
			---------------------EDF_R: MUL       vs. IFDR_R: ALU/LD/ST/JMPreg/CMP/MUL	  !!! ST should not be stalled!!!
			or 
			( 
			 (EDF_MUL_inst_R='1' and 
			 (IR_ALU_inst_R or IR_MUL_inst_R or IR_LD_inst_R or IR_CMP_inst_R or IR_JMPreg_inst_R)='1')
			 and EDF_valid_R="1" and inter_DRvalidR and (EDFRT_IFDRRS1 or EDFRT_IFDRRS2)
			)
			--------------------EDF_R: MUL        vs. IFDR_R: ST
			or 
			(EDF_MUL_inst_R='1' and	EDF_valid_R="1" and inter_DRvalidR and EDFRT_IFDRRS1 and IR_ST_inst_R='1')
			then
			inter_stallR := true;
		else
			inter_stallR := false;
		end if;	 
		-- IF/DR_L stall conditions:
		if  -----------------------DRE_L : LD/MUL     vs.   IFDR_L: ALU/LD/ST/JMPreg/MUL/CMP
			----------------------- or     CMP/CHPR   vs.   CHPR       
			(
			 (
			  (
			   ((DRE_LD_inst_L='1' and (DRE_Rd_M_L = IR_Rs1_L or DRE_Rd_M_L = IR_Rs2_L)) or DRE_MUL_inst_L='1') and 
			   (IR_ALU_inst_L or IR_MUL_inst_L or IR_LD_inst_L or IR_ST_inst_L or IR_CMP_inst_L or IR_JMPreg_inst_L)='1'
			  )	and (DRE_valid_L="1" and inter_DRvalidL and (DRELT_IFDRLS1 or DRELT_IFDRLS2)))
			 or
			 (((DRE_CMP_inst_L or DRE_CHPR_inst_L)='1' and IR_CHPR_inst_L='1') 
			 and DRE_valid_L="1" and inter_DRvalidL and	DRELT_IRLS
			 ) 
			)
			----------------------DRE_R : LD/MUL   vs.  IFDR_L: ALU/LD/ST/JMPreg/CMP/MUL
			or
			(
			 (
			  ((DRE_LD_inst_R='1' and (DRE_Rd_M_R = IR_Rs1_L or DRE_Rd_M_R = IR_Rs2_L)) or DRE_MUL_inst_R='1') and 
			  (IR_ALU_inst_L or IR_MUL_inst_L or IR_LD_inst_L or IR_ST_inst_L or IR_CMP_inst_L or IR_JMPreg_inst_L)='1'
			 )
			 and 
			 ( 
			  (DRE_valid_R="1" and DRE_unknown='0' and inter_DRvalidL and (DRERT_IFDRLS1 or DRERT_IFDRLS2)) 
			 or (DRE_valid_R="1" and DRE_unknown='1' and inter_DRvalidL and (DRERT_IFDRLS1 or DRERT_IFDRLS2) and inter_EvalidR)
			 )
			) 
			----------------------DRE_R : CMP/CHPR  vs. IFDR_L: CHPR
			or 
			(
			 ((DRE_CMP_inst_R or DRE_CHPR_inst_R)='1' and IR_CHPR_inst_L='1') and
			 (
			  (
			   (DRE_valid_R="1" and DRE_unknown='0' and inter_DRvalidL and DRERT_IRLS) 
			 or (DRE_valid_R="1" and DRE_unknown='1' and inter_DRvalidL and DRERT_IRLS and inter_EvalidR)
			  )
			 )
			)																		  
			---------------------EDF_L : MUL       vs. IFDR_L: ALU/LD/ST/JMPreg/CMP/MUL		!!!ST should not be stalled!!!
			or 
			(
			 (EDF_MUL_inst_L='1' and 
			 (IR_ALU_inst_L or IR_MUL_inst_L or IR_LD_inst_L or IR_CMP_inst_L or IR_JMPreg_inst_L)='1')
			 and EDF_valid_L="1" and inter_DRvalidL and (EDFLT_IFDRLS1 or EDFLT_IFDRLS2)
			)																				 
			---------------------EDF_L: MUL       vs  IFDR_L: ST
			or 
			(EDF_MUL_inst_L='1' and IR_ST_inst_L='1' and EDF_valid_L="1" and inter_DRvalidL and EDFLT_IFDRLS1)
			---------------------EDF_L: MUL       vs. IFDR_L: any instructions with regfile writing
			or					 
			(EDF_MUL_inst_L='1' and	EDF_valid_L="1" and inter_DRvalidL and IR_we_RF_L="1")
			---------------------EDF_R: MUL       vs. IFDR_L: ALU/LD/ST/JMPreg/CMP/MUL     !!!ST should not be stalled!!!
			or 
			( 
			 (EDF_MUL_inst_R='1' and 
			 (IR_ALU_inst_L or IR_MUL_inst_L or IR_LD_inst_L or IR_CMP_inst_L or IR_JMPreg_inst_L)='1')
			 and EDF_valid_R="1" and inter_DRvalidL and (EDFRT_IFDRLS1 or EDFRT_IFDRLS2)
			)  		
			--------------------EDF_R: MUL        vs. IFDR_L: ST
			or 
			(EDF_MUL_inst_R='1' and	EDF_valid_R="1" and inter_DRvalidL and EDFRT_IFDRLS1 and IR_ST_inst_L='1')
			then
			inter_stallL := true;
		else
			inter_stallL := false;
		end if;	 		
		--==============================================================================================
		-- inter_DRvalidL inter_DRvalidR inter_DRunknown update!
		--==============================================================================================
		if inter_stallL then
			inter_DRvalidL := false;
			inter_DRvalidR := false;
			inter_DRunknown	:= false;
		else
			if inter_stallR then
				inter_DRvalidR := false;
				inter_DRunknown := false;
			end if;
		end if;
		
		--==============================================================================================
		-- JMP control signal calculation
		--==============================================================================================
		-- cancelL calculation
		if ((DRE_JMP_inst_L='1' or DRE_JMPreg_inst_L='1') and DRE_valid_L="1") 
			or ((DRE_JMP_inst_R='1' or DRE_JMPreg_inst_R='1') and DRE_valid_R="1") then
			inter_cancelL := true; 
		else
			inter_cancelL := false;
		end if;
		-- cancelR calculation
		if ((IR_JMP_inst_L='1' or IR_JMPreg_inst_L='1') and inter_DRvalidL) 
			or ((DRE_JMP_inst_L='1' or DRE_JMPreg_inst_L='1') and DRE_valid_L="1") 
			or ((DRE_JMP_inst_R='1' or DRE_JMPreg_inst_R='1') and DRE_valid_R="1") then
			inter_cancelR := true;
		else
			inter_cancelR := false;
		end if;
		-- if cancelL is true, then cancelR is false;
		if inter_cancelL then 
			inter_cancelR := false;
		end if;		 
		--==============================================================================================
		-- inter_DRvalidL inter_DRvalidR inter_DRunknown update again!
		--==============================================================================================
		if inter_cancelL then
			inter_DRvalidL := false;
			inter_DRvalidR := false;
			inter_DRunknown	:= false;
		else
			if inter_cancelR then
				inter_DRvalidR := false;
				inter_DRunknown := false;
			end if;
		end if;
		-- JMP_validL
		if ((IR_JMP_inst_L='1' or IR_JMPreg_inst_L='1') and inter_DRvalidL) then
			inter_JMPvalidL := true;
		else
			inter_JMPvalidL := false;
		end if;
		-- JMP_validR
		if (IR_JMP_inst_R='1' or IR_JMPreg_inst_R='1') and inter_DRvalidR and not(inter_DRunknown) then
			inter_JMPvalidR := true;
		else
			inter_JMPvalidR := false;
		end if;
		if inter_JMPvalidL then
			inter_JMPvalidR := false;
		end if;												 

		--========================================================================================
		--Data forwarding signal calculation
		--========================================================================================
		-- The left way, RS1 MUX, inter_forwL1
		if DRERT_IFDRLS1 and inter_EvalidR then
			inter_forwL1 := ALUout_R;
		else  
			if DRELT_IFDRLS1 and DRE_valid_L="1" then
				inter_forwL1 :=	ALUout_L;	
			else   
				if EDFRT_IFDRLS1 and EDF_valid_R="1" then
					if EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs1_L then
						inter_forwL1 := EDF_data_R;
					else
						inter_forwL1 := Dcacheout;
					end if;
				else   
					if EDFLT_IFDRLS1 and EDF_valid_L="1" then
						if EDF_RD_L /= "00000" and EDF_Rd_L=IR_Rs1_L then
							inter_forwL1 := EDF_data_L;
						else
							inter_forwL1 := Dcacheout;
						end if;
					else  
						if DFWRT_IFDRLS1 and DFW_valid_R="1" then
							if DFW_Rd_R /= "00000" and DFW_Rd_R=IR_Rs1_L then
								if DFW_Opcode_R="110001" then -- MUL
									inter_forwL1 := ALUout_R;
								else
									inter_forwL1 := DFW_data_R;
								end if;
							else
								inter_forwL1 := DFW_cache_R;
							end if;
						else  
							if DFWLT_IFDRLS1 and DFW_valid_L="1" then
								if DFW_Rd_L /= "00000" and DFW_Rd_L=IR_Rs1_L then
									if DFW_Opcode_L="110001" then -- MUL
										inter_forwL1 := ALUout_L;
									else
										inter_forwL1 := DFW_data_L;
									end if;
								else
									inter_forwL1 := DFW_cache_L;
								end if;							   
							else
								if MULEDF_R(0)='1' -- valid bit of MUL instruction
									and MULEDF_R(5 downto 1)=IR_Rs1_L then -- MUL target reg is IR_L source reg1
									inter_forwL1 := EDF_data_R;
								else 
									if MULEDF_L(0)='1' -- valid bit of MUL instruciton
										and MULEDF_L(5 downto 1)=IR_Rs1_L then
										inter_forwL1 := EDF_data_L;
									else 
										if MULDFW_R(0)='1' -- valid bit of MUL instruction
											and MULDFW_R(5 downto 1)=IR_Rs1_L then
											inter_forwL1 := DFW_data_R;	
										else
											if MULDFW_L(0)='1' -- valid bit of MUL instruction
												and MULDFW_L(5 downto 1)=IR_Rs1_L then
												inter_forwL1 := DFW_data_L;
											else
												inter_forwL1 := DR_Rs1_L;
											end if;
										end if;
									end if;
								end if;
							end if;	  
						end if;
					end if;
				end if;
			end if;
		end if;
		
		-- The left way, RS2 MUX, inter_forwL2
		if DRERT_IFDRLS2 and inter_EvalidR then
			inter_forwL2 := ALUout_R;
		else  
			if DRELT_IFDRLS2 and DRE_valid_L="1" then
				inter_forwL2 :=	ALUout_L;	
			else   
				if EDFRT_IFDRLS2 and EDF_valid_R="1" then
					if EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs2_L then
						inter_forwL2 := EDF_data_R;
					else
						inter_forwL2 := Dcacheout;
					end if;
				else   
					if EDFLT_IFDRLS2 and EDF_valid_L="1" then
						if EDF_RD_L /= "00000" and EDF_Rd_L=IR_Rs2_L then
							inter_forwL2 := EDF_data_L;
						else
							inter_forwL2 := Dcacheout;
						end if;
					else  
						if DFWRT_IFDRLS2 and DFW_valid_R="1" then
							if DFW_Rd_R /= "00000" and DFW_Rd_R=IR_Rs2_L then
								if DFW_Opcode_R="110001" then -- MUL
									inter_forwL2 := ALUout_R;
								else
									inter_forwL2 := DFW_data_R;
								end if;
							else
								inter_forwL2 := DFW_cache_R;
							end if;
						else  
							if DFWLT_IFDRLS2 and DFW_valid_L="1" then
								if DFW_Rd_L /= "00000" and DFW_Rd_L=IR_Rs2_L then
									if DFW_Opcode_L="110001" then -- MUL
										inter_forwL2 := ALUout_L;
									else
										inter_forwL2 := DFW_data_L;
									end if;
								else
									inter_forwL2 := DFW_cache_L;
								end if;							   
							else
								if MULEDF_R(0)='1' -- valid bit of MUL instruction
									and MULEDF_R(5 downto 1)=IR_Rs2_L then -- MUL target reg is IR_L source reg1
									inter_forwL2 := EDF_data_R;
								else 
									if MULEDF_L(0)='1' -- valid bit of MUL instruciton
										and MULEDF_L(5 downto 1)=IR_Rs2_L then
										inter_forwL2 := EDF_data_L;
									else 
										if MULDFW_R(0)='1' -- valid bit of MUL instruction
											and MULDFW_R(5 downto 1)=IR_Rs2_L then
											inter_forwL2 := DFW_data_R;	
										else
											if MULDFW_L(0)='1' -- valid bit of MUL instruction
												and MULDFW_L(5 downto 1)=IR_Rs2_L then
												inter_forwL2 := DFW_data_L;
											else
												inter_forwL2 := DR_Rs2_L;
											end if;
										end if;
									end if;
								end if;
							end if;	  
						end if;
					end if;
				end if;
			end if;
		end if;
		
		-- The right way, RS1 MUX, inter_forwR1
		if DRERT_IFDRRS1 and inter_EvalidR then
			inter_forwR1 := ALUout_R;
		else  
			if DRELT_IFDRRS1 and DRE_valid_L="1" then
				inter_forwR1 :=	ALUout_L;	
			else   
				if EDFRT_IFDRRS1 and EDF_valid_R="1" then
					if EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs1_R then
						inter_forwR1 := EDF_data_R;
					else
						inter_forwR1 := Dcacheout;
					end if;
				else   
					if EDFLT_IFDRRS1 and EDF_valid_L="1" then
						if EDF_RD_L /= "00000" and EDF_Rd_L=IR_Rs1_R then
							inter_forwR1 := EDF_data_L;
						else
							inter_forwR1 := Dcacheout;
						end if;
					else  
						if DFWRT_IFDRRS1 and DFW_valid_R="1" then
							if DFW_Rd_R /= "00000" and DFW_Rd_R=IR_Rs1_R then
								if DFW_Opcode_R="110001" then -- MUL
									inter_forwR1 := ALUout_R;
								else
									inter_forwR1 := DFW_data_R;
								end if;
							else
								inter_forwR1 := DFW_cache_R;
							end if;
						else  
							if DFWLT_IFDRRS1 and DFW_valid_L="1" then
								if DFW_Rd_L /= "00000" and DFW_Rd_L=IR_Rs1_R then
									if DFW_Opcode_L="110001" then -- MUL
										inter_forwR1 := ALUout_L;
									else
										inter_forwR1 := DFW_data_L;
									end if;
								else
									inter_forwR1 := DFW_cache_L;
								end if;							   
							else
								if MULEDF_R(0)='1' -- valid bit of MUL instruction
									and MULEDF_R(5 downto 1)=IR_Rs1_R then -- MUL target reg is IR_L source reg1
									inter_forwR1 := EDF_data_R;
								else 
									if MULEDF_L(0)='1' -- valid bit of MUL instruciton
										and MULEDF_L(5 downto 1)=IR_Rs1_R then
										inter_forwR1 := EDF_data_L;
									else 
										if MULDFW_R(0)='1' -- valid bit of MUL instruction
											and MULDFW_R(5 downto 1)=IR_Rs1_R then
											inter_forwR1 := DFW_data_R;	
										else
											if MULDFW_L(0)='1' -- valid bit of MUL instruction
												and MULDFW_L(5 downto 1)=IR_Rs1_R then
												inter_forwR1 := DFW_data_L;
											else
												inter_forwR1 := DR_Rs1_R;
											end if;
										end if;
									end if;
								end if;
							end if;	  
						end if;
					end if;
				end if;
			end if;
		end if;
		
		-- The right way, RS2 MUX, inter_forwR2
		if DRERT_IFDRRS2 and inter_EvalidR then
			inter_forwR2 := ALUout_R;
		else  
			if DRELT_IFDRRS2 and DRE_valid_L="1" then
				inter_forwR2 :=	ALUout_L;	
			else   
				if EDFRT_IFDRRS2 and EDF_valid_R="1" then
					if EDF_Rd_R /= "00000" and EDF_Rd_R = IR_Rs2_R then
						inter_forwR2 := EDF_data_R;
					else
						inter_forwR2 := Dcacheout;
					end if;
				else   
					if EDFLT_IFDRRS2 and EDF_valid_L="1" then
						if EDF_RD_L /= "00000" and EDF_Rd_L=IR_Rs2_R then
							inter_forwR2 := EDF_data_L;
						else
							inter_forwR2 := Dcacheout;
						end if;
					else  
						if DFWRT_IFDRRS2 and DFW_valid_R="1" then
							if DFW_Rd_R /= "00000" and DFW_Rd_R=IR_Rs2_R then
								if DFW_Opcode_R="110001" then -- MUL
									inter_forwR2 := ALUout_R;
								else
									inter_forwR2 := DFW_data_R;
								end if;
							else
								inter_forwR2 := DFW_cache_R;
							end if;
						else  
							if DFWLT_IFDRRS2 and DFW_valid_L="1" then
								if DFW_Rd_L /= "00000" and DFW_Rd_L=IR_Rs2_R then
									if DFW_Opcode_L="110001" then -- MUL
										inter_forwR2 := ALUout_L;
									else
										inter_forwR2 := DFW_data_L;
									end if;
								else
									inter_forwR2 := DFW_cache_L;
								end if;							   
							else
								if MULEDF_R(0)='1' -- valid bit of MUL instruction
									and MULEDF_R(5 downto 1)=IR_Rs2_R then -- MUL target reg is IR_L source reg1
									inter_forwR2 := EDF_data_R;
								else 
									if MULEDF_L(0)='1' -- valid bit of MUL instruciton
										and MULEDF_L(5 downto 1)=IR_Rs2_R then
										inter_forwR2 := EDF_data_L;
									else 
										if MULDFW_R(0)='1' -- valid bit of MUL instruction
											and MULDFW_R(5 downto 1)=IR_Rs2_R then
											inter_forwR2 := DFW_data_R;	
										else
											if MULDFW_L(0)='1' -- valid bit of MUL instruction
												and MULDFW_L(5 downto 1)=IR_Rs2_R then
												inter_forwR2 := DFW_data_L;
											else
												inter_forwR2 := DR_Rs2_R;
											end if;
										end if;
									end if;
								end if;
							end if;	  
						end if;
					end if;
				end if;
			end if;
		end if;					
		-- The left way, RS1 MUX, inter_forwL1, final value
		if IR_Opcode_L="000001" or IR_Opcode_L="000011"	then -- JMP.link or JMPreg.link
			inter_forwL1(31 downto 0) := IR_PC_L;
			inter_forwL1(63 downto 32):= x"00000000";
		else
			inter_forwL1 := inter_forwL1;
		end if;	 
		
		-- The right way, RS1 MUX, inter_forwR1, final value
		if IR_Opcode_R="000001" or IR_Opcode_R="000011"	then -- JMP.link or JMPreg.link
			inter_forwL1(31 downto 0) := IR_PC_R;
			inter_forwL1(63 downto 32):= x"00000000";
		else
			inter_forwR1 := inter_forwR1;
		end if;						   
		
		-- The left way, RS2 MUX, inter_forwL2, final value
		if IR_Opcode_L="000001" or IR_Opcode_L="000011"	then -- JMP.link or JMPreg.link
			inter_forwL2 := "0000000000000000000000000000000000000000000000000000000000000100";		   --number 4
		else
			if  IR_Opcode_L="001000" -- CMP 
			    or IR_Opcode_L="101010" -- SHPR
			    or IR_Opcode_L="110000" -- PALU 
			    or IR_Opcode_L="110001" -- PMUL
			    or IR_Opcode_L="110010" -- PSHF 
			    then
				inter_forwL2 := inter_forwL2;
			else
				inter_forwL2 := IR_imm_L;
			end if;   
		end if;
		
		-- The right way, RS2 MUX, inter_forwR2, final value
		if IR_Opcode_R="000001" or IR_Opcode_R="000011"	then -- JMP.link or JMPreg.link
			inter_forwR2 := "0000000000000000000000000000000000000000000000000000000000000100";		   --number 4
		else
			if  IR_Opcode_R="001000" -- CMP 
			    or IR_Opcode_R="101010" -- SHPR
			    or IR_Opcode_R="110000" -- PALU 
			    or IR_Opcode_R="110001" -- PMUL
			    or IR_Opcode_R="110010" -- PSHF 
			    then
				inter_forwR2 := inter_forwR2;
			else
				inter_forwR2 := IR_imm_R;
			end if;   
		end if;	
		
		-- Data cache address MUX  ### NEED MODIFICATIONS!!! FOR DATA FPRWARDING!!!######
		if  (DRE_Opcode_L = "010000" or DRE_Opcode_L = "010001" or DRE_Opcode_L = "010010" or DRE_Opcode_L = "010011"	or
			DRE_Opcode_L = "010100" or DRE_Opcode_L = "010101" or DRE_Opcode_L = "010110" or DRE_Opcode_L = "010111"	or
			DRE_Opcode_L = "011000" or DRE_Opcode_L = "011001" or DRE_Opcode_L = "011010" or DRE_Opcode_L = "011011"	or
			DRE_Opcode_L = "011100" or DRE_Opcode_L = "011101" or DRE_Opcode_L = "011110" or DRE_Opcode_L = "011111") and 
			DRE_valid_L="1" then -- LD/ST  
			Dcache_address := ALUout_L(31 downto 0);
			if (DRE_Opcode_R = "010000" or DRE_Opcode_R = "010001" or DRE_Opcode_R = "010010" or DRE_Opcode_R = "010011"	or
				DRE_Opcode_R = "010100" or DRE_Opcode_R = "010101" or DRE_Opcode_R = "010110" or DRE_Opcode_R = "010111"	or
				DRE_Opcode_R = "011000" or DRE_Opcode_R = "011001" or DRE_Opcode_R = "011010" or DRE_Opcode_R = "011011"	or
				DRE_Opcode_R = "011100" or DRE_Opcode_R = "011101" or DRE_Opcode_R = "011110" or DRE_Opcode_R = "011111") and 
				inter_EvalidR then -- LD/ST 																 
				assert (false) -- assert always
                	report "LD/ST can not execute in both way in the same cycle!"
                	severity WARNING;											
			end if;
		else
			if (DRE_Opcode_R = "010000" or DRE_Opcode_R = "010001" or DRE_Opcode_R = "010010" or DRE_Opcode_R = "010011"	or
				DRE_Opcode_R = "010100" or DRE_Opcode_R = "010101" or DRE_Opcode_R = "010110" or DRE_Opcode_R = "010111"	or
				DRE_Opcode_R = "011000" or DRE_Opcode_R = "011001" or DRE_Opcode_R = "011010" or DRE_Opcode_R = "011011"	or
				DRE_Opcode_R = "011100" or DRE_Opcode_R = "011101" or DRE_Opcode_R = "011110" or DRE_Opcode_R = "011111") and 
				inter_EvalidR then -- LD/ST 				
				Dcache_address := ALUout_R(31 downto 0);
			else
				Dcache_address := x"00000000";
			end if;
		end if;
			
		-- data forwarding to ST data MUX		
		if ((DRE_Opcode_L = "011000" or DRE_Opcode_L = "011001" or DRE_Opcode_L = "011010" or DRE_Opcode_L = "011011"	or
			DRE_Opcode_L = "011100" or DRE_Opcode_L = "011101" or DRE_Opcode_L = "011110" or DRE_Opcode_L = "011111") and 
			DRE_valid_L="1") then
			L_IS_ST := true;
		end if;
		if 	((DRE_Opcode_R = "011000" or DRE_Opcode_R = "011001" or DRE_Opcode_R = "011010" or DRE_Opcode_R = "011011"	or
			DRE_Opcode_R = "011100" or DRE_Opcode_R = "011101" or DRE_Opcode_R = "011110" or DRE_Opcode_R = "011111") and 
			inter_EvalidR) then
			R_IS_ST := true;
		end if;
		if R_IS_ST and L_IS_ST then
			assert (false) -- assert always
               	report "STs can not execute in both ways in the same cycle!"
               	severity WARNING;	
		end if;
		
		if 	R_IS_ST or L_IS_ST then
			if (R_IS_ST and DRE_Rd_L = DRE_Rs2_R and DRE_we_RF_L="1" and DRE_valid_L="1") then 
				inter_st := ALUout_L;
			else
				if (((R_IS_ST and EDF_Rd_R=DRE_Rs2_R) or (L_IS_ST and EDF_Rd_R=DRE_Rs2_L)) and EDF_we_RF_R="1" and EDF_valid_R="1") then
					inter_st := EDF_data_R;
				else
					if (((R_IS_ST and EDF_Rd_M_R=DRE_Rs2_R) or (L_IS_ST and EDF_Rd_M_R=DRE_Rs2_L)) and EDF_we_RF_M_R="1" and EDF_valid_R="1") then 
						inter_st := Dcacheout;
					else
						if (((R_IS_ST and EDF_Rd_L=DRE_Rs2_R) or (L_IS_ST and EDF_Rd_L=DRE_Rs2_L)) and EDF_we_RF_L="1" and EDF_valid_L="1") then 
							inter_st := EDF_data_L;
						else
							if (((R_IS_ST and EDF_Rd_M_L=DRE_Rs2_R) or (L_IS_ST and EDF_Rd_M_L=DRE_Rs2_L)) and EDF_we_RF_M_L="1" and EDF_valid_L="1") then 
								inter_st := Dcacheout;
							else
								if (((R_IS_ST and DFW_Rd_R=DRE_Rs2_R) or (L_IS_ST and DFW_Rd_R=DRE_Rs2_L)) and DFW_we_RF_R="1" and DFW_valid_R="1") then
									if DFW_Opcode_R="110001" then  --MUL
										inter_st := ALUout_R;
									else
										inter_st := DFW_data_R;
									end if;
								else
									if (((R_IS_ST and DFW_Rd_M_R=DRE_Rs2_R) or (L_IS_ST and DFW_Rd_M_R=DRE_Rs2_L)) and DFW_we_RF_M_R="1" and DFW_valid_R="1") then
										inter_st := DFW_cache_R;
									else
										if (((R_IS_ST and DFW_Rd_L=DRE_Rs2_R) or (L_IS_ST and DFW_Rd_L=DRE_Rs2_L)) and DFW_we_RF_L="1" and DFW_valid_L="1") then
											if DFW_Opcode_L="110001" then  --MUL
												inter_st := ALUout_L;
											else
												inter_st := DFW_data_L;
											end if;					   
										else
											if (((R_IS_ST and DFW_Rd_M_L=DRE_Rs2_R) or (L_IS_ST and DFW_Rd_M_L=DRE_Rs2_L)) and DFW_we_RF_M_L="1" and DFW_valid_L="1") then
												inter_st := DFW_cache_L;
											else
												if MULEDF_R(0)='1' -- valid bit of MUL instruction
													and ((L_IS_ST and MULEDF_R(5 downto 1)=DRE_Rs2_L) or (R_IS_ST and MULEDF_R(5 downto 1)=DRE_Rs2_R)) then 
													inter_st := EDF_data_R;
												else 
													if MULEDF_L(0)='1' -- valid bit of MUL instruction
														and ((L_IS_ST and MULEDF_L(5 downto 1)=DRE_Rs2_L) or (R_IS_ST and MULEDF_L(5 downto 1)=DRE_Rs2_R)) then 
														inter_st := EDF_data_L;	 
													else
														if MULDFW_R(0)='1' -- vaild MUL
															and ((L_IS_ST and MULDFW_R(5 downto 1)=DRE_Rs2_L) or (R_IS_ST and MULDFW_R(5 downto 1)=DRE_Rs2_R)) then
															inter_st := DFW_data_R;
														else
															if MULDFW_L(0)='1' --valid MUL
																and ((L_IS_ST and MULEDF_L(5 downto 1)=DRE_Rs2_L) or (R_IS_ST and MULEDF_L(5 downto 1)=DRE_Rs2_R)) then 
																inter_st := DFW_data_L;
															else  
																if DRE_valid_L ="1" and L_IS_ST then
																	inter_st := DRE_st_L;
																	if inter_EvalidR and R_IS_ST then
																		assert (false) -- assert always
                															report "No two STs can execute in both way in the same cycle!"
                															severity WARNING;	
																	end if;
																else
																	if inter_EvalidR and R_IS_ST then
																		inter_st := DRE_st_R;
																	else
																		inter_st := x"0000000000000000";
																	end if;
																end if;
															end if;
														end if;
													end if;
												end if;
											end if;
										end if;
									end if;
								end if;
							end if;
						end if;
					end if;
				end if;
			end if;
		else  
			inter_st := x"0000000000000000";
		end if;			
		
		--===================================================================================================
		-- JMP disp MUX
		--===================================================================================================
		if inter_JMPvalidL and (IR_Opcode_L="000000" or IR_Opcode_L="000001") then -- JMP
			inter_JMPdisp := IR_imm_L(31 downto 0);
		else
			if inter_JMPvalidL and (IR_Opcode_L="000010" or IR_Opcode_L="000011") then -- JMPreg
				inter_JMPdisp := DR_Rs1_L(31 downto 0);
			else 
				if inter_JMPvalidR and (IR_Opcode_R="000000" or IR_Opcode_R="000001") then -- JMP
					inter_JMPdisp := IR_imm_R(31 downto 0);
				else
					if inter_JMPvalidR and (IR_Opcode_R="000010" or IR_Opcode_R="000011") then -- JMPreg
						inter_JMPdisp := DR_Rs1_L(31 downto 0);
					else
						inter_JMPdisp := "00000000000000000000000000001000";
					end if;
				end if;			
			end if;
		end if;
		
		--=================================================================================================
		--CHPR valid signal	and imm4
		--=================================================================================================
		if (IR_Opcode_L="001011" or IR_Opcode_L="001100") and inter_DRvalidL then
			inter_chprvalid := '1';
			inter_chprimm4  := IR_pred_imm4_L;
		else
			if (IR_Opcode_R="001011" or IR_Opcode_R="001100") and inter_DRvalidR and inter_DRunknown=false then
			inter_chprvalid := '1';
			inter_chprimm4  := IR_pred_imm4_R;
			else
				inter_chprvalid := '0';
				inter_chprimm4  := "0000";
			end if;
		end if;	 
		if (IR_Opcode_L="001100") and inter_DRvalidL then --chpr.load
			inter_chprimm8  := IR_pred_imm8_L;
			inter_pred_we8b := '1';
		else
			if (IR_Opcode_R="001100") and inter_DRvalidR and inter_DRunknown=false then
				inter_chprimm8  := IR_pred_imm8_R;
				inter_pred_we8b := '1';
			else
				inter_chprimm8  := "00000000";
				inter_pred_we8b := '0';
			end if;
		end if;	 
		--=================================================================================================
		--regfile control signal and WAW hazard elimination
		--=================================================================================================
		-- left way
		if DFW_valid_L="1" then					
			if DFW_Opcode_L="110001" then
				inter_we_RF_L :='0' or MULDFW_L(0);
			else
				inter_we_RF_L := DFW_we_RF_L(0);
			end if;
			inter_we_RF_M := DFW_we_RF_M_L(0);	
			inter_Rd_L := DFW_Rd_L;
			inter_data_L := DFW_data_L;
			inter_data_M := DFW_cache_L;
			inter_Rd_M := DFW_Rd_M_L;	
		else
			if MULDFW_L(0)='1' then
				inter_we_RF_L := '1';
				inter_Rd_L := MULDFW_L(5 downto 1);
				inter_data_L := DFW_data_L;
				inter_we_RF_M := '0';
				inter_Rd_M := "00000";
				inter_data_M := x"0000000000000000";
			else
				inter_we_RF_L := '0';
				inter_Rd_L := "00000";
				inter_data_L := x"0000000000000000";
				inter_we_RF_M := '0';
				inter_Rd_M := "00000";
				inter_data_M := x"0000000000000000";
			end if;
		end if;	  
		
		-- right way
		if DFW_valid_R="1" then	   
			if DFW_Opcode_R="110001" then 
				inter_we_RF_R := '0' or MULDFW_R(0);
			else
				inter_we_RF_R := DFW_we_RF_R(0);
			end if;
			inter_we_RF_M := DFW_we_RF_M_R(0);
			inter_Rd_R := DFW_Rd_R;
			inter_data_R := DFW_data_R;
			inter_data_M := DFW_cache_R;
			inter_Rd_M := DFW_Rd_M_R;	
		else
			if MULDFW_R(0)='1' then
				inter_we_RF_R := '1';
				inter_Rd_R := MULDFW_R(5 downto 1);
				inter_data_R := DFW_data_R;
			else
				inter_we_RF_R := '0';
				inter_Rd_R := "00000";
				inter_data_R := x"0000000000000000";
			end if;
		end if;		
		
		--=================================================================================================
		-- WAW hazard elimination
		--=================================================================================================
		if DFW_valid_L="1" and DFW_valid_R="1" then
			if DFW_Rd_L=DFW_Rd_R and DFW_we_RF_L="1" and DFW_we_RF_R="1" then
				inter_data_L := inter_data_R;
				inter_data_R := inter_data_R;
			end if;
			if MULDFW_L(0)='1' or MULDFW_R(0)='1' then
				assert(false)
				report  "MUL instruction should have nullified this instruction!!"
				severity WARNING;
			end if;
		else
			if DFW_valid_L="1" and MULDFW_R(0)='1' and DFW_Rd_L=MULDFW_R(5 downto 1) then
				inter_data_L := inter_data_L;
				inter_data_R := inter_data_L;
			else
				if DFW_valid_R="1" and MULDFW_L(0)='1' and DFW_Rd_R=MULDFW_L(5 downto 1) then
					inter_data_R := inter_data_R;
					inter_data_L := inter_data_R;
				else
					if MULDFW_L(0)='1' and MULDFW_R(0)='1' and MULDFW_L(5 downto 1)=MULDFW_R(5 downto 1) then
						inter_data_L := inter_data_R;
						inter_data_R := inter_data_R;
					end if; 
				end if;
			end if;
		end if;			  
		
	--=============================================================================================================
	-- Data Cache write enable signal   &  predfile write enable signal
	--=============================================================================================================
	if (EDF_valid_L="1" and EDF_we_Dcache_L="1") or (EDF_valid_R="1" and EDF_we_Dcache_R="1") then
		inter_cache_we := '1';
	else
		inter_cache_we := '0';
	end if;								
	
	
			
	--=============================================================================================================
	--output assignment
	--=============================================================================================================

	RF_we_L <= inter_we_RF_L and reset; 
	RF_we_R <= inter_we_RF_R and reset;
	RF_we_M <= inter_we_RF_M and reset;   
	RF_data_L <= inter_data_L;
	RF_data_R <= inter_data_R;
	RF_data_M <= inter_data_M;
	RF_Rd_L	<= inter_Rd_L;
	RF_Rd_R	<= inter_Rd_R;
	RF_Rd_M <= inter_Rd_M;
	
	if inter_DRvalidL then
		DR_valid_L <= '1' and reset;
	else
		DR_valid_L <= '0' and reset;
	end if;	  
	if inter_DRvalidR then
		DR_valid_R <= '1' and reset;
	else
		DR_valid_R <= '0' and reset;
	end if;		  
	if inter_EvalidR then
		E_valid_R <= '1' and reset;
	else
		E_valid_R <= '0' and reset;
	end if;		 
	if inter_DRunknown then
		DR_unknown <= '1' and reset;
	else
		DR_unknown <= '0' and reset;
	end if;
	
	JMP_disp <= inter_JMPdisp; 
	if inter_JMPvalidL then
		JMPvalidL <= '1' and reset;
	else
		JMPvalidL <= '0' and reset;
	end if;		  
	if inter_JMPvalidR then
		JMPvalidR <= '1' and reset;
	else
		JMPvalidR <= '0' and reset;
	end if;
	
	DRMUX1_L <= inter_forwL1; 
	DRMUX2_L <=	inter_forwL2;
	DRMUX1_R <=	inter_forwR1;
	DRMUX2_R <=	inter_forwR2;
	
	E_st_addr <= Dcache_address;
	E_st_data <= inter_st;
	pred_imm8 <= inter_chprimm8;
	pred_we8b <= inter_pred_we8b and reset;
	Dcache_we <= inter_cache_we and reset;
	ALUoutL   <= ALUout_L;
	ALUoutR   <= ALUout_R;
	chpr_valid<= inter_chprvalid and reset;
	chpr_imm4 <= inter_chprimm4;
	CMPresuL  <= CMP_resu_L and reset;
	CMPresuR  <= CMP_resu_R and reset;
	MULpipe_L <= inter_MULL;
	MULpipe_R <= inter_MULR;  
	if inter_stallL then
		stallL <= '1' and reset;  
		inter_stallR := false;
	else
		stallL <= '0'and reset;
	end if;
	if inter_stallR then
		stallR <= '1' and reset;
	else
		stallR <= '0' and reset;
	end if;
	if inter_stallL then
		PCstall<= '1' and reset;
	else
		PCstall<= '0' and reset;
	end if;
	pred_we_L <= DFW_valid_L(0) and DFW_we_pred_L(0) and reset;
	pred_we_R <= DFW_valid_R(0) and DFW_we_pred_R(0) and reset;
	end process	;
  																				 
end Ctrl_unit_bh;
																				   	   