Index: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Stat_List_unit/src/Stat_List_unit_vhdl_body.cpp
===================================================================
--- trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Stat_List_unit/src/Stat_List_unit_vhdl_body.cpp	(revision 81)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Stat_List_unit/src/Stat_List_unit_vhdl_body.cpp	(revision 135)
@@ -24,5 +24,406 @@
   {
     log_printf(FUNC,Stat_List_unit,FUNCTION,"Begin");
-    vhdl->set_body ("");
+
+    uint32_t size_bank        = log2(_param->_nb_bank);
+    uint32_t size_gpr_ptr     = log2(_param->_nb_general_register_by_bank);
+    uint32_t size_spr_ptr     = log2(_param->_nb_special_register_by_bank);
+
+    uint32_t LSB_gpr_num_reg  = 0;
+    uint32_t MSB_gpr_num_reg  = log2(_param->_nb_general_register_by_bank) - 1;
+    uint32_t LSB_gpr_num_bank = MSB_gpr_num_reg+1;
+    uint32_t MSB_gpr_num_bank = _param->_size_general_register -1 ;
+
+    uint32_t LSB_spr_num_reg  = 0;
+    uint32_t MSB_spr_num_reg  = log2(_param->_nb_special_register_by_bank) - 1;
+    uint32_t LSB_spr_num_bank = MSB_spr_num_reg+1;
+    uint32_t MSB_spr_num_bank = _param->_size_special_register -1;
+
+
+    vhdl->set_comment(0,"=====================================================");
+    vhdl->set_comment(0,"=====[ CONSTANT ]====================================");
+    vhdl->set_comment(0,"=====================================================");
+    
+    for (uint32_t j=0; j<_param->_nb_inst_insert; j++)
+    vhdl->set_body (0,"internal_INSERT_"+toString(j)+"_ACK <= '1';");
+
+    for (uint32_t j=0; j<_param->_nb_inst_insert; j++)
+    vhdl->set_body (0,"     out_INSERT_"+toString(j)+"_ACK <= internal_INSERT_"+toString(j)+"_ACK;");
+
+    for (uint32_t j=0; j<_param->_nb_inst_retire; j++)
+    vhdl->set_body (0,"internal_RETIRE_"+toString(j)+"_ACK <= '1';");
+
+    for (uint32_t j=0; j<_param->_nb_inst_retire; j++)
+    vhdl->set_body (0,"     out_RETIRE_"+toString(j)+"_ACK <= internal_RETIRE_"+toString(j)+"_ACK;");
+    
+
+    vhdl->set_body   (0,"");
+    vhdl->set_body   (0,"transition: process (in_CLOCK)");
+
+//     vhdl->set_body   (0,"variable gpr_stat_list_next : Tstat_list_gpr;");
+//     vhdl->set_body   (0,"variable spr_stat_list_next : Tstat_list_spr;");
+
+    vhdl->set_body   (0,"begin  -- process transition");
+    vhdl->set_body   (1,"if in_CLOCK'event and in_CLOCK = '1' then");
+    vhdl->set_body   (2,"if in_NRESET = '0' then");
+
+    uint32_t gpr = 0;
+    uint32_t spr = 0;
+
+    vhdl->set_comment(3,"Init Stat List");
+    vhdl->set_comment(3,"xxx_stat_list : ");
+
+    vhdl->set_comment(3,"  [0] is_free");
+    vhdl->set_comment(3,"  [1] is_link");
+
+    vhdl->set_body   (3,"");
+    vhdl->set_comment(3,"gpr_stat_list");
+    vhdl->set_body   (3,"");
+    for (uint32_t i=0; i<_param->_nb_bank; i++)
+      for (uint32_t j=0; j<_param->_nb_general_register_by_bank; j++)
+	if ((gpr++)<_param->_nb_gpr_use_init)
+	  {
+	    vhdl->set_body   (3,"gpr_stat_list("+toString(i)+")("+toString(j)+")<=\"10\";");
+	  }
+	else 
+	  {
+	    vhdl->set_body   (3,"gpr_stat_list("+toString(i)+")("+toString(j)+")<=\"00\";");
+	  }
+
+    vhdl->set_body   (3,"");
+    vhdl->set_comment(3,"spr_stat_list");
+    vhdl->set_body   (3,"");
+    for (uint32_t i=0; i<_param->_nb_bank; i++)
+      for (uint32_t j=0; j<_param->_nb_special_register_by_bank; j++)
+	if ((spr++)<_param->_nb_spr_use_init)
+	  {
+	    vhdl->set_body   (3,"spr_stat_list("+toString(i)+")("+toString(j)+")<=\"10\";");
+	  }
+	else 
+	  {
+	    vhdl->set_body   (3,"spr_stat_list("+toString(i)+")("+toString(j)+")<=\"00\";");
+	  }
+
+    vhdl->set_body   (3,"");
+    vhdl->set_comment(3,"Init Pointer");
+
+#ifdef SYSTEMC_VHDL_COMPATIBILITY
+    if (size_gpr_ptr>0)
+    vhdl->set_body   (3,"reg_GPR_PTR_FREE <= "+std_logic_cst(size_gpr_ptr,1)+";");
+    if (size_spr_ptr>0)
+    vhdl->set_body   (3,"reg_SPR_PTR_FREE <= "+std_logic_cst(size_spr_ptr,1)+";");
+#else
+    if (size_gpr_ptr>0)
+    vhdl->set_body   (3,"reg_GPR_PTR_FREE <= "+std_logic_cst(size_gpr_ptr,0)+";");
+    if (size_spr_ptr>0)
+    vhdl->set_body   (3,"reg_SPR_PTR_FREE <= "+std_logic_cst(size_spr_ptr,0)+";");
+#endif
+
+    vhdl->set_body   (2,"else"); //   in_CLOCK'event and in_CLOCK = '1'
+
+//     vhdl->set_body   (2,"gpr_stat_list_next := gpr_stat_list;");
+//     vhdl->set_body   (2,"spr_stat_list_next := spr_stat_list;");
+
+    vhdl->set_comment(3,"=====================================================");
+    vhdl->set_comment(3,"=====[ INSERT ]======================================");
+    vhdl->set_comment(3,"=====================================================");
+
+    for (uint32_t i=0; i<_param->_nb_inst_insert; i++)
+      {
+        vhdl->set_body   (3,"if ((in_INSERT_"+toString(i)+"_VAL and internal_INSERT_"+toString(i)+"_ACK) = '1') then");
+
+        {
+          vhdl->set_body   (4,"if (in_INSERT_"+toString(i)+"_WRITE_RD = '1') then");
+          std::string port = "in_INSERT_"+toString(i)+"_NUM_REG_RD_PHY_NEW";
+          std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0";
+          std::string num_reg  = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0";
+          std::string addr     = "("+num_bank+")("+num_reg+")";
+
+          vhdl->set_body   (5,"gpr_stat_list"+addr+" <= \"10\";");
+          vhdl->set_body   (4,"end if;"); // write_rd
+        }
+
+        {
+          vhdl->set_body   (4,"if (in_INSERT_"+toString(i)+"_WRITE_RE = '1') then");
+          std::string port = "in_INSERT_"+toString(i)+"_NUM_REG_RE_PHY_NEW";
+          std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0";
+          std::string num_reg  = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0";
+          std::string addr     = "("+num_bank+")("+num_reg+")";
+          vhdl->set_body   (5,"spr_stat_list"+addr+" <= \"10\";");
+          vhdl->set_body   (4,"end if;"); // write_re
+        }
+
+        vhdl->set_body   (3,"end if;"); // transaction insert
+      }
+
+    vhdl->set_comment(3,"=====================================================");
+    vhdl->set_comment(3,"=====[ RETIRE ]======================================");
+    vhdl->set_comment(3,"=====================================================");
+
+    for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
+      {
+        vhdl->set_body   (3,"if ((in_RETIRE_"+toString(i)+"_VAL and internal_RETIRE_"+toString(i)+"_ACK) = '1') then");
+        
+        std::string restore = "in_RETIRE_"+toString(i)+"_RESTORE";
+
+        // write rd
+        vhdl->set_body   (4,"if (in_RETIRE_"+toString(i)+"_WRITE_RD = '1') then");
+        {
+          std::string restore_old = "in_RETIRE_"+toString(i)+"_RESTORE_RD_PHY_OLD";
+          
+          {
+            std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RD_PHY_OLD";
+            std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0";
+            std::string num_reg  = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+            vhdl->set_body   (5,"gpr_stat_list"+addr+"(1) <= "+restore+" and "+restore_old+";");
+          }
+          
+          {
+            std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RD_PHY_NEW";
+            std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0";
+            std::string num_reg  = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+
+            vhdl->set_body   (5,"if ("+restore+" = '1') then");
+            vhdl->set_body   (5,"gpr_stat_list"+addr+"(1) <= '0';");
+            vhdl->set_body   (5,"end if;"); // write_rd
+          }
+        }
+
+        vhdl->set_body   (4,"end if;"); // write_rd
+
+        // write re
+        vhdl->set_body   (4,"if (in_RETIRE_"+toString(i)+"_WRITE_RE = '1') then");
+        {
+          std::string restore_old = "in_RETIRE_"+toString(i)+"_RESTORE_RE_PHY_OLD";
+          
+          {
+            std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RE_PHY_OLD";
+            std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0";
+            std::string num_reg  = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+            vhdl->set_body   (5,"spr_stat_list"+addr+"(1) <= "+restore+" and "+restore_old+";");
+          }
+          
+          {
+            std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RE_PHY_NEW";
+            std::string num_bank = (size_bank   >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0";
+            std::string num_reg  = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+            
+            vhdl->set_body   (5,"if ("+restore+" = '1') then");
+            vhdl->set_body   (5,"spr_stat_list"+addr+"(1) <= '0';");
+            vhdl->set_body   (5,"end if;"); // write_re
+          }
+        }
+
+        vhdl->set_body   (4,"end if;"); // write_re
+        vhdl->set_body   (3,"end if;"); // transaction retire
+      }
+
+    for (uint32_t i=0; i<_param->_nb_reg_free; i++)
+      {
+        {
+          vhdl->set_comment(3,"=====================================================");
+          vhdl->set_comment(3,"=====[ PUSH_GPR ]====================================");
+          vhdl->set_comment(3,"=====================================================");
+          vhdl->set_body   (3,"if ((internal_PUSH_GPR_"+toString(i)+"_VAL and in_PUSH_GPR_"+toString(i)+"_ACK) = '1') then");
+
+          std::string num_bank = (size_bank   >0)?("conv_integer(internal_PUSH_GPR_"+toString(i)+"_NUM_BANK)"):"0";
+          std::string num_reg  = (size_gpr_ptr>0)?("conv_integer(internal_PUSH_GPR_"+toString(i)+"_NUM_REG )"):"0";
+          std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+          vhdl->set_body   (4,"gpr_stat_list"+addr+"(0) <= '1';");
+          vhdl->set_body   (3,"end if;");
+        }
+
+        {
+          vhdl->set_comment(3,"=====================================================");
+          vhdl->set_comment(3,"=====[ PUSH_SPR ]====================================");
+          vhdl->set_comment(3,"=====================================================");
+          vhdl->set_body   (3,"if ((internal_PUSH_SPR_"+toString(i)+"_VAL and in_PUSH_SPR_"+toString(i)+"_ACK) = '1') then");
+
+          std::string num_bank = (size_bank   >0)?("conv_integer(internal_PUSH_SPR_"+toString(i)+"_NUM_BANK)"):"0";
+          std::string num_reg  = (size_spr_ptr>0)?("conv_integer(internal_PUSH_SPR_"+toString(i)+"_NUM_REG )"):"0";
+          std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+          vhdl->set_body   (4,"spr_stat_list"+addr+"(0) <= '1';");
+          vhdl->set_body   (3,"end if;");
+        }
+      }
+
+    vhdl->set_comment(3,"=====================================================");
+    vhdl->set_comment(3,"=====[ POINTER ]=====================================");
+    vhdl->set_comment(3,"=====================================================");
+
+    if (size_gpr_ptr>0)
+      {
+        if (is_power2(_param->_nb_general_register_by_bank))
+          {
+            if (size_gpr_ptr == 1)
+              vhdl->set_body   (3,"reg_GPR_PTR_FREE <= not reg_GPR_PTR_FREE;");
+            else
+              vhdl->set_body   (3,"reg_GPR_PTR_FREE <= reg_GPR_PTR_FREE - "+std_logic_cst(size_gpr_ptr,1)+";");
+          }
+        else
+          {
+            throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of GPR must a power of 2."));
+          }
+      }
+    
+    if (size_spr_ptr>0)
+      {
+        if (is_power2(_param->_nb_special_register_by_bank))
+          {
+            if (size_spr_ptr == 1)
+              vhdl->set_body   (3,"reg_SPR_PTR_FREE <= not reg_SPR_PTR_FREE;");
+            else
+              vhdl->set_body   (3,"reg_SPR_PTR_FREE <= reg_SPR_PTR_FREE - "+std_logic_cst(size_spr_ptr,1)+";");
+          }
+        else
+          {
+            throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of SPR must a power of 2."));
+          }
+      }
+
+    vhdl->set_body   (2,"end if;"); //   in_CLOCK'event and in_CLOCK = '1'
+    vhdl->set_body   (1,"end if;"); //   if in_NRESET = '0'
+    vhdl->set_body   (0,"end process transition;");
+    
+    {
+    vhdl->set_body   (0,"");
+    vhdl->set_comment(0,"=====================================================");
+    vhdl->set_comment(0,"=====[ PUSH_GPR ]====================================");
+    vhdl->set_comment(0,"=====================================================");
+    vhdl->set_body   (0,"");
+
+    for (uint32_t i=0; i<_param->_nb_reg_free; i++)
+      {
+        uint32_t offset     = i*_param->_nb_bank_by_port_free;
+        std::string address; 
+        
+        if (size_gpr_ptr > 0)
+          {
+            address = "internal_PUSH_GPR_"+toString(i)+"_NUM_REG";
+            vhdl->set_body   (0,"internal_PUSH_GPR_"+toString(i)+"_NUM_REG  <= reg_GPR_PTR_FREE;");
+          }
+        else
+          {
+            address = "0";
+          }
+        
+        vhdl->set_body   (0,"internal_PUSH_GPR_"+toString(i)+"_VAL      <= '1' when");
+        vhdl->set_body   (1,"false");
+        
+        for (uint32_t j=0; j<_param->_nb_bank_by_port_free; j++)
+          {
+            std::string num_bank = toString(offset+j);
+            std::string num_reg  = "conv_integer("+address+")";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+            vhdl->set_body   (1,"or (gpr_stat_list"+addr+" = \"00\")");
+          }
+        vhdl->set_body   (1,"else '0';");
+        
+        if (size_bank > 0)
+          {
+        vhdl->set_body   (0,"internal_PUSH_GPR_"+toString(i)+"_NUM_BANK <= ");
+        for (uint32_t j=0; j<_param->_nb_bank_by_port_free-1; j++)
+          {
+            uint32_t   _num_bank = offset+j;
+            std::string num_bank = toString(_num_bank);
+            std::string num_reg  = "conv_integer("+address+")";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+            vhdl->set_body   (1,std_logic_cst(size_bank,_num_bank)+" when (gpr_stat_list"+addr+" = \"00\") else");
+          }
+        vhdl->set_body   (1,std_logic_cst(size_bank,offset+_param->_nb_bank_by_port_free-1)+";");
+          }
+
+        vhdl->set_body   (0,"out_PUSH_GPR_"+toString(i)+"_VAL     <= internal_PUSH_GPR_"+toString(i)+"_VAL;");
+
+        if (is_power2(_param->_nb_general_register_by_bank))
+          {
+            std::string num_bank = (size_bank    > 0)?("internal_PUSH_GPR_"+toString(i)+"_NUM_BANK"):"";
+            std::string num_reg  = (size_gpr_ptr > 0)?address:"";
+            std::string conc     = ((size_gpr_ptr*size_bank) > 0)?" & ":"";
+
+        vhdl->set_body   (0,"out_PUSH_GPR_"+toString(i)+"_NUM_REG <=  "+num_bank+conc+num_reg+";");
+          }
+        else
+          {
+            throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of GPR must a power of 2."));
+          }
+      }
+      }
+
+
+    {
+    vhdl->set_body   (0,"");
+    vhdl->set_comment(0,"=====================================================");
+    vhdl->set_comment(0,"=====[ PUSH_SPR ]====================================");
+    vhdl->set_comment(0,"=====================================================");
+    vhdl->set_body   (0,"");
+
+    for (uint32_t i=0; i<_param->_nb_reg_free; i++)
+      {
+        uint32_t offset     = i*_param->_nb_bank_by_port_free;
+        std::string address; 
+        
+        if (size_spr_ptr > 0)
+          {
+            address = "internal_PUSH_SPR_"+toString(i)+"_NUM_REG";
+            vhdl->set_body   (0,"internal_PUSH_SPR_"+toString(i)+"_NUM_REG  <= reg_SPR_PTR_FREE;");
+          }
+        else
+          {
+            address = "0";
+          }
+        
+        vhdl->set_body   (0,"internal_PUSH_SPR_"+toString(i)+"_VAL      <= '1' when");
+        vhdl->set_body   (1,"false");
+        
+        for (uint32_t j=0; j<_param->_nb_bank_by_port_free; j++)
+          {
+            std::string num_bank = toString(offset+j);
+            std::string num_reg  = "conv_integer("+address+")";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+            vhdl->set_body   (1,"or (spr_stat_list"+addr+" = \"00\")");
+          }
+        vhdl->set_body   (1,"else '0';");
+        
+        if (size_bank > 0)
+          {
+        vhdl->set_body   (0,"internal_PUSH_SPR_"+toString(i)+"_NUM_BANK <= ");
+        for (uint32_t j=0; j<_param->_nb_bank_by_port_free-1; j++)
+          {
+            uint32_t   _num_bank = offset+j;
+            std::string num_bank = toString(_num_bank);
+            std::string num_reg  = "conv_integer("+address+")";
+            std::string addr     = "("+num_bank+")("+num_reg+")";
+          
+            vhdl->set_body   (1,std_logic_cst(size_bank,_num_bank)+" when (spr_stat_list"+addr+" = \"00\") else");
+          }
+        vhdl->set_body   (1,std_logic_cst(size_bank,offset+_param->_nb_bank_by_port_free-1)+";");
+          }
+
+        vhdl->set_body   (0,"out_PUSH_SPR_"+toString(i)+"_VAL     <= internal_PUSH_SPR_"+toString(i)+"_VAL;");
+
+        if (is_power2(_param->_nb_special_register_by_bank))
+          {
+            std::string num_bank = (size_bank    > 0)?("internal_PUSH_SPR_"+toString(i)+"_NUM_BANK"):"";
+            std::string num_reg  = (size_spr_ptr > 0)?address:"";
+            std::string conc     = ((size_spr_ptr*size_bank) > 0)?" & ":"";
+
+        vhdl->set_body   (0,"out_PUSH_SPR_"+toString(i)+"_NUM_REG <=  "+num_bank+conc+num_reg+";");
+          }
+        else
+          {
+            throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of SPR must a power of 2."));
+          }
+      }
+    }
+
     log_printf(FUNC,Stat_List_unit,FUNCTION,"End");
   };
