  
-- ### -------------------------------------------------------------- ###
-- #                                                                    #
-- # file       : mips_seq.fsm                                          #
-- # date       : 05 august 1996                                        #
-- # version    : v0.0                                                  #
-- #                                                                    #
-- # origin     : this description has been developed by CAO-VLSI team  #
-- #              at MASI laboratory, University Pierre et Marie Curie  #
-- #              URA CNRS 818, Institut Blaise Pascal                  #
-- #              4 Place Jussieu 75252 Paris Cedex 05 - France         #
-- # E-mail      :      fahim RAHIM_SARWARY                             #
-- #                    cao-vlsi@masi.ibp.fr                            #
-- # descr.     : Finite State Machine desciption of the sequencer      #
-- #              Reset input is coming from the status                 #
-- #                                                                    #
-- #    SOLUTION 3 pour le PORBLEME RFE/JUMP :pas de verification dans  #
-- #                l'etat init 			               #
-- ### -------------------------------------------------------------- ###


entity mips_seq is

-- Declaration de l'interface ( copie par coeur.vst )

  PORT (
  ck            : in BIT;                       -- ck
  frz           : in BIT;                       -- frz
  rqs           : in BIT;                       -- int,rqs,reset
  reset         : in BIT;                       -- status reset register
  resnul        : in BIT;                       -- resnul
  alu_sign      : in BIT;                       --alu_signe
  ir_opcod      : in BIT_VECTOR(18 DOWNTO 0) ;   -- ir_opcod
  vdd           : in BIT;                       -- vdd
  vss           : in BIT;                       -- vss
  scin          : in BIT;                       -- scin
  test          : in BIT;                       -- test
  itrqs         : in BIT;			-- it reqst
  adrs		: in BIT_VECTOR(1 downto 0);     -- adr1 and adr2
  exrqs		: in BIT;			-- exeption reqst
 
  ctlopx        : out bit_vector(8 DOWNTO 0) ;  -- ctlopx
  ctlopy        : out bit_vector(6 DOWNTO 0) ;  -- ctlopy
  ctlalu        : out bit_vector(5  DOWNTO 0) ;  -- ctlalu
  wenable       : out bit_vector(10 DOWNTO 0) ;  -- wenable
  ctlrw         : out bit_vector(4 DOWNTO 0) ;  -- ctlrw
  ctladr        : out bit ;                     -- ctladr
  excp          : out bit_vector(6 downto 0) ;                     -- e_cpu
  scout         : out BIT                       -- scout
  );

end mips_seq;


architecture STATE_MACHINE of mips_seq is

-- Declaration des etats du microsequencer possibles ( un etat pour chaque m-instr )


type ETAT_TYPE is ( init, init_rfe, ico_e, imdu, rfe_e_2, reg1, reg2, imd, lor_e,
		    lori_e, lb1_e, lb2_e, mfc0_e, mtc0_e,  lxori_e, epc1, epc2,
		    ifetch1, ifetch1_e, sr2i_e, cr2i_e, epc2i_e, bar2i_e, i2sr_e,
		    i2cr_e, i2bar_e, i2epc_e, landi_e, land_e, lxor_e, lnor_e, sllv_e,
          slti_e,sltiu_e, sll_e, srl_e, sra_e, srlv_e, srav_e, lui_e, sltu_e, slt_e, 
          beq, bne, blez, bgtz, bltz, bgez, bltzal, bgezal, branch_e, 
          jal, j_e, jalr, jr, jalre, jr_e, rfe_e, syscall_e, mfhi_e, mthi_e, 
          mtlo_e, mflo_e, lw_e,lh_e,lb_e,sw_e,sh_e,sb_e, lw1_e, lh1_e, lw2_e, lh2_e, 
          lbu2_e, lhu2_e, lhad1, lhad0, lbad00, lbad01, lbad10, lbad11,
		    sw1_e, sb1_e, sh1_e, irq, pct, ifetch_e, brk_e, reset0, reset1,
-- ajout des etats arithmetiques
		addiu_e, addi_e, addi1_e, addu_e, sub_e, sub1_e, subu_e, add_e, add1_e );




signal EF, EP:ETAT_TYPE;

	--pragma CURRENT_STATE EP
	--pragma NEXT_STATE EF
	--pragma SCAN_TEST test
	--pragma SCAN_IN scin
	--pragma SCAN_OUT scout
	--pragma CLOCK ck

	-- Declaration des OPCODES des instructions
	constant spec     : bit_vector (5 downto 0) := B"000_000"  ;    --spec
	constant bcond    : bit_vector (5 downto 0) := B"000_001"  ;    --bcond
	constant cop0     : bit_vector (5 downto 0) := B"010_000"  ;    --cop0
	constant j_i      : bit_vector (5 downto 0) := B"000_010"  ;    -- j
	constant jal_i    : bit_vector (5 downto 0) := B"000_011"  ;    -- jal
	constant beq_i    : bit_vector (5 downto 0) := B"000_100"  ;    -- beq
	constant bne_i    : bit_vector (5 downto 0) := B"000_101"  ;    -- bne
	constant blez_i   : bit_vector (5 downto 0) := B"000_110"  ;    -- blez
	constant bgtz_i   : bit_vector (5 downto 0) := B"000_111"  ;    -- bgtz
	constant sll_i    : bit_vector (5 downto 0) := B"000_000"  ;    -- sll
	constant srl_i    : bit_vector (5 downto 0) := B"000_010"  ;    -- srl
	constant sra_i    : bit_vector (5 downto 0) := B"000_011"  ;    -- sra
	constant sllv_i   : bit_vector (5 downto 0) := B"000_100"  ;    -- sllv
	constant srlv_i   : bit_vector (5 downto 0) := B"000_110"  ;    -- srlv
	constant srav_i   : bit_vector (5 downto 0) := B"000_111"  ;    -- srav
	constant and_i    : bit_vector (5 downto 0) := B"100_100"  ;    -- and
	constant or_i     : bit_vector (5 downto 0) := B"100_101"  ;    -- or
	constant xor_i    : bit_vector (5 downto 0) := B"100_110"  ;    -- xor
	constant nor_i    : bit_vector (5 downto 0) := B"100_111"  ;    -- nor
	constant slti_i   : bit_vector (5 downto 0) := B"001_010"  ;    -- slti
	constant sltiu_i  : bit_vector (5 downto 0) := B"001_011"  ;    -- sltiu
	constant andi_i   : bit_vector (5 downto 0) := B"001_100"  ;    -- andi
	constant ori_i    : bit_vector (5 downto 0) := B"001_101"  ;    -- ori
	constant xori_i   : bit_vector (5 downto 0) := B"001_110"  ;    -- xori
	constant lui_i    : bit_vector (5 downto 0) := B"001_111"  ;    -- lui
	constant jr_i     : bit_vector (5 downto 0) := B"001_000"  ;    -- jr
	constant jalr_i   : bit_vector (5 downto 0) := B"001_001"  ;    -- jalr
	constant syscall_i: bit_vector (5 downto 0) := B"001_100"  ;    -- syscall
	constant break_i  : bit_vector (5 downto 0) := B"001_101"  ;    -- break
	constant mfhi_i   : bit_vector (5 downto 0) := B"010_000"  ;    -- mfhi
	constant mthi_i   : bit_vector (5 downto 0) := B"010_001"  ;    -- mthi
	constant mflo_i   : bit_vector (5 downto 0) := B"010_010"  ;    -- mflo
	constant mtlo_i   : bit_vector (5 downto 0) := B"010_011"  ;    -- mtlo
	constant lb_i     : bit_vector (5 downto 0) := B"100_000"  ;    -- lb
	constant lh_i     : bit_vector (5 downto 0) := B"100_001"  ;    -- lh
	constant lw_i     : bit_vector (5 downto 0) := B"100_011"  ;    -- lw
	constant lbu_i    : bit_vector (5 downto 0) := B"100_100"  ;    -- lbu
	constant lhu_i    : bit_vector (5 downto 0) := B"100_101"  ;    -- lhu
	constant slt_i    : bit_vector (5 downto 0) := B"101_010"  ;    -- slt
	constant sltu_i   : bit_vector (5 downto 0) := B"101_011"  ;    -- sltu
	constant sb_i     : bit_vector (5 downto 0) := B"101_000"  ;    -- sb
	constant sh_i     : bit_vector (5 downto 0) := B"101_001"  ;    -- sh
	constant sw_i     : bit_vector (5 downto 0) := B"101_011"  ;    -- sw
	constant sr       : bit_vector (2 downto 0) := B"100"      ;    -- sr
	constant cr       : bit_vector (2 downto 0) := B"101"      ;	-- cr
	constant epc      : bit_vector (2 downto 0) := B"110"      ;	-- epc
	constant bar      : bit_vector (2 downto 0) := B"000"      ;	-- bar
	constant bltz_i   : bit_vector (1 downto 0) := B"00"       ;    -- bltz
	constant bgez_i   : bit_vector (1 downto 0) := B"10"       ;    -- bgez
	constant bltzal_i : bit_vector (1 downto 0) := B"01"       ;    -- bltzal
	constant bgezal_i : bit_vector (1 downto 0) := B"11"       ;    -- bgezal
	

-- ajout des commandes add, addi, sub, addu, addiu, subu
	constant add_i    : bit_vector (5 downto 0) := B"100_000"  ;    -- add
	constant addi_i   : bit_vector (5 downto 0) := B"001_000"  ;    -- addi
	constant addu_i   : bit_vector (5 downto 0) := B"100_001"  ;    -- addu
	constant addiu_i  : bit_vector (5 downto 0) := B"001_001"  ;    -- addiu
	constant sub_i    : bit_vector (5 downto 0) := B"100_010"  ;    -- sub
	constant subu_i   : bit_vector (5 downto 0) := B"100_011"  ;    -- subu




	
	-- Description des operations de l'Alu

	constant a_sum  : bit_vector (5 downto 0) := B"111110" ;
	constant a_sumv : bit_vector (5 downto 0) := B"111110" ;
	constant a_dif  : bit_vector (5 downto 0) := B"111111" ;
	constant a_difv : bit_vector (5 downto 0) := B"111111" ;
	constant a_and  : bit_vector (5 downto 0) := B"110010" ;
	constant a_or   : bit_vector (5 downto 0) := B"110000" ;
	constant a_xor  : bit_vector (5 downto 0) := B"110100" ;
	constant a_nor  : bit_vector (5 downto 0) := B"111000" ;
	constant a_sll  : bit_vector (5 downto 0) := B"100100" ;
	constant a_srl  : bit_vector (5 downto 0) := B"100000" ;
	constant a_sra  : bit_vector (5 downto 0) := B"100010" ;
	constant a_slt  : bit_vector (5 downto 0) := B"001101" ;
	constant a_sltu : bit_vector (5 downto 0) := B"001111" ;

	-- Description de l'operande X

	constant x_rs   : bit_vector (8 downto 0) := B"000000011" ;
	constant x_rt   : bit_vector (8 downto 0) := B"000000010" ;
	constant x_pc   : bit_vector (8 downto 0) := B"000000100" ;
	constant x_ad   : bit_vector (8 downto 0) := B"000000101" ;
	constant x_hi   : bit_vector (8 downto 0) := B"000001000" ;
	constant x_lo   : bit_vector (8 downto 0) := B"000001001" ;
	-- Modif : Inversion des microcodes de x_cr et x_sr
	constant x_cr   : bit_vector (8 downto 0) := B"000010000" ;
	constant x_sr   : bit_vector (8 downto 0) := B"000010001" ;
	constant x_bar  : bit_vector (8 downto 0) := B"000100000" ;
 	constant x_epc  : bit_vector (8 downto 0) := B"000100001" ;
	constant x_c0   : bit_vector (8 downto 0) := B"001000000" ;
	constant x_c1   : bit_vector (8 downto 0) := B"001000001" ;
	constant x_dt   : bit_vector (8 downto 0) := B"010000000" ;
	constant x_ch   : bit_vector (8 downto 0) := B"010000001" ;
        constant x_pc4  : bit_vector (8 downto 0) := B"100000000";

	-- Description de l'operande Y

	constant y_i16  : bit_vector (6 downto 0) := B"0001000" ;
	constant y_i18  : bit_vector (6 downto 0) := B"0000101" ;
	constant y_iu28  : bit_vector (6 downto 0) := B"0000100" ;
	constant y_sham : bit_vector (6 downto 0) := B"0100000" ;
	constant y_dt   : bit_vector (6 downto 0) := B"0000011" ;
	constant y_ad   : bit_vector (6 downto 0) := B"0000010" ;
	constant y_c0   : bit_vector (6 downto 0) := B"0001001" ;
	constant y_c4   : bit_vector (6 downto 0) := B"0010000" ;
	constant y_c16  : bit_vector (6 downto 0) := B"0010001" ;
	constant y_cad  : bit_vector (6 downto 0) := B"0100001" ;
	constant y_c24 : bit_vector (6 downto 0) := B"1000001" ;
	constant y_c8  : bit_vector (6 downto 0) := B"1000000" ;
	
	-- Description du registre destination

	constant r_no   : bit_vector (10 downto 0) := B"00000000000" ;
	constant r_pc   : bit_vector (10 downto 0) := B"01000000000" ;
	constant r_ad   : bit_vector (10 downto 0) := B"00100000000" ;
	constant r_rd   : bit_vector (10 downto 0) := B"10000000001" ;
	constant r_r31  : bit_vector (10 downto 0) := B"10000000010" ;
	constant r_epc  : bit_vector (10 downto 0) := B"00000010000" ;
	constant r_bar  : bit_vector (10 downto 0) := B"00000100000" ;
	constant r_hi   : bit_vector (10 downto 0) := B"00010000000" ;
	constant r_lo   : bit_vector (10 downto 0) := B"00001000000" ;
	constant r_cr   : bit_vector (10 downto 0) := B"00000000101" ;
	constant r_sr   : bit_vector (10 downto 0) := B"00000001000" ;
	constant r_erq  : bit_vector (10 downto 0) := B"00000001110" ;
	constant r_rfe  : bit_vector (10 downto 0) := B"00000001011" ;
        constant r_rt   : bit_vector (10 downto 0) := B"10000000000" ;
        constant r_scan : bit_vector (10 downto 0) := B"01111111101" ;
	
	-- Description des modes d'acces memoire 

	constant m_no    : bit_vector (4 downto 0) := B"00001" ;
	constant m_fetch : bit_vector (4 downto 0) := B"10001" ;
	constant m_rw    : bit_vector (4 downto 0) := B"01001" ;
	constant m_ww    : bit_vector (4 downto 0) := B"00000" ;
	constant m_wh    : bit_vector (4 downto 0) := B"00100" ;
	constant m_wb    : bit_vector (4 downto 0) := B"00010" ;
	constant m_scan  : bit_vector (4 downto 0) := B"11000" ;

	constant o_no    : bit := '1';
	constant o_fetch : bit := '1';
	constant o_rw    : bit := '0';
	constant o_ww    : bit := '0';
	constant o_rb    : bit := '0';
	constant o_wb    : bit := '0';
	constant o_wh    : bit := '0';
	constant o_rh    : bit := '0';

	constant e_sys	 : bit_vector (6 downto 0) := B"0010000";
	constant e_brk	 : bit_vector (6 downto 0) := B"0001000";
	constant e_ri     : bit_vector (6 downto 0) := B"0000010";
	constant e_cpu	 : bit_vector (6 downto 0) := B"0000001";
	constant e_nop	 : bit_vector (6 downto 0) := B"0000000";
	constant e_lw	 : bit_vector (6 downto 0) := B"0010001";
	constant e_lh	 : bit_vector (6 downto 0) := B"0010010";
	constant e_lb	 : bit_vector (6 downto 0) := B"0010100";
	constant e_sw	 : bit_vector (6 downto 0) := B"0011000";
	constant e_sh	 : bit_vector (6 downto 0) := B"0011100";
	constant e_sb	 : bit_vector (6 downto 0) := B"0011110";
	constant e_ifetch : bit_vector (6 downto 0):= B"0011111";
	constant e_ibe : bit_vector (6 downto 0):= B"0100000";
	constant e_dbe : bit_vector (6 downto 0):= B"1000000";
	constant e_ovf : bit_vector (6 downto 0):= B"1111111";
	constant e_clr : bit_vector (6 downto 0):= B"1010101";
 

-- Description de l'automate

begin
process ( EP   , ir_opcod, resnul, frz  , rqs, reset  )
begin

-- FONCTION DE TRANSITION

    if (reset = '1') then
	EF      <= reset0;

    else case EP is

      when reset0 =>
    EF <= reset1;

     when reset1 =>
    EF <= ifetch1;
    
    when init =>
	if frz then EF <= init;
	elsif ir_opcod(18 downto 13) = ori_i then EF <= imdu;            
	elsif ir_opcod(18 downto 13) = andi_i then EF <= imdu;   
	elsif ir_opcod(18 downto 13) = xori_i then EF <= imdu; 
	elsif(ir_opcod(18 downto 13) = spec and ir_opcod(5 downto 0) = or_i) then EF <= reg1;             
	elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = and_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = xor_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = slt_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sltu_i) then EF <= reg1;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sllv_i) then EF <= reg2;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srlv_i) then EF <= reg2;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srav_i) then EF <= reg2;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = nor_i)  then EF <= reg1;                    

-- ajout de l'arithmetique avec registre 
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = add_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = addu_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sub_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = subu_i) then EF <= reg1;
--

elsif (ir_opcod (18 downto 13) = spec and ir_opcod(5 downto 0) = sll_i)           then EF <= sll_e    ;             
elsif (ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srl_i)            then EF <= srl_e    ;             
elsif (ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sra_i)           then EF <= sra_e    ;             


elsif ir_opcod (18 downto 13)= lui_i             then EF <= imd    ;

elsif ir_opcod (18 downto 13) = slti_i           then EF <= imd    ;
elsif ir_opcod (18 downto 13) = sltiu_i          then EF <= imd    ;            

-- ajout de l'arithmetique (immediat)            
elsif ir_opcod (18 downto 13) = addiu_i          then EF <= imd    ;            
elsif ir_opcod (18 downto 13) = addi_i           then EF <= imd    ;            
--


elsif ir_opcod (18 downto 13) = jal_i            then EF <= jal    ;             
elsif ir_opcod (18 downto 13) = j_i              then EF <= j_e      ;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = jalr_i) then EF <= jalre;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = jr_i) then EF <= jr_e;                      
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = syscall_i) then EF <= syscall_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = break_i) then EF <= brk_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mfhi_i) then EF <= mfhi_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mflo_i) then EF <= mflo_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mthi_i) then EF <= mthi_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mtlo_i) then EF <= mtlo_e;
elsif ir_opcod (18 downto 13)= beq_i       then EF <= reg1;
elsif ir_opcod (18 downto 13)= bne_i     then EF <= reg1;
elsif ir_opcod (18 downto 13)=  blez_i  then EF <= blez;
elsif ir_opcod (18 downto 13)=  bgtz_i  then EF <= bgtz;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bltz_i) then EF <= bltz;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bgez_i) then EF <= bgez;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bltzal_i) then EF <= bltzal;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bgezal_i) then EF <= bgezal;          
elsif ir_opcod (18 downto 13)= lb_i             then EF <= lb_e    ; 
elsif ir_opcod (18 downto 13) = lbu_i            then EF <= lb_e    ;
elsif ir_opcod (18 downto 13) = lhu_i            then EF <= lh_e    ;
elsif ir_opcod (18 downto 13) = lh_i             then EF <= lh_e    ;
elsif ir_opcod (18 downto 13) = lw_i             then EF <= lw_e    ;
elsif ir_opcod (18 downto 13) = sh_i             then EF <= sh_e    ;             
elsif ir_opcod (18 downto 13) = sw_i             then EF <= sw_e    ;             
elsif ir_opcod (18 downto 13) = sb_i             then EF <= sb_e    ;
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12)='1') then EF <= rfe_e;
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12 downto 11) = B"00") then EF <= mfc0_e;                  
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12 downto 11) = B"01") then EF <= mtc0_e;
else    EF <= ico_e;             
	
		    end if;
	
--**********************************************************************
when init_rfe =>
 if frz then EF <= init_rfe;
elsif ir_opcod(18 downto 13) = ori_i then EF <= imdu;            
elsif ir_opcod(18 downto 13) = andi_i then EF <= imdu;   
elsif ir_opcod(18 downto 13) = xori_i then EF <= imdu;           
elsif(ir_opcod(18 downto 13) = spec and ir_opcod(5 downto 0) = or_i) then EF <= reg1;             
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = and_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = xor_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = slt_i) then EF <= reg1;            
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sltu_i) then EF <= reg1;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sllv_i) then EF <= reg2;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srlv_i) then EF <= reg2;           
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srav_i) then EF <= reg2;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = nor_i)  then EF <= reg1;                    

-- ajout de l'arithmetique avec registre 
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = add_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = addu_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sub_i) then EF <= reg1;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = subu_i) then EF <= reg1;
--

elsif (ir_opcod (18 downto 13) = spec and ir_opcod(5 downto 0) = sll_i)           then EF <= sll_e    ;             
elsif (ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = srl_i)            then EF <= srl_e    ;             
elsif (ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = sra_i)           then EF <= sra_e    ;             
elsif ir_opcod (18 downto 13)= lui_i             then EF <= imd    ;             
elsif ir_opcod (18 downto 13) = slti_i           then EF <= imd    ;
elsif ir_opcod (18 downto 13) = sltiu_i          then EF <= imd    ;            

-- ajout de l'arithmetique (immediat)            
elsif ir_opcod (18 downto 13) = addiu_i          then EF <= imd    ;            
elsif ir_opcod (18 downto 13) = addi_i           then EF <= imd    ;            
--

elsif ir_opcod (18 downto 13) = jal_i            then EF <= jal    ;             
elsif ir_opcod (18 downto 13) = j_i              then EF <= j_e      ;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = jalr_i) then EF <= jalre;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = jr_i) then EF <= jr_e;                      
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = syscall_i) then EF <= syscall_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = break_i) then EF <= brk_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mfhi_i) then EF <= mfhi_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mflo_i) then EF <= mflo_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mthi_i) then EF <= mthi_e;
elsif(ir_opcod (18 downto 13)= spec and ir_opcod(5 downto 0) = mtlo_i) then EF <= mtlo_e;
elsif ir_opcod (18 downto 13)= beq_i       then EF <= reg1;
elsif ir_opcod (18 downto 13)= bne_i     then EF <= reg1;
elsif ir_opcod (18 downto 13)=  blez_i  then EF <= blez;
elsif ir_opcod (18 downto 13)=  bgtz_i  then EF <= bgtz;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bltz_i) then EF <= bltz;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bgez_i) then EF <= bgez;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bltzal_i) then EF <= bltzal;
elsif (ir_opcod (18 downto 13)= bcond and ir_opcod(7 downto 6) = bgezal_i) then EF <= bgezal;          
elsif ir_opcod (18 downto 13)= lb_i             then EF <= lb_e    ; 
elsif ir_opcod (18 downto 13) = lbu_i            then EF <= lb_e    ;
elsif ir_opcod (18 downto 13) = lhu_i            then EF <= lh_e    ;
elsif ir_opcod (18 downto 13) = lh_i             then EF <= lh_e    ;
elsif ir_opcod (18 downto 13) = lw_i             then EF <= lw_e    ;
elsif ir_opcod (18 downto 13) = sh_i             then EF <= sh_e    ;             
elsif ir_opcod (18 downto 13) = sw_i             then EF <= sw_e    ;             
elsif ir_opcod (18 downto 13) = sb_i             then EF <= sb_e    ;
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12)='1') then EF <= rfe_e;
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12 downto 11) = B"00") then EF <= mfc0_e;                  
elsif (ir_opcod (18 downto 13) = cop0 and ir_opcod(12 downto 11) = B"01") then EF <= mtc0_e;
else    EF <= ico_e;             
	
		    end if;

--**************************************************************************            
		when imdu =>
		   if frz then EF <= imdu;
		   
			elsif ir_opcod(18 downto 13) = ori_i        then EF <= lori_e  ;       
			elsif ir_opcod(18 downto 13) = andi_i       then EF <= landi_e ;       
			elsif ir_opcod(18 downto 13) = xori_i       then EF <= lxori_e ;      

		 	-- Modif sltu_e et non slti_e	
			-- Modif Si on passe par imdu l immediat ne sera pas signe sur 32 bits.
			-- elsif ir_opcod(18 downto 13) = sltiu_i      then EF <= sltu_e ;       
			else EF <= ico_e;
		   end if;
 
-- ***********************************************************************

when reg1 =>
  if frz then EF <= reg1;
   
elsif  (ir_opcod(5 downto 0) = or_i and ir_opcod(18 downto 13) = spec)      then EF <= lor_e  ;       
elsif  (ir_opcod(5 downto 0) = and_i and ir_opcod(18 downto 13) = spec)     then EF <= land_e ;        
elsif  (ir_opcod(5 downto 0) = xor_i and ir_opcod(18 downto 13) =spec)      then EF <= lxor_e ;        
elsif  (ir_opcod(5 downto 0) = slt_i and ir_opcod(18 downto 13) = spec)     then EF <= slt_e  ;       
elsif  (ir_opcod(5 downto 0) = sltu_i and ir_opcod(18 downto 13)= spec)     then EF <= sltu_e ;       
elsif  (ir_opcod(5 downto 0) = nor_i and ir_opcod(18 downto 13) = spec)    then EF <= lnor_e  ;       

--insertion des etats add ...
elsif  (ir_opcod(5 downto 0) = add_i and ir_opcod(18 downto 13) = spec)     then EF <= add_e  ;       
elsif  (ir_opcod(5 downto 0) = addu_i and ir_opcod(18 downto 13) = spec)     then EF <= addu_e  ;       
elsif  (ir_opcod(5 downto 0) = sub_i and ir_opcod(18 downto 13) = spec)     then EF <= sub_e  ;       
elsif  (ir_opcod(5 downto 0) = subu_i and ir_opcod(18 downto 13) = spec)     then EF <= subu_e  ;       
--

elsif  ir_opcod(18 downto 13) = beq_i       then EF <= beq  ;       
elsif  ir_opcod(18 downto 13) = bne_i       then Ef <= bne  ;  
else   EF <= ico_e;     
 
		    end if;


when reg2 =>
  if frz then EF <= reg2;
   
elsif  (ir_opcod(5 downto 0) = sllv_i and ir_opcod(18 downto 13) = spec)    then EF <= sllv_e ;        
elsif  (ir_opcod(5 downto 0) = srlv_i and ir_opcod(18 downto 13) =spec )    then EF <= srlv_e ;        
elsif  (ir_opcod(5 downto 0) = srav_i and ir_opcod(18 downto 13) =spec)     then EF <= srav_e ;        
elsif  ir_opcod(18 downto 13) = beq_i       then EF <= beq  ;       
elsif  ir_opcod(18 downto 13) = bne_i       then Ef <= bne  ;  
else   EF <= ico_e;     
 
		    end if;

-- ***********************************************************************

	
when imd =>
   if frz then EF <= imd;
      
	elsif ir_opcod(18 downto 13) = lui_i        then EF <= lui_e   ; 				
	elsif ir_opcod(18 downto 13) = slti_i          then EF <= slti_e  ;
	elsif ir_opcod(18 downto 13) = sltiu_i      then EF <= sltiu_e ;
-- insertion des immediats add ...
	elsif ir_opcod(18 downto 13) = addiu_i      then EF <= addiu_e ;
	elsif ir_opcod(18 downto 13) = addi_i      then EF <= addi_e ;

	else EF <= ico_e;     
		    end if;

-- ***********************************************************************

		when lor_e =>
		   if frz then EF <= lor_e;
		   
			elsif rqs then 
				  EF <= irq;
				
			
					else EF <= init ;        
		    end if;

-- ***********************************************************************

		when lori_e =>
		   if frz then EF <= lori_e;
		   
		   elsif rqs then 
					 EF <= irq;
				
					else EF <= init ;       
		    end if;

--************************************************************************************
		when land_e =>
		   if frz then EF <= land_e;
		   
		   elsif rqs then 
					 EF <= irq;
				
				
			else EF <= init;
					       
		    end if;

			
--************************************************************************************
		when landi_e =>
		   if frz then EF <= landi_e;
		   
		    elsif	 rqs then 
					 EF <= irq;
				
				
					else EF <= init ;      
		    end if;

			
-- ***********************************************************************
		when lxor_e =>
		    if frz then 
		        EF <= lxor_e;
		    elsif rqs then 
		        EF <= irq;
		    else 
		        EF <= init ;        
		    end if;


-- ***********************************************************************

		when lxori_e =>
		   if frz then EF <= lxori_e;
		   
			elsif rqs then 
					 EF <= irq;
		
			
					else EF <= init ;       
		    end if;


-- ***********************************************************************

		when lnor_e =>
		   if frz then EF <= lnor_e;
		   
			elsif rqs then 
					 EF <= irq;
				
			
					else EF <= init ;        
		    end if;


-- ***********************************************************************
		when sllv_e =>
		   if frz then EF <= sllv_e;
		   
			elsif rqs then 
					 EF <= irq;
				
				
					else EF <= init ;     
		    end if;


-- ***********************************************************************

		when sll_e =>
		   if frz then EF <= sll_e;
		   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init ;       
		    end if;


--*****************************************************************************************************************

		when srl_e =>
		   if frz then EF <= srl_e;
		   
			elsif rqs then 
				 EF <= irq;
				
				
					else EF <= init ;       
		    end if;


--***********************************************************************************************************

		when sra_e =>
		   	if frz then 
				EF <= sra_e;
			elsif rqs then 
				EF <= irq;
			else 
				EF <= init ;      
		    	end if;

--********************************************************************************************************
	when srlv_e =>
		   if frz then EF <= srlv_e;
		   
			elsif rqs then 
					 EF <= irq;
				
			
					else EF <= init ;     
		    end if;


-- ***********************************************************************

		when srav_e =>
		   if frz then EF <= srav_e;
		   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init ;       
		    end if;

-- ***********************************************************************

		when lui_e =>
		   if frz then EF <= lui_e;
		   
			elsif rqs then 
				 EF <= irq;
				
				
					else EF <= init ;      
		    end if;

			
-- ***********************************************************************

	when sltiu_e =>
		   if frz then EF <= sltiu_e;
		   
			elsif rqs then 
				 EF <= irq;
				
		
					else EF <= init ;       
		    end if;

-- ***********************************************************************
-- insertion de l'etat de addiu
	when addiu_e =>
		   if frz then EF <= addiu_e;
		   
			elsif rqs then 
				 EF <= irq;
				
		
					else EF <= init ;       
		    end if;

-- ***********************************************************************
-- insertion des etats de addi
	when addi_e =>
		   if frz then EF <= addi_e;
		   
			  else EF <= addi1_e; 	
		
		    end if;


-- ***********************************************************************
	when addi1_e =>
			if frz then 
				EF <= addi1_e; 
			elsif rqs then 
				EF <= irq; 
			else  	
				EF <= init ;       
			end if;

-- ***********************************************************************
-- insertion de l'etat de addu
	when addu_e =>
		   if frz then EF <= addu_e;
		   
			elsif rqs then 
				 EF <= irq;
				
		
					else EF <= init ; 
		    end if;
      
-- ***********************************************************************
-- insertion des etats de add
	when add_e =>
		   if frz then EF <= add_e;
		   
			  else EF <= add1_e; 	
		
		    end if;


-- ***********************************************************************
	when add1_e =>
			if frz then 
				EF <= add1_e; 
			elsif rqs then 
				EF <= irq; 
			else  	
				EF <= init ;       
			end if;

-- ***********************************************************************
-- insertion de l'etat de subu
	when subu_e =>
		   if frz then EF <= subu_e;
		   
			elsif rqs then 
				 EF <= irq;
				
		
					else EF <= init ; 
		    end if;
      
-- ***********************************************************************
-- insertion des etats de sub
	when sub_e =>
		   if frz then EF <= sub_e;
		   
			  else EF <= sub1_e; 	
		
		    end if;


-- ***********************************************************************
	when sub1_e =>
			if frz then 
				EF <= sub1_e; 
			elsif rqs then 
				EF <= irq; 
			else  	
				EF <= init ;       
			end if;

-- ***********************************************************************
	when sltu_e =>
		   if frz then EF <= sltu_e;
		   
			elsif rqs then 
				 EF <= irq;
				
		
					else EF <= init ;       
		    end if;

			
-- ***********************************************************************

		when slt_e =>
		   if frz then EF <= slt_e;
		   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init ;       
		    end if;

-- ***********************************************************************

		when slti_e =>
		   if frz then EF <= slti_e;
		   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init ;       
		    end if;


-- ***********************************************************************
		when beq =>
		   if frz then EF <= beq;
		   else
			if resnul = '1'  then EF <= branch_e ;       end if; 
			if resnul = '0' then EF <= ifetch_e ;       end if; 
		    end if;


 -- ***********************************************************************

		when bne =>
		   if frz then EF <= bne;
		   else
			if resnul='0' then EF <= branch_e ;       end if; 
			if resnul='1' then EF <= ifetch_e ;       end if; 
		    end if;

-- ***********************************************************************

		when blez =>
		   if frz then EF <= blez;
		   else
			if (resnul = '1' or alu_sign = '1') then  EF <= branch_e  ;  
			else
			 EF <= ifetch_e  ;       end if;
		    
			end if;

-- ***********************************************************************

		when bgtz =>
		   if frz then EF <= bgtz;
		   else
			if (alu_sign = '0' and resnul = '0') then  EF <= branch_e  ; 
			else
			    EF <= ifetch_e  ;       end if;
		    end if;


-- ***********************************************************************

		when bltz =>
			   if frz then EF <= bltz;
		   else
			if (resnul = '0' and alu_sign = '1') then  EF <= branch_e  ; 
			else
			    EF <= ifetch_e  ;  end if;
		    end if;

--**************************************************************************************************************

		when bgez =>
			  if frz then EF <= bgez;
		   else
			if (resnul = '1' or alu_sign = '0') then  EF <= branch_e  ; 
			else
			   EF <= ifetch_e  ; end if;      
		    end if;

--**************************************************************************************************************

		when bltzal =>
		   if frz then EF <= bltzal;
		   else
			EF <= bltz;
		    end if;

			
--**************************************************************************************************************

		when bgezal =>
		   if frz then EF <= bgezal;
		   else
			EF <= bgez;
		    end if;

		
-- *********************************************************************** 
		when branch_e =>
		   if frz then EF <= branch_e;
		   else
			EF <= ifetch_e    ;
		    end if;

			
-- ***********************************************************************

		when jal =>
		   if frz then EF <= jal;
		   else
			EF <= j_e ;
		    end if;

-- ***********************************************************************

		when j_e =>
		   if frz then EF <= j_e;
		   else 
			
			EF <= ifetch_e   ;
		    end if;


-- ***********************************************************************
	when jalre =>
		   if frz then EF <= jalre;
		   else 
				EF <= jalr;
		
		
		    end if;


-- ***********************************************************************

		when jalr =>
		   if frz then EF <= jalr;
		   else
			EF <= jr ;
		    end if;


-- ***********************************************************************
	when jr_e =>
		   	if frz then 
				EF <= jr_e;
		   	else 
				EF <= jr ;
		    	end if;

-- ***********************************************************************
	
		when jr =>
		   if frz then 
		       EF <= jr;
		   elsif rqs then 
		       EF <= irq ;
		   else  
		      EF <= ifetch_e    ;
		   end if;

-- ***********************************************************************


		when rfe_e =>
		   if frz then EF <= rfe_e;
		   elsif rqs then EF <= irq; 
		  else 
 			EF <= rfe_e_2    ;
		    end if;


-- ***********************************************************************

		when rfe_e_2 =>
		   if frz then EF <= rfe_e_2;
		   else
 			EF <= init_rfe    ;
		    end if;


-- ***********************************************************************

		when syscall_e =>
		   	if frz then 
				EF <= syscall_e;
		   	else
				EF <= irq       ;
		    	end if;


-- ***********************************************************************

		when brk_e =>
		   if frz then EF <= brk_e;
		   else
			EF <= irq       ;
		    end if;


-- ***********************************************************************

		when mfhi_e =>
		   if frz then EF <= mfhi_e;
		   else
			EF <= init;
		    end if;

-- ***********************************************************************

		when mthi_e =>
		   if frz then EF <= mthi_e;
		   else
			EF <= init;
		    end if;

-- ***********************************************************************

		when mtlo_e =>
		   if frz then EF <= mtlo_e;
			else 
				EF <= init;
		   end if;


-- ***********************************************************************

		when mflo_e =>
		  if frz then EF <= mflo_e;
		   else
			EF <= init;
		    end if;

-- ***********************************************************************


		when lw1_e =>
		   	if frz then 
				EF <= lw1_e;
		   	else
				EF <= lw2_e ;
		    	end if;


-- ***********************************************************************
		when lw_e =>
		   	if frz then 
				EF <= lw_e;
		   	else
				EF <= lw1_e ;
		    	end if;


-- ***********************************************************************
		when lh1_e =>
			if frz then 
				EF <= lh1_e;
			elsif adrs(1) = '0' then 
				EF <= lhad1;
			else 
				EF <= lhad0 ;
			end if;


-- ***********************************************************************
		when lh_e =>
			if frz then 
				EF <= lh_e;
			else  
				EF <= lh1_e; 
		
			end if;


-- ***********************************************************************
		when lw2_e =>
			if frz then 
				EF <= lw2_e; 
			elsif rqs then 
				EF <= irq; 
			else  	
				EF <= init ;       
			end if;


-- ***********************************************************************
		when lhad1 =>
		   	if frz then 
				EF <= lhad1;
			elsif rqs then 
				EF <= irq;				
			elsif ir_opcod(18 downto 13)= lh_i then  
				EF <= lh2_e ;
     			else  
				EF <= lhu2_e;
		    	end if;

-- ***********************************************************************
		when lhad0 =>
		   	if frz then 
				EF <= lhad0;
			elsif rqs then 
				EF <= irq;				
			elsif ir_opcod(18 downto 13)= lh_i then  
				EF <= lh2_e ;
     			else  
				EF <= lhu2_e;
		    	end if;

-- ***********************************************************************
        	when lh2_e =>
		   if frz then EF <= lh2_e;
		   elsif rqs then EF <= irq;
		   else	EF <= init ;
		    end if;


-- ***********************************************************************

        	when lhu2_e =>
		   if frz then EF <= lhu2_e;
		   elsif rqs then EF <= irq;
		   else
			EF <= init ;
		    end if;


-- ***********************************************************************
	when lb_e =>
	    if frz then
		EF <= lb_e;
	    else 
		EF <= lb1_e;
	    end if;

			
-- ***********************************************************************
	when lb1_e =>
	    if frz then 
		EF <= lb1_e;
	    elsif adrs(1 downto 0) = B"11" then 
		EF <= lbad00 ;
	    elsif adrs( 1 downto 0) = B"10" then 
		EF <= lbad01;
	    elsif adrs( 1 downto 0) = B"01" then 
		EF <= lbad10;
	    else  
		EF <= lbad11; 
	    end if;

-- ***********************************************************************
		when lbad00 =>
		   if frz then 
		   	EF <= lbad00;
		   elsif ir_opcod(18 downto 13) = lb_i  then 
		   	EF <= lb2_e;
		   else  
		   	EF <= lbu2_e;	
		   end if;

-- ***********************************************************************
		when lbad01 =>
		   if frz then EF <= lbad01;
		   elsif
			ir_opcod(18 downto 13) = lb_i  then EF <= lb2_e;
		   else  EF <= lbu2_e;	
			
		    end if;

				 
-- ***********************************************************************
		when lbad10 =>
		   if frz then EF <= lbad10;
		   elsif
			ir_opcod(18 downto 13) = lb_i then EF <= lb2_e;
		   else  EF <= lbu2_e;	
			
		    end if;

-- ***********************************************************************
		when lbad11 =>
		   if frz then EF <= lbad11;
		   elsif
			ir_opcod(18 downto 13) = lb_i then EF <= lb2_e;
		   else  EF <= lbu2_e;	
			
		    end if;

-- ***********************************************************************
		when lbu2_e =>
		   if frz then EF <= lbu2_e;
	           elsif rqs then EF <= irq;
			
		   else  EF <= init;	
			
		    end if;

-- ***********************************************************************
		when lb2_e =>
		   if frz then EF <= lb2_e;
		   elsif  rqs then EF <= irq;
		   
			
		   else  EF <= init;	
			
		    end if;


-- ***********************************************************************

		when sw_e =>
		   if frz then EF <= sw_e;
		   else
			
		     EF <= sw1_e;
		    end if;

-- ***********************************************************************

		when sw1_e =>
		   if frz then EF <= sw1_e;
		   else
			EF <= ifetch_e    ;
		    end if;

-- ***********************************************************************

		when sb_e =>
		   if frz then EF <= sb_e;
		   else
			
		     EF <= sb1_e;
		    end if;
			
-- ***********************************************************************
		when sb1_e =>
		   if frz then EF <= sb1_e;
		   else
			EF <= ifetch_e    ;
		    end if;

-- ***********************************************************************

		when sh_e =>
		   if frz then EF <= sh_e;
		   else
			
		     EF <= sh1_e;
		    end if;

-- ***********************************************************************
		when sh1_e =>
		   if frz then EF <= sh1_e;
		   else
			EF <= ifetch_e    ;
		    end if;

-- ***********************************************************************

		when mfc0_e =>
                   if frz then EF <= mfc0_e;
                  
			elsif ir_opcod(10 downto 8) = sr 	then EF <= sr2i_e	 ;		
			elsif ir_opcod(10 downto 8) = cr 	then EF <= cr2i_e ;		
			elsif ir_opcod(10 downto 8) = epc 	then EF <= epc2i_e ;	
			elsif ir_opcod(10 downto 8) = bar       then EF <= bar2i_e ;   
			else EF <= ico_e;   	
                    end if;

     
-- ***********************************************************************

		when mtc0_e =>
                   if frz then EF <= mtc0_e;
                   
			elsif ir_opcod(10 downto 8) = sr 	then EF <= i2sr_e	 ;		
			elsif ir_opcod(10 downto 8) = cr	then EF <= i2cr_e ;		
			elsif ir_opcod(10 downto 8) = bar 	then EF <= i2bar_e ;	
			elsif ir_opcod(10 downto 8) = epc       then EF <= i2epc_e ;   
			else EF <= ico_e ;   	
                    end if;


-- ***********************************************************************

		when sr2i_e =>
                   if frz then EF <= sr2i_e;
                   
			elsif rqs then 
				 EF <= irq;
				
				
					else EF <= init	;	
                    end if;


-- ***********************************************************************

		when i2sr_e =>
                   	if frz then 
		   		EF <= i2sr_e;
                   
			elsif rqs then 
				EF <= irq;
			else 
				EF <= init;	
                    	end if;

-- ***********************************************************************

		when cr2i_e =>
                   if frz then EF <= cr2i_e;
                   
			elsif rqs then 
			 EF <= irq;
				
				
					else EF <= init	;	
                    end if;


-- ***********************************************************************

		when i2cr_e =>
                   if frz then EF <= i2cr_e;
                   
			elsif rqs then 
					 EF <= irq;
			
				
					else EF <= init	;	
                    end if;


-- ***********************************************************************

		when i2epc_e =>
                   if frz then EF <= i2epc_e;
                   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init	;		
                    end if;


-- ***********************************************************************

		when epc2i_e =>
                   if frz then EF <= epc2i_e;
                   
			elsif rqs then 
				 EF <= irq;
				
			
					else EF <= init	;		
                    end if;


-- ***********************************************************************

		when i2bar_e =>
                   if frz then EF <= i2bar_e;
                   
			elsif rqs then 
				 EF <= irq;
				
				
					else EF <= init	;	
                    end if;
 

-- ***********************************************************************

		when bar2i_e =>
                   if frz then EF <= bar2i_e;
                   
			elsif rqs then 
				 EF <= irq;
			
				
					else EF <= init;	
                    end if;


-- ***********************************************************************



		when ico_e =>
		   if frz then EF <= ico_e;
		   else
			EF <= irq;
		    end if;

			
-- ***********************************************************************

		when irq =>
		   	if frz then 
				EF <= irq;
		      	elsif itrqs = '1'  then 
				EF <= epc1 ;
			else 
				EF <= epc2 ;
		    	end if;

			
-- ***********************************************************************

		when epc1 =>
		   	if frz then 
				EF <= epc1;
		   	else
				EF <= pct ;
		    	end if;

-- ***********************************************************************

		when epc2 =>
		   	if frz then 
				EF <= epc2;
		   	else
				EF <= pct ;
		    	end if;

-- ***********************************************************************

		when pct =>
		   	if frz then 
		   		EF <= pct;
		   	else
				EF <= ifetch1_e ;
		    	end if;


-- ***********************************************************************

		when ifetch_e =>
		   if frz then EF <= ifetch_e;
		   
			elsif rqs then 
				 EF <= irq;
					else EF <= init ;        
		    end if;

-- ***********************************************************************
		when ifetch1_e =>
			if frz then EF <= ifetch1_e;
				else EF<= init ;
			end if;

--*************************************************************************	
		when ifetch1 =>
		   if frz then EF <= ifetch1;
		   else
			 EF <= init ;        
		    end if;
		

	end case;

	end if;                 -- end if of reset = '1'

--FONCTION DE GENERATION

   IF (test ='1') THEN
		excp <= e_nop;
		ctlopx <= x_c0;
		ctlopy <= y_c0;
		ctlalu <= a_sum;
		ctlrw <= m_scan;
		ctladr <= o_no;
		wenable <= r_scan;
   ELSE

   case EP is

     when reset0 =>
               excp    <= e_clr;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_cad  ;
               ctlalu  <= a_sum ;
               wenable <= r_pc ;
               ctlrw   <= m_no  ;
               ctladr  <= o_no   ;
               
     when reset1 =>
               excp    <= e_clr;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0  ;
               ctlalu  <= a_sum ;
               wenable <= r_sr ;
               ctlrw   <= m_no  ;
               ctladr  <= o_no   ;
               
         when init =>
               excp    <= e_ifetch;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c4 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;

         when init_rfe =>
               excp <=e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c4 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;
               
         when imdu =>
               excp    <= e_nop;
               ctlopx  <= x_ch ;
               ctlopy  <= y_i16 ;
               ctlalu  <= a_and ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;
               
         when reg1 =>
               excp    <= e_nop;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;

         when reg2 =>
               excp    <= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;
               
         when imd =>
               excp    <=  e_nop;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_i16 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;
               
         when lor_e =>
               excp    <= e_ibe  ;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_or ;
               if frz='0' then  
                  wenable <= r_rd ;
                  ctlrw   <= m_fetch ;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no ;
                  ctlrw   <= m_no ;
                  ctladr  <= o_no;
               end if;
               
         when lori_e =>
               excp    <= e_ibe  ;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_or ;
               if frz='0' then  
                  wenable <= r_rt ;
                  ctlrw   <= m_fetch ;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no ;
                  ctlrw   <= m_no ;
                  ctladr  <= o_no;
               end if;
               
         when land_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_ad;
               ctlalu  <=  a_and;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when landi_e =>
               excp    <=  e_ibe;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_ad;
               ctlalu  <=  a_and;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lxor_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_xor ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lxori_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_xor ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lnor_e =>
               excp    <= e_ibe ;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_nor ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sllv_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_sll ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sll_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_sham ;
               ctlalu  <= a_sll ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when srl_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_sham ;
               ctlalu  <= a_srl ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sra_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_sham ;
               ctlalu  <= a_sra ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
         when srlv_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_ad ;
               ctlalu  <=  a_srl;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when srav_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_sra ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lui_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_ad;
               ctlopy  <=  y_c16;
               ctlalu  <=  a_sll;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sltiu_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_sltu ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sltu_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_sltu ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when slt_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_slt ;
               if NOT frz then
                  wenable <= r_rd;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when slti_e =>
               excp<= e_ibe;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_slt ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when beq =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_dif;
               wenable <= r_no;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               
         when bne =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_ad ;
               ctlalu  <= a_dif;
               wenable <= r_no;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               
         when blez =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_dif ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when bgtz =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_dif;
               
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when bltz =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_dif;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when bgez =>
               excp<= e_nop;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when bltzal =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_r31;
               else
                  wenable <= r_no;
               end if;
               
         when bgezal =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_r31;
               else
                  wenable <= r_no;
               end if;
               
         when branch_e =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_i18 ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;
               
         when jal =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_r31;
               else
                  wenable <= r_no;
               end if;
               
         when j_e =>
               excp<= e_nop;
               
               ctlopx  <= x_pc4 ;
               ctlopy  <= y_iu28 ;
               ctlalu  <= a_or ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;
               
         when jalre =>
               excp<=  e_ifetch;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when jalr =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_rd;
               else
                  wenable <= r_no;
               end if;
               
         when jr_e =>
               excp<=  e_nop;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when jr =>
               excp<= e_nop;
               ctlopx  <= x_ad;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctladr <= o_no;
               ctlrw <= m_no;
               
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;
               
         when rfe_e =>
               excp<= e_cpu;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               wenable <= r_no;
               if NOT frz then
                  ctladr <= o_fetch;
                  ctlrw  <= m_fetch;
               else
                  ctladr <= o_no;
                  ctlrw  <= m_no;
               end if;
               
         when rfe_e_2 =>
               excp<= e_nop;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw <= m_no;
               ctladr <= o_no;
               if NOT frz then
                  wenable <= r_rfe;
               else
                  wenable <= r_no;
               end if;
               
         when syscall_e =>
               excp<= e_sys;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when brk_e =>
               excp<= e_brk;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when mfhi_e =>
               excp<= e_cpu;
               ctlopx  <= x_hi ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  ctlrw <= m_fetch;
                  ctladr <= o_fetch;
                  wenable <= r_rd;
               else  
                  wenable <= r_no;
                  ctlrw <= m_no;
                  ctladr <= o_no;
               end if;
               
         when mthi_e =>
               excp<= e_cpu;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  ctlrw <= m_fetch;
                  ctladr <= o_fetch;
                  wenable <= r_hi;
               else 
                  wenable <= r_no;
                  ctlrw <= m_no;
                  ctladr <= o_no;
               end if;
               
         when mtlo_e =>
               excp<= e_cpu;
               ctlopx  <= x_rs ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  ctlrw <= m_fetch;
                  ctladr <= o_fetch;
                  wenable <= r_lo;
               else 
                  ctlrw  <= m_no;
                  ctladr <= o_no;
                  wenable <= r_no;
               end if; 
               
         when mflo_e =>
               excp<= e_cpu;
               ctlopx  <= x_lo ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  ctlrw <= m_fetch;
                  ctladr <= o_fetch;
                  wenable <= r_rd;    
               else 
                  wenable <= r_no;
                  ctlrw <= m_no;
                  ctladr <= o_no;
               end if;
               
         when lw1_e =>
               excp<= e_dbe;
               ctlopx  <=  x_c0;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               wenable <= r_no;
               if NOT frz then
                  ctlrw   <= m_rw;
                  ctladr  <= o_rw;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lw_e =>
               excp<= e_lw;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_i16;
               ctlalu  <=  a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if not FRZ then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when lh1_e =>
               excp<=  e_dbe;
               ctlopx  <=  x_c0;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               wenable <= r_no;
               if NOT frz then
                  ctlrw   <= m_rw;
                  ctladr  <= o_rh;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lh_e =>
               excp<=  e_lh;
               ctlopx  <=  x_rs;
               ctlopy  <=  y_i16;
               ctlalu  <=  a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if not FRZ then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when lw2_e =>
               excp<= e_ibe;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_dt ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lhad1 =>
               excp<= e_nop;
               ctlopx  <= x_c0;
               ctlopy  <= y_dt ;
               ctlalu  <= a_sum;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;
               
         when lhad0 =>
               excp<= e_nop;
               ctlopx  <= x_dt;
               ctlopy  <= y_c16 ;
               ctlalu  <= a_sll;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable <= r_no;
               end if;
               
         when lh2_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_ad;
               ctlopy  <=  y_c16;
               ctlalu  <=  a_sra;               
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch;
               else 
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lhu2_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_ad;
               ctlopy  <=  y_c16;
               ctlalu  <=  a_srl;               
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch;
               else 
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lb_e =>
               excp<=  e_lb;
               ctlopx<=  x_rs;
               ctlopy<=  y_i16;
               ctlalu<=  a_sum;
               ctlrw<= m_no;
               ctladr<= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when lb1_e =>
               excp<= e_dbe;
               ctlopx<= x_c0;
               ctlopy<= y_c0;
               ctlalu<= a_sum;
               wenable<= r_no;
               if NOT frz then
                  ctlrw   <= m_rw;
                  ctladr  <= o_rb;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when lbad00 =>
               excp<=  e_nop;
               ctlopx  <=  x_dt;
               ctlopy  <=  y_c24;
               ctlalu  <=  a_sll;
               ctlrw   <=  m_no;
               ctladr   <=  o_no;
               if NOT frz then
                  wenable <= r_ad;               
               else
                  wenable   <= r_no;         
               end if;
               
         when lbad01 =>
               excp<=  e_nop;
               ctlopx  <=  x_dt;
               ctlopy  <=  y_c16;
               ctlalu  <=  a_sll;
               ctlrw   <=  m_no;
               ctladr   <=  o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable   <= r_no;
               end if;
               
         when lbad10 =>
               excp<=  e_nop;
               ctlopx  <=  x_dt;
               ctlopy  <=  y_c8;
               ctlalu  <=  a_sll;
               ctlrw   <=  m_no;
               ctladr   <=  o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable   <= r_no;
               end if;
         when lbad11 =>
               excp<= e_nop;
               ctlopx  <=  x_dt;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               ctlrw   <=  m_no;
               ctladr   <=  o_no;
               if NOT frz then
                  wenable <= r_ad;
               else
                  wenable   <= r_no;
               end if;
               
         when lbu2_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_ad;
               ctlopy  <=  y_c24;
               ctlalu  <=  a_srl;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw  <= m_fetch;
                  ctladr  <= o_no;
               else
                  wenable   <= r_no;
                  ctlrw     <= m_no;
                  ctladr    <= o_no;
               end if;

         when lb2_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_ad;
               ctlopy  <=  y_c24;
               ctlalu  <=  a_sra;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw  <= m_fetch;
                  ctladr  <= o_no;
               else
                  wenable   <= r_no;
                  ctlrw     <= m_no;
                  ctladr    <= o_no;
               end if;
               
         when sw_e =>
               excp<= e_sw;
               ctlopx  <= x_rs ;
               ctlopy  <= y_i16 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               
               end if;
               
         when sw1_e =>
               excp<= e_dbe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               wenable <= r_no;
               if NOT frz then
                  ctlrw   <= m_ww;
                  ctladr  <= o_ww;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sb_e =>
               excp<= e_sb;
               ctlopx  <= x_rs ;
               ctlopy  <= y_i16 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;
               
         when sb1_e =>
               excp<= e_dbe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               wenable <= r_no;
               if NOT frz then
                  ctlrw   <= m_wb;
                  ctladr  <= o_wb;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when sh_e =>
               excp<= e_sh;
               ctlopx  <= x_rs ;
               ctlopy  <= y_i16 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               if NOT frz then 
                  wenable <= r_ad;
               else 
                  wenable <= r_no;
               end if;

         when sh1_e =>
               excp<= e_dbe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0;
               ctlalu  <= a_sum ;
               wenable <= r_no;
               if NOT frz then
                  ctlrw   <= m_wh;
                  ctladr  <= o_wh;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when mfc0_e =>
               excp<= e_cpu;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when mtc0_e =>
               excp<= e_cpu;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when sr2i_e =>
               excp<= e_ibe;
               ctlopx  <= x_sr ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when i2sr_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_sr;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no; 
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when cr2i_e =>
               excp<= e_ibe;
               ctlopx  <= x_cr ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when i2cr_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_cr;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
               
         when i2epc_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_epc;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when epc2i_e =>
               excp<= e_ibe;
               ctlopx  <= x_epc;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
               
         when i2bar_e =>
               excp<= e_ibe;
               ctlopx  <= x_rt ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_bar;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when bar2i_e =>
               excp<=  e_ibe;
               ctlopx  <= x_bar;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               if NOT frz then
                  wenable <= r_rt;
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  wenable <= r_no;
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
	 
	when addiu_e =>
		excp <= e_ibe;
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_sum;
		if NOT frz then
		   wenable <= r_rt;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
                   ctlrw   <= m_no;
                   ctladr  <= o_no;
		end if; 
		             
	when addu_e =>
		excp <= e_ibe;
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_sum;
		if NOT frz then
		   wenable <= r_rd;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
                   ctlrw   <= m_no;
                   ctladr  <= o_no;
		end if; 
		         
        when addi_e =>
		excp <= e_ovf; 
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_sum;

		if NOT frz then
		   wenable <= r_ad;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

	when addi1_e =>
		excp <= e_ibe;
		ctlopx <= x_c0;
		ctlopy <= y_ad;
		ctlalu <= a_sum;
		
		if NOT frz then
		   wenable <= r_rt;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

        when add_e =>
		excp <= e_ovf; 
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_sum;

		if NOT frz then
		   wenable <= r_ad;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

	when add1_e =>
		excp <= e_ibe;
		ctlopx <= x_c0;
		ctlopy <= y_ad;
		ctlalu <= a_sum;
		
		if NOT frz then
		   wenable <= r_rd;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

	when subu_e =>
		excp <= e_ibe;
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_dif;
		if NOT frz then
		   wenable <= r_rd;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
                   ctlrw   <= m_no;
                   ctladr  <= o_no;
		end if; 
		         
        when sub_e =>
		excp <= e_ovf; 
		ctlopx <= x_rs;
		ctlopy <= y_ad;
		ctlalu <= a_dif;

		if NOT frz then
		   wenable <= r_ad;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

	when sub1_e =>
		excp <= e_ibe;
		ctlopx <= x_c0;
		ctlopy <= y_ad;
		ctlalu <= a_sum;
		
		if NOT frz then
		   wenable <= r_rd;
		   ctlrw   <= m_fetch;
		   ctladr  <= o_fetch;
		else
		   wenable <= r_no;
		   ctlrw   <= m_no;
		   ctladr  <= o_no;
		end if;

		



 
        when ico_e =>
               excp<= e_ri;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no ;
               ctladr  <= o_no;
               wenable <= r_no;
               
         when irq =>
               excp <= e_clr;
               ctlopx  <= x_c0 ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no ;
               ctladr  <= o_no;
               if frz='0' then 
                  wenable <= r_erq ;
               else 
                  wenable <=  r_no;
               end if;
               
         when epc1 =>
               excp<= e_nop;
               ctlopx  <= x_pc ;
               ctlopy  <= y_c0 ;
               ctlalu  <= a_sum ;
               ctlrw   <= m_no ;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_epc;
               else
                  wenable <= r_no;
               end if;
               
         when epc2 =>
               excp<= e_nop;
               ctlopx  <=  x_pc;
               ctlopy  <=  y_c4;
               ctlalu  <=  a_dif;
               ctlrw   <= m_no ;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_epc;
               else
                  wenable <= r_no;
               end if;
               
         when pct =>
               excp<= e_nop;
               ctlopx  <=  x_c1;
               ctlopy  <=  y_c0;
               ctlalu  <=  a_sum;
               ctlrw   <= m_no ;
               ctladr  <= o_no;
               if NOT frz then
                  wenable <= r_pc;
               else
                  wenable <= r_no;
               end if;
               
         when ifetch_e =>
               excp<=  e_ibe;
               ctlopx  <=  x_c0;
               ctlopy  <=  y_c0 ;
               ctlalu  <=  a_sum ;
               wenable <= r_no ;
               if NOT frz then
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
               end if;
               
         when ifetch1_e =>
               excp<= e_ibe;
               ctlopx <= x_c0;
               ctlopy <= y_ad;
               ctlalu <= a_sum;
               if NOT frz then 
                  ctlrw <= m_fetch ;
                  ctladr <= o_fetch;
                  wenable <= r_bar ;
               else 
                  ctlrw <= m_no;
                  ctladr <= o_no;
                  wenable <= r_no;
               end if;

         when ifetch1 =>
               excp<=  e_ibe;
               ctlopx  <=  x_c0;
               ctlopy  <=  y_c0 ;
               ctlalu  <=  a_sum ;
               if NOT frz then
                  ctlrw   <= m_fetch;
                  ctladr  <= o_fetch ;
                  wenable <= r_erq ;
               else
                  ctlrw   <= m_no;
                  ctladr  <= o_no;
                  wenable <= r_no;
               end if;
   

   end case;

   END IF;		


	end process;

  process (ck)
  begin

    if (ck = '1' and not ck'stable) then
      EP <= EF;
    end if;

  end process;

end STATE_MACHINE;
