Index: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_genMoore.cpp
===================================================================
--- trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_genMoore.cpp	(revision 82)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_genMoore.cpp	(revision 88)
@@ -22,5 +22,10 @@
   void Update_Prediction_Table::genMoore (void)
   {
-    log_printf(FUNC,Update_Prediction_Table,FUNCTION,"Begin");
+    log_begin(Update_Prediction_Table,FUNCTION);
+    log_function(Update_Prediction_Table,FUNCTION,_name.c_str());
+    log_printf(NONE,Update_Prediction_Table,FUNCTION,FUNCTION);
+
+    if (PORT_READ(in_NRESET) == 1)
+      {
 
     // ===================================================================
@@ -30,99 +35,234 @@
     for (uint32_t i=0; i<_param->_nb_context; i++)
       {
-	if (_param->_have_port_depth [i])
-	  {
-	    PORT_WRITE(out_DEPTH_TAIL      [i], reg_BOTTOM [i]);
-	  }
-	PORT_WRITE(out_DEPTH_NB_BRANCH [i], reg_NB_ELT [i]);
-      }
+	if (_param->_have_port_depth)
+          {
+        PORT_WRITE(out_DEPTH_CURRENT [i], reg_UPT_TOP    [i]);
+        PORT_WRITE(out_DEPTH_MIN     [i], reg_UPT_BOTTOM [i]);
+          }
+	PORT_WRITE(out_DEPTH_MAX     [i], reg_UPT_TOP    [i]);
+      }
+
     // ===================================================================
     // =====[ UPDATE ]====================================================
     // ===================================================================
 
-    Tdepth_t tab_depth [_param->_nb_context];
+    bool     retire_ras_from_ufpt [_param->_nb_context]; // event ufpt -> restore RAS, else update upt
+    bool     retire_ras_from_upt  [_param->_nb_context]; // event upt  -> restore RAS, else restore others structure
+    bool     ufpt_update          [_param->_nb_context];
+    bool     upt_update           [_param->_nb_context];
+    Tdepth_t tab_ufpt_depth       [_param->_nb_context];
+    Tdepth_t tab_upt_depth        [_param->_nb_context];
+
     for (uint32_t i=0; i<_param->_nb_context; i++)
-      tab_depth [i] = reg_BOTTOM [i];
+      {
+        event_state_t event_state = reg_EVENT_STATE [i];
+
+        retire_ras_from_ufpt [i] = ((event_state == EVENT_STATE_FLUSH_UFPT        ) or
+                                    (event_state == EVENT_STATE_FLUSH_UFPT_AND_UPT));
+        retire_ras_from_upt  [i] = (event_state == EVENT_STATE_FLUSH_UPT_RAS);
+
+        ufpt_update          [i] = true;
+        upt_update           [i] = true;
+        tab_ufpt_depth       [i] = reg_UFPT_UPDATE [i];
+        tab_upt_depth        [i] = reg_UPT_UPDATE  [i];
+      }
 
     for (uint32_t i=0; i<_param->_nb_inst_update; i++)
       {
-	uint32_t   context = (reg_UPDATE_PRIORITY+i)%_param->_nb_context;
-	Tdepth_t   depth   = tab_depth[context];
-	state_t    state   = reg_UPDATE_PREDICTION_TABLE [context][depth]._state;
+	Tcontext_t          context     = (reg_UPDATE_PRIORITY+i)%_param->_nb_context;
+
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE [%d] (genMoore)",i);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context         : %d",context);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * event_state     : %s",toString(reg_EVENT_STATE [context]).c_str());
+
+        Tcontrol_t          val                  = false;
+        Tcontrol_t          val_without_ack      = false;
+        Tcontrol_t          miss_prediction      ;
+        Tcontrol_t          direction_good       ;
+        Tcontrol_t          btb_val              ;
+        Taddress_t          btb_address_src      ;
+        Taddress_t          btb_address_dest     ;
+        Tbranch_condition_t btb_condition        ;
+        Tcontrol_t          dir_val              ;
+        Thistory_t          dir_history          ;
+        Tcontrol_t          ras_val              ;
+        Tcontrol_t          ras_push             ;
+        Taddress_t          ras_address          ;
+        Tptr_t              ras_index            ;
+        Tcontrol_t          ras_prediction_ifetch;
+
+        // Test if update fetch prediction table need update port
+        if (retire_ras_from_ufpt [context])
+          {
+            if (ufpt_update [context])
+              {
+                // Update Fetch Prediction Table
+                // An update of ufpt is to previous miss. Just restore Return Address Stack
+                
+                Tdepth_t            depth     = tab_ufpt_depth[context];
+                ufpt_state_t        state     = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state; 
+                Tbranch_condition_t condition = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition; 
+                
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth           : %d",depth    );
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * state           : %s",toString(state    ).c_str());
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * condition       : %s",toString(condition).c_str());
+                
+                val                   = (state == UPDATE_FETCH_PREDICTION_STATE_EVENT);
+                miss_prediction       = 1;
+//              direction_good        = ;
+                btb_val               = 0; // don't update btb (is update by the event branch)
+//              btb_address_src       = ;
+//              btb_address_dest      = ;
+//              btb_condition         = ;
+                dir_val               = 0; // don't update btb (is update by the event branch (if conditionnal branch))
+//              dir_history           = ;
+                ras_val               = update_ras(condition); // repop/ repush data -> don't corrupt ras
+                ras_push              = push_ras(condition);
+                ras_address           = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._address_ras;
+                ras_index             = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._index_ras;
+                ras_prediction_ifetch = 1;
+                
+                internal_UPDATE_FROM_UFPT [i] = true;
+                internal_UPDATE_DEPTH     [i] = depth;
+                internal_UPDATE_RAS       [i] = false;
+
+                // Warning : don't update same entry
+                if (depth == reg_UFPT_BOTTOM[context])
+                  ufpt_update [context] = false;
+                
+                tab_ufpt_depth[context] = (depth==0)?(_param->_size_ufpt_queue[context]-1):(depth-1);
+              }
+          }
+        else
+          {
+            if (upt_update [context])
+              {
+                // Update Prediction Table
+                
+                Tdepth_t            depth     = tab_upt_depth[context];
+                upt_state_t         state     = reg_UPDATE_PREDICTION_TABLE [context][depth]._state; 
+                Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition; 
+                Tcontrol_t          ifetch    = reg_UPDATE_PREDICTION_TABLE [context][depth]._ifetch_prediction;
+                
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth           : %d",depth    );
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * state           : %s",toString(state    ).c_str());
+                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * condition       : %s",toString(condition).c_str());
+              
+                Tcontrol_t          state_is_ok_ko           = ((state == UPDATE_PREDICTION_STATE_OK) or
+                                                                (state == UPDATE_PREDICTION_STATE_KO));
+                Tcontrol_t          state_is_event           = (state == UPDATE_PREDICTION_STATE_EVENT);
+                Tcontrol_t          state_is_event_update    = state_is_event and     need_update(condition);
+                Tcontrol_t          state_is_event_no_update = state_is_event and not need_update(condition);
+
+                if (retire_ras_from_upt [context])
+                  {
+                val                   = state_is_event_update;
+                val_without_ack       = state_is_event_no_update;
+                  }
+                else
+                  {
+                val                   = state_is_ok_ko;
+                val_without_ack       = false;
+                  }                  
+
+                miss_prediction       = (state != UPDATE_PREDICTION_STATE_OK);
+                direction_good        = reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take   ;
+                btb_val               = update_btb(condition);
+                btb_address_src       = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src ;
+                btb_address_dest      = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest;
+                btb_condition         = condition;
+                dir_val               = update_dir(condition) and ifetch; // if not ifetch, then static prediction
+                dir_history           = reg_UPDATE_PREDICTION_TABLE [context][depth]._history     ;
+                ras_val               = update_ras(condition); // repop/ repush data -> don't corrupt ras
+                ras_push              = push_ras(condition);
+                ras_address           = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_ras;
+                ras_index             = reg_UPDATE_PREDICTION_TABLE [context][depth]._index_ras;
+                ras_prediction_ifetch = ifetch;
+
+                internal_UPDATE_FROM_UFPT [i] = false;
+                internal_UPDATE_DEPTH     [i] = depth;
+                internal_UPDATE_RAS       [i] = retire_ras_from_upt [context];
+
+                // Warning : don't update same entry
+                if (retire_ras_from_upt [context])
+                  {
+                    // Restore RAS. 
+                    if ((depth == reg_UPT_BOTTOM[context]) or not (val or val_without_ack))
+                      upt_update [context] = false;
+                    
+                    tab_upt_depth[context] = (depth==0)?(_param->_size_upt_queue[context]-1):(depth-1);
+                  }
+                else
+                  {
+                    if ((depth == reg_UPT_TOP [context]) or not (val or val_without_ack))
+                      upt_update [context] = false;
+                    
+                    tab_upt_depth[context] = (depth+1)%_param->_size_upt_queue[context];
+                  }
+              }
+          }
+
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * val             : %d",val    );
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * val_without_ack : %d",val_without_ack);
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * btb_val         : %d",btb_val);
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * dir_val         : %d",dir_val);
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * ras_val         : %d",ras_val);
+
+	internal_UPDATE_VAL             [i] = val;
+	internal_UPDATE_VAL_WITHOUT_ACK [i] = val_without_ack;
+        internal_UPDATE_CONTEXT_ID      [i] = context;
+
+	PORT_WRITE(out_UPDATE_VAL                   [i],internal_UPDATE_VAL [i]);
+        if (val)
+          {
+        if (_param->_have_port_context_id)
+        PORT_WRITE(out_UPDATE_CONTEXT_ID            [i],context              );
+        PORT_WRITE(out_UPDATE_MISS_PREDICTION       [i],miss_prediction      );
+        PORT_WRITE(out_UPDATE_DIRECTION_GOOD        [i],direction_good       );
+        PORT_WRITE(out_UPDATE_BTB_VAL               [i],btb_val              );
+        PORT_WRITE(out_UPDATE_BTB_ADDRESS_SRC       [i],btb_address_src      );
+
+        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * address_src     : %.8x",btb_address_src);
+
+        PORT_WRITE(out_UPDATE_BTB_ADDRESS_DEST      [i],btb_address_dest     );
+        PORT_WRITE(out_UPDATE_BTB_CONDITION         [i],btb_condition        );
+        PORT_WRITE(out_UPDATE_DIR_VAL               [i],dir_val              );
+        if (_param->_have_port_history)
+        PORT_WRITE(out_UPDATE_DIR_HISTORY           [i],dir_history          );
+        PORT_WRITE(out_UPDATE_RAS_VAL               [i],ras_val              );
+        PORT_WRITE(out_UPDATE_RAS_PUSH              [i],ras_push             );
+        PORT_WRITE(out_UPDATE_RAS_ADDRESS           [i],ras_address          );
+        PORT_WRITE(out_UPDATE_RAS_INDEX             [i],ras_index            );
+        PORT_WRITE(out_UPDATE_RAS_PREDICTION_IFETCH [i],ras_prediction_ifetch);
+          }
+      }
+
+//     // ===================================================================
+//     // =====[ BRANCH_EVENT ]==============================================
+//     // ===================================================================
+//     for (uint32_t i=0; i<_param->_nb_context; i++)
+//       {
+// 	Tdepth_t   depth   = (reg_BOTTOM [i] + reg_NB_ELT_UPDATE [i])%_param->_size_queue [i];
+// 	state_t    state   = reg_UPDATE_PREDICTION_TABLE [i][depth]._state;
 	
-	Tcontrol_t val     = ((state == UPDATE_PREDICTION_STATE_OK) or
-			      (state == UPDATE_PREDICTION_STATE_KO));
-
-// 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"UPDATE [%d] (genMoore)",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,"  * state       : %s",toString(state).c_str());
-// 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * val         : %d",val);
-// 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * addr_src    : %x",reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src );
-// 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * addr_dest   : %x",reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest);
-
-	if (val)
-	  {
-	    Tbranch_condition_t cond    = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition;
-		      
-	    Tcontrol_t          ifetch  = reg_UPDATE_PREDICTION_TABLE [context][depth]._ifetch_prediction;
-	    Tcontrol_t          btb_val = true;
-	    Tcontrol_t          dir_val = (ifetch and // not ifetch == static prediction
-					   ((cond == BRANCH_CONDITION_FLAG_UNSET) or
-					    (cond == BRANCH_CONDITION_FLAG_SET)));
-	    Tcontrol_t          ras_val = ((cond == BRANCH_CONDITION_NONE_WITH_WRITE_STACK) or
-					   (cond == BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK) or
-					   (cond == BRANCH_CONDITION_READ_STACK));
-	    
-	    Tcontrol_t          push = ((cond == BRANCH_CONDITION_NONE_WITH_WRITE_STACK) or
-					(cond == BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK));
-
-	    if (_param->_have_port_context_id)
-	    PORT_WRITE(out_UPDATE_CONTEXT_ID            [i],context);
-	    PORT_WRITE(out_UPDATE_MISS_PREDICTION       [i],(state == UPDATE_PREDICTION_STATE_KO));
-	    PORT_WRITE(out_UPDATE_DIRECTION_GOOD        [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take   );
-	    PORT_WRITE(out_UPDATE_BTB_VAL               [i],btb_val);
-	    PORT_WRITE(out_UPDATE_BTB_ADDRESS_SRC       [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src );
-	    PORT_WRITE(out_UPDATE_BTB_ADDRESS_DEST      [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest);
-	    PORT_WRITE(out_UPDATE_BTB_CONDITION         [i],cond);
-	    PORT_WRITE(out_UPDATE_DIR_VAL               [i],dir_val);
-	    if (_param->_have_port_history)
-	    PORT_WRITE(out_UPDATE_DIR_HISTORY           [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._history     );
-	    PORT_WRITE(out_UPDATE_RAS_VAL               [i],ras_val);
-	    PORT_WRITE(out_UPDATE_RAS_PUSH              [i],push);
-	    PORT_WRITE(out_UPDATE_RAS_ADDRESS           [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._address_ras );
-	    PORT_WRITE(out_UPDATE_RAS_INDEX             [i],reg_UPDATE_PREDICTION_TABLE [context][depth]._index_ras   );
-	    PORT_WRITE(out_UPDATE_RAS_PREDICTION_IFETCH [i],ifetch);
-
-	    internal_UPDATE_CONTEXT_ID [i] = context;
-	    internal_UPDATE_DEPTH      [i] = depth;
-
-	    tab_depth[context] = (depth+1)%_param->_size_queue[context];
-	  }
-
-	internal_UPDATE_VAL [i] = val;
-	PORT_WRITE(out_UPDATE_VAL [i], internal_UPDATE_VAL [i]);
-      }
-
-    // ===================================================================
-    // =====[ BRANCH_EVENT ]==============================================
-    // ===================================================================
-    for (uint32_t i=0; i<_param->_nb_context; i++)
-      {
-	Tdepth_t   depth   = (reg_BOTTOM [i] + reg_NB_ELT_UPDATE [i])%_param->_size_queue [i];
-	state_t    state   = reg_UPDATE_PREDICTION_TABLE [i][depth]._state;
-	
-	Tcontrol_t val     = (state == UPDATE_PREDICTION_STATE_EVENT);
-
-	if (val)
-	  {
-	    PORT_WRITE(out_BRANCH_EVENT_ADDRESS_SRC  [i], reg_UPDATE_PREDICTION_TABLE [i][depth]._address_src );
-	    PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST [i], reg_UPDATE_PREDICTION_TABLE [i][depth]._address_dest);
-	    internal_BRANCH_EVENT_DEPTH [i] = depth;
-	  }
-
-	internal_BRANCH_EVENT_VAL   [i] = val;
-	PORT_WRITE(out_BRANCH_EVENT_VAL [i], internal_BRANCH_EVENT_VAL [i]);
-      }
-    log_printf(FUNC,Update_Prediction_Table,FUNCTION,"End");
+// 	Tcontrol_t val     = ((state == UPDATE_PREDICTION_STATE_EVENT) or
+//                               (state == UPDATE_PREDICTION_STATE_WAITEND_AND_EVENT));
+
+// 	if (val)
+// 	  {
+// //          breakpoint ("UPT : have an branch_event (depth %d)",depth);
+// 	    PORT_WRITE(out_BRANCH_EVENT_ADDRESS_SRC  [i], reg_UPDATE_PREDICTION_TABLE [i][depth]._address_src );
+// 	    PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST [i], reg_UPDATE_PREDICTION_TABLE [i][depth]._address_dest);
+// 	    internal_BRANCH_EVENT_DEPTH [i] = depth;
+// 	  }
+
+// 	internal_BRANCH_EVENT_VAL   [i] = val;
+// 	PORT_WRITE(out_BRANCH_EVENT_VAL [i], internal_BRANCH_EVENT_VAL [i]);
+//       }
+
+      }
+    log_end(Update_Prediction_Table,FUNCTION);
   };
 
