Index: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp
===================================================================
--- trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp	(revision 109)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp	(revision 111)
@@ -102,4 +102,17 @@
               if (end)
                 {
+#if defined(DEBUG) and defined(DEBUG_Update_Prediction_Table) and (DEBUG_Update_Prediction_Table == true)
+                  if (reg_UPDATE_PREDICTION_TABLE [i][bottom]._retire_ok)
+                    {
+                      uint32_t num_thread = _param->_translate_num_context_to_num_thread [i];
+                      branchement_log_file [num_thread] 
+                        << std::hex
+                        << "0x" << reg_UPDATE_PREDICTION_TABLE [i][bottom]._address_src  << " "
+                        << "0x" << reg_UPDATE_PREDICTION_TABLE [i][bottom]._address_dest << " "
+                        << std::dec
+                        <<         reg_UPDATE_PREDICTION_TABLE [i][bottom]._good_take    << " "
+                        << std::endl;
+                    }
+#endif
                   log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]",i,bottom);
                   log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]._state =  UPDATE_PREDICTION_STATE_EMPTY",i,bottom);
@@ -180,5 +193,9 @@
 //            reg_UFPT_UPDATE  [context] = reg_UFPT_TOP [context];
               if (need_update(condition))
-                reg_UFPT_NB_NEED_UPDATE [context] ++;
+                {
+                  reg_UFPT_NB_NEED_UPDATE [context] ++;
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
+
+                }
 	    }
 
@@ -293,4 +310,6 @@
                     {
                       reg_UFPT_NB_NEED_UPDATE [context] --;
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
+
                     }
 		}
@@ -305,5 +324,6 @@
               log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_WAIT_END (decod - hit)",context,upt_ptr_write);
               reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state = UPDATE_PREDICTION_STATE_WAIT_END;
-              
+              reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._retire_ok = false;
+
               // Write new accurate 
 #ifdef DEBUG_TEST
@@ -377,5 +397,8 @@
                       // Free a register that need update ?
                       if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
-                        reg_UFPT_NB_NEED_UPDATE [context] --;
+                        {
+                          reg_UFPT_NB_NEED_UPDATE [context] --;
+                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
+                        }
                     }
                   else
@@ -402,7 +425,10 @@
 #ifdef STATISTICS
                       Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition;
+#endif
                       bool ok     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_OK);
-#endif
                       bool ko     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO);
+
+                      if (ok or ko)
+                        reg_UPDATE_PREDICTION_TABLE [context][depth]._retire_ok = true;
 
                       // Have an update, test the state to transiste to the good state
@@ -513,27 +539,38 @@
               if (miss)
 		{
+                  // Flush UPT
+                  uint32_t      top                 = reg_UPT_TOP [context];
+                  uint32_t      new_update          = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
+                                                   
+                  Taddress_t    address_src         = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
+                  event_state_t event_state         = reg_EVENT_STATE [context];
+                  upt_state_t   event_top           = reg_UPDATE_PREDICTION_TABLE [context][top]._state;
+                  bool          previous_ufpt_event = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
+                                                       (event_state == EVENT_STATE_MISS_FLUSH_UFPT         ) or
+                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
+                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT        ));
+
+                  bool          previous_upt_event  = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
+                                                       (event_state == EVENT_STATE_MISS_FLUSH_UPT          ) or
+                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
+                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UPT         ) or
+                                                       (event_top   == UPDATE_PREDICTION_STATE_END_KO      ) or
+                                                       (event_top   == UPDATE_PREDICTION_STATE_KO          )
+//                                                   (event_state == EVENT_STATE_WAIT_END_EVENT          ) or
+//                                                   ((event_state == EVENT_STATE_UPDATE_CONTEXT         ) and
+//                                                    (reg_EVENT_SOURCE [context] == EVENT_SOURCE_UPT))
+                                                  );
+//                bool          update_ras     = (new_update != depth);
+
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top                 : %d",top);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update          : %d",new_update);
+//                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras          : %d",update_ras);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * previous_upt_event  : %d",previous_upt_event);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * previous_ufpt_event : %d",previous_ufpt_event);
+
                   // Have a miss !!!
                   // Flush UPFT
-                  flush_UFPT [context] = true;
+                  flush_UFPT [context] = not previous_ufpt_event;
                   
-                  // Flush UPT
-                  uint32_t      top            = reg_UPT_TOP [context];
-                  uint32_t      new_update     = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
-
-                  Taddress_t    address_src    = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
-                  event_state_t event_state    = reg_EVENT_STATE [context];
-                  bool          previous_event = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
-                                                  (event_state == EVENT_STATE_MISS_FLUSH_UPT          ) or
-                                                  (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
-                                                  (event_state == EVENT_STATE_EVENT_FLUSH_UPT         ) or
-                                                  ((event_state == EVENT_STATE_UPDATE_CONTEXT          ) and
-                                                   (reg_EVENT_SOURCE [context] == EVENT_SOURCE_UPT)));
-//                bool          update_ras     = (new_update != depth);
-
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top            : %d",top);
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update     : %d",new_update);
-//                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras     : %d",update_ras);
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * previous_event : %d",previous_event);
-
                   if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_WAIT_END)
                     {
@@ -541,5 +578,8 @@
                            j!=top; 
                            j=(j+1)%_param->_size_upt_queue[context])
-                        reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
+                        {
+                          reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
+                          reg_UPDATE_PREDICTION_TABLE [context][j]._retire_ok = false;
+                        }
                       
                   
@@ -548,5 +588,5 @@
 //                    reg_UPT_TOP_EVENT [context] = top;
 
-                      if (not previous_event)
+                      if (not previous_upt_event)
                         {
                           reg_UPT_TOP_EVENT [context] = top;
@@ -556,6 +596,7 @@
                         {
                           // Have event. Top index this slot
-                          
-                          switch (reg_UPDATE_PREDICTION_TABLE [context][top]._state)
+                          reg_UPDATE_PREDICTION_TABLE [context][top]._retire_ok = false;
+
+                          switch (event_top)
                             {
                             case UPDATE_PREDICTION_STATE_END_KO : 
@@ -573,4 +614,7 @@
                             default :
                               {
+//                                 reg_UPDATE_PREDICTION_TABLE [context][top]._state = UPDATE_PREDICTION_STATE_EVENT;
+//                                 break;
+
 #ifdef DEBUG_TEST
                                 throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
@@ -585,6 +629,9 @@
                       log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_KO (branch_complete, ifetch hit)",context,depth);
                       reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
-                      
-                      if (reg_UFPT_NB_NEED_UPDATE [context] > 0)
+
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE [%d] : %d",context,reg_UFPT_NB_NEED_UPDATE [context]);
+                     
+                      if ( (reg_UFPT_NB_NEED_UPDATE [context] > 0) or
+                           (reg_UFPT_NB_UPDATE      [context] > 0))
                         {
                           log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT (branch_complete - miss)",context);
@@ -736,5 +783,4 @@
                     uint32_t bottom     = reg_UPT_BOTTOM [i];
                     uint32_t new_update = ((top==0)?_param->_size_upt_queue[i]:top)-1; 
-                    bool     full       = ((depth == top) and (top == bottom) and not reg_UPT_EMPTY [i]);
 //                     bool     empty      = reg_UPT_EMPTY [i];
 
@@ -749,5 +795,6 @@
                                                          (event_state == EVENT_STATE_EVENT_FLUSH_UPT));
 
-                    bool find = false; // have slot to update ???
+                    bool     find = false; // have slot to update ???
+                    Tdepth_t depth_new = depth;
 
                     // flush all slot after the event
@@ -760,5 +807,9 @@
                           find = true;
                           reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EVENT;
-                        }
+                          reg_UPDATE_PREDICTION_TABLE [i][j]._retire_ok = false;
+                        }
+                      else
+                        if (not find) // while state == end or empty
+                          depth_new ++;
                     
                     if ((reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END) and
@@ -767,18 +818,24 @@
                         find = true;
                         reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_EVENT;
+                        reg_UPDATE_PREDICTION_TABLE [i][depth]._retire_ok = false;
+
                       }
+                    else
+                      // while state == end or empty
+                      depth = (depth_new+1)%_param->_size_upt_queue[i];
 
                     log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * find       : %d",find);
+                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth_new  : %d",depth_new);
                     
                     // Test if have update slot
                     if (find)
                       {
-                        // flush all slot after the event
-                        for (uint32_t j=(depth+1)%_param->_size_upt_queue[i];
-                             j!=top; 
-                             j=(j+1)%_param->_size_upt_queue[i])
-                          reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EVENT;
-
-                        reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_EVENT;
+//                         // flush all slot after the event
+//                         for (uint32_t j=(depth+1)%_param->_size_upt_queue[i];
+//                              j!=top; 
+//                              j=(j+1)%_param->_size_upt_queue[i])
+//                           reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EVENT;
+
+//                         reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_EVENT;
                         
                         // reg_UPT_BOTTOM    [i];
@@ -791,5 +848,6 @@
                       }
 
-                    bool          update_ras = find and ((top != depth) or full);
+                    bool     full       = ((depth == top) and (top == bottom) and not reg_UPT_EMPTY [i]);
+                    bool     update_ras = find and ((top != depth) or full);
                     
                     log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras : %d",update_ras);
@@ -807,5 +865,8 @@
                     reg_EVENT_UPT_PTR [i] = depth;
 
-                    if (reg_UFPT_NB_NEED_UPDATE [i] > 0)
+                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE          : %d",reg_UFPT_NB_NEED_UPDATE [i]);
+//                     if (reg_UFPT_NB_NEED_UPDATE [i] > 0)
+                    if ( (reg_UFPT_NB_NEED_UPDATE [i] > 0) or
+                         (reg_UFPT_NB_UPDATE      [i] > 0))
                       {
                         if (update_ras)
@@ -871,5 +932,4 @@
               if (reg_UFPT_NB_NEED_UPDATE [i] == 0)
                 {
-
                   // No entry need prediction, flush all entry -> Reset
                   for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
@@ -881,17 +941,22 @@
               else
                 {
+                  uint32_t bottom = reg_UFPT_BOTTOM [i];
                   for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
-                    // EMPTY : no event
-                    // END   : already update
-                    // EVENT : previous event
-                    if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state == UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
-                      {
-                        reg_UFPT_NB_UPDATE [i] ++;
-                        reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EVENT;
-                      }
-
-                  // TOP is next write slot : last slot is TOP-1
-                  uint32_t top = reg_UFPT_TOP [i];
-                  reg_UFPT_UPDATE    [i] = ((top==0)?_param->_size_ufpt_queue[i]:top)-1;
+                    {
+                      uint32_t index = (bottom+j)%_param->_size_ufpt_queue[i];
+                      // EMPTY : no event
+                      // END   : already update
+                      // EVENT : previous event
+                      if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][index]._state == UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
+                        {
+                          reg_UFPT_UPDATE    [i] = index;
+                          reg_UFPT_NB_UPDATE [i] ++;
+                          reg_UPDATE_FETCH_PREDICTION_TABLE [i][index]._state = UPDATE_FETCH_PREDICTION_STATE_EVENT;
+                        }
+                    }
+
+//                   // TOP is next write slot : last slot is TOP-1
+//                   uint32_t top = reg_UFPT_TOP [i];
+//                   reg_UFPT_UPDATE    [i] = ((top==0)?_param->_size_ufpt_queue[i]:top)-1;
 
 //                reg_UFPT_BOTTOM    [i];
