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 94)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp	(revision 95)
@@ -44,4 +44,5 @@
             reg_UPT_BOTTOM           [i] = 0;
             reg_UPT_TOP              [i] = 0;
+            reg_UPT_TOP_EVENT        [i] = 0;
             reg_UPT_UPDATE           [i] = 0;
                                                                                     
@@ -87,7 +88,9 @@
             {
               uint32_t bottom = reg_UPT_BOTTOM [i];
-              
+              bool     end_ok = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_OK);
+              bool     end_ko = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_KO);
+
               // Test if state is end
-              if (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END)
+              if (end_ok or end_ko)
                 {
                   log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]",i,bottom);
@@ -96,6 +99,14 @@
                   // Free slot
                   reg_UPDATE_PREDICTION_TABLE [i][bottom]._state = UPDATE_PREDICTION_STATE_EMPTY;
+
                   // Update pointer
                   reg_UPT_BOTTOM [i] = (bottom+1)%_param->_size_upt_queue[i];
+//                   if (bottom = reg_UPT_UPDATE [i])
+//                     reg_UPT_UPDATE [i] = reg_UPT_BOTTOM [i];
+                  if (end_ko) // free
+                    {
+                      reg_UPT_TOP    [i] = reg_UPT_TOP_EVENT [i];
+                      reg_UPT_UPDATE [i] = reg_UPT_TOP_EVENT [i];
+                    }
                 }
             }
@@ -299,7 +310,7 @@
 
 	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_COMPLETE[%d] - Accepted",i);
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss    : %d",miss);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context    : %d",context);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth      : %d",depth);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss       : %d",miss);
 	      
               if (miss)
@@ -312,4 +323,8 @@
                   uint32_t top        = reg_UPT_TOP [context];
                   uint32_t new_update = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
+
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top        : %d",top);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update : %d",new_update);
+
                   for (uint32_t j=(depth+1)%_param->_size_upt_queue[context];
                                 j!=top; 
@@ -317,9 +332,8 @@
                     reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
                   
-                  // TOP is next write slot : last slot is TOP-1
-                  reg_UPT_UPDATE [context] = new_update;
-                  
-//                reg_UPT_BOTTOM [context];
-                  reg_UPT_TOP    [context] = depth;
+                  
+//                reg_UPT_BOTTOM    [context];
+                  reg_UPT_TOP       [context] = depth;
+                  reg_UPT_TOP_EVENT [context] = top;
 
 #ifdef DEBUG_TEST
@@ -331,6 +345,10 @@
                   reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
                   
-
-                  Taddress_t          address_src = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
+                  Taddress_t    address_src         = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
+                  event_state_t event_state         = reg_EVENT_STATE [context];
+                  bool          previous_update_ras = (event_state == EVENT_STATE_FLUSH_UPT);
+                  bool          update_ras          = (new_update != depth);
+
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras : %d",update_ras);
 
                   if (reg_UFPT_NB_NEED_UPDATE [context] > 0)
@@ -341,8 +359,19 @@
                   else
                     {
-                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT_RAS (branch_complete - miss)",context);
-                      // have ras prediction ?
-                      reg_EVENT_STATE [context] = (new_update!=depth)?EVENT_STATE_FLUSH_UPT_RAS:EVENT_STATE_UPDATE_CONTEXT;
-                    }
+                      if (not previous_update_ras)
+                        {
+                          // have ras prediction ?
+                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UPT (branch_complete - miss)",context);
+
+                          reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UPT;
+             
+                        }
+                    }
+
+                  if (not previous_update_ras)
+                    {
+                      reg_UPT_UPDATE [context]  = new_update;
+                    }
+                  // else no update
 
                   reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
@@ -370,97 +399,129 @@
 	// =====[ UPDATE ]====================================================
 	// ===================================================================
-	for (uint32_t i=0; i<_param->_nb_inst_update; i++)
-	  if ((internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_ACK [i])) or
-              (internal_UPDATE_VAL_WITHOUT_ACK [i]))
-	    {
-	      Tcontext_t context = internal_UPDATE_CONTEXT_ID [i];
-	      Tdepth_t   depth   = internal_UPDATE_DEPTH      [i];
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
-
-              if (internal_UPDATE_FROM_UFPT [i])
+        {
+          bool can_continue [_param->_nb_context];
+          for (uint32_t i=0; i<_param->_nb_context; ++i)
+            can_continue [i] = true;
+
+          for (uint32_t i=0; i<_param->_nb_inst_update; i++)
+            {
+	      Tcontext_t context   = internal_UPDATE_CONTEXT_ID [i];
+
+              if ((internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_ACK [i])) or
+                  (internal_UPDATE_VAL_WITHOUT_ACK [i] and can_continue [context]))
                 {
-                // if free a slot, also all queue is updated
-                // Last slot ?
-                if (reg_UFPT_UPDATE [context] == reg_UFPT_BOTTOM [context])
-                  switch (reg_EVENT_STATE [context])
-                    {
-                    case EVENT_STATE_FLUSH_UFPT         : reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT; break;
-                    case EVENT_STATE_FLUSH_UFPT_AND_UPT : reg_EVENT_STATE [context] = (reg_UPT_UPDATE[context]!=reg_UPT_TOP[context])?EVENT_STATE_FLUSH_UPT_RAS:EVENT_STATE_UPDATE_CONTEXT;  break;
-                    default : break;
-                    }
-                
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
-                  
-                  // Change state
-#ifdef DEBUG_TEST
-                  if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state != UPDATE_FETCH_PREDICTION_STATE_EVENT)
-                    throw ERRORMORPHEO(FUNCTION,_("Update : invalid ufpt state."));
-#endif
-
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (update)",context,depth);
-
-                  reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state = UPDATE_FETCH_PREDICTION_STATE_END;
-
-
-                  // Update pointer
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (before) : %d",reg_UFPT_UPDATE [context]);
-                  reg_UFPT_UPDATE [context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (after ) : %d",reg_UFPT_UPDATE [context]);
-                  // Free a register that need update ?
-                  if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
-                    reg_UFPT_NB_NEED_UPDATE [context] --;
+                  Tdepth_t   depth     = internal_UPDATE_DEPTH      [i];
+                  
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
+                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
+                  
+                  if (internal_UPDATE_FROM_UFPT [i])
+                    {
+                      // if free a slot, also all queue is updated
+                      // Last slot ?
+                      if (reg_UFPT_UPDATE [context] == reg_UFPT_BOTTOM [context])
+                        switch (reg_EVENT_STATE [context])
+                          {
+                          case EVENT_STATE_FLUSH_UFPT             : reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT; break;
+                            // impossible to have an update on ufpt and reg_upt_update>reg_upt_top
+                          case EVENT_STATE_FLUSH_UFPT_AND_UPT : reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UPT ; break;
+                          default : break;
+                          }
+                      
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
+                      
+                      // Change state
+#ifdef DEBUG_TEST
+                      if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state != UPDATE_FETCH_PREDICTION_STATE_EVENT)
+                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid ufpt state."));
+#endif
+                      
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (update)",context,depth);
+                      
+                      reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state = UPDATE_FETCH_PREDICTION_STATE_END;
+                      
+                      
+                      // Update pointer
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (before) : %d",reg_UFPT_UPDATE [context]);
+                      reg_UFPT_UPDATE [context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (after ) : %d",reg_UFPT_UPDATE [context]);
+                      // Free a register that need update ?
+                      if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
+                        reg_UFPT_NB_NEED_UPDATE [context] --;
+                    }
+                  else
+                    {
+                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
+                      
+                      // Change state
+#ifdef DEBUG_TEST 
+                      if (internal_UPDATE_RAS [i])
+                        {
+                          if ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_EVENT) and
+                              (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_KO   ))
+                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
+                        }
+                      else
+                        {
+                          if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_OK   )
+                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
+                        }
+#endif
+
+//                    bool have_event = ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO) or
+//                                       (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_EVENT));
+                      bool ko     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO);
+
+                      // Have an update, test the state to transiste to the good state
+                      if (ko)
+                        {
+                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO (update)",context,depth);
+                          
+                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_KO;
+                        }
+                      else
+                        {
+                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_OK (update)",context,depth);
+                          
+                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_OK;
+                        }
+                      
+                      // Update pointer
+                      //  * if update RAS : update pointer is decreaste until it equal at top pointer
+                      if (internal_UPDATE_RAS [i])
+                        {
+                          // if end_event, restart too bottom, else decrease pointer
+                          bool end_event  = (reg_UPT_UPDATE [context] == reg_UPT_TOP [context]);
+                          
+                          reg_UPT_UPDATE [context] = (end_event)?reg_UPT_BOTTOM[context]:(((depth==0)?_param->_size_upt_queue[context]:depth)-1);
+                          if (end_event)
+                            {
+                              reg_UPT_UPDATE [context] = reg_UPT_BOTTOM[context];
+                              reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
+                            }
+                          else
+                            {
+                              reg_UPT_UPDATE [context] = (((depth==0)?_param->_size_upt_queue[context]:depth)-1);
+                            }
+                        }
+                      else
+                        {
+                          // increase pointer
+                          reg_UPT_UPDATE [context] = (depth+1)%_param->_size_upt_queue[context];
+                        }
+                      
+                      // Free the branch with no accurate ?
+                      if (reg_UPDATE_PREDICTION_TABLE [context][depth]._is_accurate == false)
+                        reg_IS_ACCURATE [context] = true;
+                    }
                 }
               else
-                {
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
-                  
-                  // Change state
-#ifdef DEBUG_TEST 
-                  if (internal_UPDATE_RAS [i])
-                    {
-                      if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_EVENT)
-                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
-                    }
-                  else
-                    {
-                      if ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_OK   ) and
-                          (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_KO   ))
-                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
-                    }
-#endif
-
-                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END (update)",context,depth);
-
-                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END;
-
-                  // Update pointer
-                  bool end_event = (reg_UPT_UPDATE [context] == reg_UPT_TOP [context]);
-
-                  if (internal_UPDATE_RAS [i])
-                    {
-                      reg_UPT_UPDATE [context] = (end_event)?reg_UPT_BOTTOM[context]:(((depth==0)?_param->_size_upt_queue[context]:depth)-1);
-                    }
-                  else
-                    {
-                      reg_UPT_UPDATE [context] = (depth+1)%_param->_size_upt_queue[context];
-                    }
-                  
-                  // End and event ?
-                  if (end_event and
-                      (reg_EVENT_STATE [context] != EVENT_STATE_OK))
-                    {
-                      reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
-                    }
-
-                  // Free the branch with no accurate ?
-                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._is_accurate == false)
-                    reg_IS_ACCURATE [context] = true;
-                }
-	    }
+                can_continue [context] = false;
+            }
 	
-	// Round robin
-	reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
+          // Round robin
+          reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
+        }
 
  	// ===================================================================
@@ -470,5 +531,5 @@
 	  if (internal_BRANCH_EVENT_VAL [i] and PORT_READ(in_BRANCH_EVENT_ACK [i]))
             {
-	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_EVENT [%d] - Accepted",i);
 
 #ifdef DEBUG_TEST
@@ -478,8 +539,57 @@
               
               // Change state
-              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_OK (branch_event)",i);
+              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_WAIT_END_EVENT (branch_event)",i);
               
-              reg_EVENT_STATE [i] = EVENT_STATE_OK;
+              reg_EVENT_STATE [i] = EVENT_STATE_WAIT_END_EVENT;
             }
+
+ 	// ===================================================================
+	// =====[ EVENT ]=====================================================
+	// ===================================================================
+        for (uint32_t i=0; i<_param->_nb_context; ++i)
+          {
+            //----------------------------------------------------------------
+            // Cases
+            //----------------------------------------------------------------
+            //   * EVENT_TYPE_NONE               - nothing
+            //   * EVENT_TYPE_MISS_SPECULATION   
+            //     * EVENT_STATE_END             - Change state, reset pointer
+            //   * EVENT_TYPE_EXCEPTION          - 
+            //     * EVENT_STATE_EVENT           - Flush upft and upt
+            //     * EVENT_STATE_END             - Change state, reset pointer
+            //   * EVENT_TYPE_BRANCH_NO_ACCURATE - nothing : manage in decod and update
+            //   * EVENT_TYPE_SPR_ACCESS         - nothing
+            //   * EVENT_TYPE_MSYNC              - nothing
+            //   * EVENT_TYPE_PSYNC              - nothing
+            //   * EVENT_TYPE_CSYNC              - nothing
+
+            Tevent_state_t event_state = PORT_READ(in_EVENT_STATE [i]);
+            Tevent_type_t  event_type  = PORT_READ(in_EVENT_TYPE  [i]);
+//             Tdepth_t       depth       = PORT_READ(in_EVENT_DEPTH [i]);
+            
+            // Test if end of miss
+            if ((event_state == EVENT_STATE_END) and
+                (event_type  == EVENT_TYPE_MISS_SPECULATION))
+              {
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * EVENT");
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * state : EVENT_STATE_END");
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * type  : EVENT_TYPE_MISS_SPECULATION");
+
+#ifdef DEBUG_TEST
+                if (reg_EVENT_STATE [i] != EVENT_STATE_WAIT_END_EVENT)
+                  throw ERRORMORPHEO(FUNCTION,_("Event : invalid event state."));
+#endif
+                
+                // Change state
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_OK (event)",i);
+                
+                reg_EVENT_STATE [i] = EVENT_STATE_OK;
+
+//                 uint32_t bottom = reg_UPT_BOTTOM [i];
+
+//                 reg_UPT_TOP    [i] = bottom;
+//                 reg_UPT_UPDATE [i] = bottom;
+              }
+          }
 
  	// ===================================================================
@@ -561,4 +671,5 @@
 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_BOTTOM          : %d",reg_UPT_BOTTOM         [i]);
 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP             : %d",reg_UPT_TOP            [i]);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP_EVENT       : %d",reg_UPT_TOP_EVENT      [i]);
 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_UPDATE          : %d",reg_UPT_UPDATE         [i]);
 	for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
