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 78)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp	(revision 81)
@@ -24,4 +24,249 @@
     log_printf(FUNC,Update_Prediction_Table,FUNCTION,"Begin");
 
+    if (PORT_READ(in_NRESET) == 0)
+      {
+	for (uint32_t i=0; i<_param->_nb_context; i++)
+	  {
+	    reg_TOP                [i] = 0;
+	    reg_BOTTOM             [i] = 0;
+	    reg_NB_ELT             [i] = 0;
+	    reg_NB_ELT_NEED_UPDATE [i] = 0;
+	    for (uint32_t j=0; j<_param->_size_queue[i]; j++)
+	      reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EMPTY;
+	  }
+	reg_UPDATE_PRIORITY = 0;
+      }
+    else
+      {
+	// ===================================================================
+	// =====[ PREDICT ]===================================================
+	// ===================================================================
+	for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
+	  if (PORT_READ(in_PREDICT_VAL[i]) and internal_PREDICT_ACK [i])
+	    {
+	      Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
+	      uint32_t   top     = reg_TOP [context];
+
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"PREDICT[%d] - Accepted",i);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * context : %d",context);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * top     : %d",top);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * nb_elt  : %d",reg_NB_ELT[context]);
+
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._state        = UPDATE_PREDICTION_STATE_WAIT_DECOD;
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._ifetch_prediction = true;
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._condition    = PORT_READ(in_PREDICT_BTB_CONDITION    [i]);
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._address_src  = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._last_take    = PORT_READ(in_PREDICT_BTB_LAST_TAKE    [i]);
+	    //reg_UPDATE_PREDICTION_TABLE [context][top]._good_take    
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._history      = (_param->_have_port_history)?PORT_READ(in_PREDICT_DIR_HISTORY [i]):0;
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._address_ras  = PORT_READ(in_PREDICT_RAS_ADDRESS      [i]);
+	      reg_UPDATE_PREDICTION_TABLE [context][top]._index_ras    = PORT_READ(in_PREDICT_RAS_INDEX        [i]);
+
+	      reg_TOP    [context] = (top+1)%_param->_size_queue [context];
+	      reg_NB_ELT [context] ++;
+	    }
+
+	// ===================================================================
+	// =====[ DECOD ]=====================================================
+	// ===================================================================
+	for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
+	  if (PORT_READ(in_DECOD_VAL[i]) and internal_DECOD_ACK [i])
+	    {
+	      Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
+	      Tcontrol_t miss    = PORT_READ(in_DECOD_MISS_PREDICTION [i]);
+
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"DECOD[%d] - Accepted",i);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * context : %d",context);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * miss    : %d",miss);
+	      log_printf(TRACE,Update_Prediction_Table,FUNCTION," * nb_elt  : %d",reg_NB_ELT[context]);
+	      
+	      // Test if miss ifetch
+	      //   miss ifetch = decod a branch and the predict unit have not predict this branch ... gloup :P
+	      if (miss)
+		{
+		  Tdepth_t depth = (_param->_have_port_depth)?PORT_READ(in_DECOD_UPDATE_PREDICTION_ID [i]):0;
+		  Tdepth_t top   = reg_TOP [context];
+
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._state        = UPDATE_PREDICTION_STATE_WAITEND;
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._ifetch_prediction = false; // static prediction
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._condition    = PORT_READ(in_DECOD_BTB_CONDITION    [i]);
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._address_src  = PORT_READ(in_DECOD_BTB_ADDRESS_SRC  [i]);
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._address_dest = PORT_READ(in_DECOD_BTB_ADDRESS_DEST [i]);
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._last_take    = PORT_READ(in_DECOD_BTB_LAST_TAKE    [i]);
+		//reg_UPDATE_PREDICTION_TABLE [context][top]._good_take
+		//reg_UPDATE_PREDICTION_TABLE [context][top]._history
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._address_ras  = PORT_READ(in_DECOD_RAS_ADDRESS      [i]);
+		  reg_UPDATE_PREDICTION_TABLE [context][top]._index_ras    = PORT_READ(in_DECOD_RAS_INDEX        [i]);
+
+		  // Invalid all previous "ifetch" prediction 
+		  // (ifetch prediction = prediction make in fetch stage and not again comming in decod stage)
+		  uint32_t nb_elt_miss        = ((top> depth)?top:(top+_param->_size_queue[context]))-depth;
+		  uint32_t nb_elt_need_update = 0;
+		  for (uint32_t j=0; j<nb_elt_miss; j++)
+		    {
+		      uint32_t k=(depth+j)%_param->_size_queue[context];
+		      
+		      // Ifetch have make a prediction and it's a miss
+		      // When ifetch predict :
+		      //   * btb is not change       -> needn't update
+		      //   * direction is not change -> needn't update
+		      //   * ras have change         -> need    update
+
+		      Tbranch_condition_t cond = reg_UPDATE_PREDICTION_TABLE [context][k]._condition;
+		      if ((cond == BRANCH_CONDITION_NONE_WITH_WRITE_STACK) or
+			  (cond == BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK) or
+			  (cond == BRANCH_CONDITION_READ_STACK))
+			{
+			  nb_elt_need_update ++;
+			  reg_UPDATE_PREDICTION_TABLE [context][k]._state = UPDATE_PREDICTION_STATE_KO;
+			}
+		      else
+			{
+			  reg_UPDATE_PREDICTION_TABLE [context][k]._state = UPDATE_PREDICTION_STATE_END;
+			}
+		    }
+
+		  reg_TOP                [context] = (depth+1)%_param->_size_queue [context];
+		  reg_NB_ELT_NEED_UPDATE [context] += nb_elt_need_update;
+		  reg_NB_ELT             [context] ++;
+		}
+	      else
+		{
+		  // Normal case : branch is previous predicated, change state of branch
+		  Tdepth_t depth = (_param->_have_port_depth)?PORT_READ(in_DECOD_UPDATE_PREDICTION_ID [i]):0;
+
+		  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_WAITEND;
+		}
+	    }
+
+	// ===================================================================
+	// =====[ BRANCH_COMPLETE ]===========================================
+	// ===================================================================
+	for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
+	  if (PORT_READ(in_BRANCH_COMPLETE_VAL[i]) and internal_BRANCH_COMPLETE_ACK [i])
+	    {
+	      Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
+	      Tdepth_t   depth   = (_param->_have_port_depth     )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
+
+	      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," * nb_elt  : %d",reg_NB_ELT[context]);
+	      
+	      if (internal_BRANCH_COMPLETE_MISS_PREDICTION [i])
+		{
+		  // Miss case
+		  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
+
+		  // Another prediction (prediction with depth higer)
+		  Tdepth_t top                = reg_TOP [context];
+		  uint32_t nb_elt_miss        = ((top> depth)?top:(top+_param->_size_queue[context]))-depth;
+		  uint32_t nb_elt_need_update = 1;
+		  for (uint32_t j=1; j<nb_elt_miss; j++)
+		    {
+		      uint32_t k=(depth+j)%_param->_size_queue[context];
+		      
+		      // Ifetch have make a prediction and it's a miss
+		      // When ifetch predict :
+		      //   * btb is not change       -> needn't update
+		      //   * direction is not change -> needn't update
+		      //   * ras have change         -> need    update
+
+		      Tbranch_condition_t cond = reg_UPDATE_PREDICTION_TABLE [context][k]._condition;
+		      if ((cond == BRANCH_CONDITION_NONE_WITH_WRITE_STACK) or
+			  (cond == BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK) or
+			  (cond == BRANCH_CONDITION_READ_STACK))
+			{
+			  nb_elt_need_update ++;
+			  reg_UPDATE_PREDICTION_TABLE [context][k]._state = UPDATE_PREDICTION_STATE_KO;
+			}
+		      else
+			{
+			  reg_UPDATE_PREDICTION_TABLE [context][k]._state = UPDATE_PREDICTION_STATE_END;
+			}
+		    }
+		  reg_NB_ELT_NEED_UPDATE [context] += nb_elt_need_update;
+
+		  // Update pointer :
+		  reg_TOP                [context]  = depth;
+		  reg_NB_ELT             [context] -= nb_elt_miss;
+		}
+	      else
+		{
+		  // Hit case
+#ifdef DEBUG_TEST
+		  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_WAITEND)
+		    ERRORMORPHEO(FUNCTION,"Branche complete : invalid state");
+#endif
+		  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_OK;
+		}
+
+	      // In all case : update good_take and address_destination
+	      reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take    = internal_BRANCH_COMPLETE_TAKE         [i];
+	      reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest = internal_BRANCH_COMPLETE_ADDRESS_DEST [i];
+	    }
+
+	// ===================================================================
+	// =====[ UPDATE ]====================================================
+	// ===================================================================
+	for (uint32_t i=0; i<_param->_nb_inst_update; i++)
+	  if (internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_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 (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO)
+		reg_NB_ELT_NEED_UPDATE [context] --;
+
+	      reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END;
+	    }
+	
+	// Round robin
+	reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
+
+	// ===================================================================
+	// =====[ GARBAGE COLLECTOR ]=========================================
+	// ===================================================================
+
+	for (uint32_t i=0; i<_param->_nb_context; i++)
+	  {
+	    uint32_t bottom = reg_BOTTOM [i];
+	    
+	    // Test if the tail of queue is finish (ok or ko and update)
+	    if (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END)
+	      {
+		log_printf(TRACE,Update_Prediction_Table,FUNCTION,"GARBAGE_COLLECTOR");
+		log_printf(TRACE,Update_Prediction_Table,FUNCTION," * context : %d",i);
+		log_printf(TRACE,Update_Prediction_Table,FUNCTION," * bottom  : %d",bottom);
+
+		reg_UPDATE_PREDICTION_TABLE [i][bottom]._state = UPDATE_PREDICTION_STATE_EMPTY;
+		reg_BOTTOM [i] = (bottom+1)%_param->_size_queue [i];
+		if (reg_NB_ELT [i]>0)
+		  reg_NB_ELT [i] --;
+	      }
+	  }
+      }
+
+// #if (DEBUG >= DEBUG_TRACE)
+    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"Dump Update_Prediction_Table");
+    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * reg_UPDATE_PRIORITY      : %d",reg_UPDATE_PRIORITY);
+    for (uint32_t i=0; i<_param->_nb_context; i++)
+      {
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Update_Prediction_Table [%d]",i);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_TOP                : %d",reg_TOP                [i]);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_BOTTOM             : %d",reg_BOTTOM             [i]);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_NB_ELT             : %d",reg_NB_ELT             [i]);
+	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_NB_ELT_NEED_UPDATE : %d",reg_NB_ELT_NEED_UPDATE [i]);
+	for (uint32_t j=0; j<_param->_size_queue[i]; j++)
+	  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      [%d] %s %x",j,toString(reg_UPDATE_PREDICTION_TABLE [i][j]._state).c_str(),reg_UPDATE_PREDICTION_TABLE [i][j]._address_src);
+      }
+// #endif
+
+
 #if defined(STATISTICS) or defined(VHDL_TESTBENCH)
     end_cycle ();
