Index: trunk/IPs/systemC/processor/Morpheo/Behavioural/Stage_1_Ifetch/Predictor/Meta_Predictor/Two_Level_Branch_Predictor/SelfTest/src/test.cpp
===================================================================
--- trunk/IPs/systemC/processor/Morpheo/Behavioural/Stage_1_Ifetch/Predictor/Meta_Predictor/Two_Level_Branch_Predictor/SelfTest/src/test.cpp	(revision 2)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Stage_1_Ifetch/Predictor/Meta_Predictor/Two_Level_Branch_Predictor/SelfTest/src/test.cpp	(revision 3)
@@ -7,9 +7,9 @@
  */
 
-#define NB_ITERATION 1
+#define NB_ITERATION 512
 
 #include "Behavioural/Stage_1_Ifetch/Predictor/Meta_Predictor/Two_Level_Branch_Predictor/SelfTest/include/test.h"
 #include "Include/Test.h"
-
+#include "Include/BitManipulation.h"
 void test (string name,
 	   morpheo::behavioural::stage_1_ifetch::predictor::meta_predictor::two_level_branch_predictor::Parameters param)
@@ -28,5 +28,5 @@
    * Déclarations des signaux
    *********************************************************************/
-  sc_clock                              *  CLOCK ("clock", 1.0, 0.5);
+  sc_clock                              *  CLOCK;
 
   sc_signal<Tcontrol_t>                 *  PREDICT_VAL                 [param._nb_prediction];
@@ -41,5 +41,5 @@
   sc_signal<Tbht_history_t>             *  BRANCH_COMPLETE_BHT_HISTORY [param._nb_branch_complete];
   sc_signal<Tpht_history_t>             *  BRANCH_COMPLETE_PHT_HISTORY [param._nb_branch_complete];
-  sc_signal<Tcontrol_t>                 *  BRANCH_COMPLETE_HIT         [param._nb_branch_complete];
+  sc_signal<Tcontrol_t>                 *  BRANCH_COMPLETE_DIRECTION   [param._nb_branch_complete];
 
   // Rename signal
@@ -75,6 +75,6 @@
       rename = "BRANCH_COMPLETE_PHT_HISTORY_"+toString(i);
       BRANCH_COMPLETE_PHT_HISTORY [i] = new sc_signal<Tpht_history_t> (rename.c_str());
-      rename = "BRANCH_COMPLETE_HIT_"        +toString(i);
-      BRANCH_COMPLETE_HIT         [i] = new sc_signal<Tcontrol_t>     (rename.c_str());
+      rename = "BRANCH_COMPLETE_DIRECTION_"  +toString(i);
+      BRANCH_COMPLETE_DIRECTION   [i] = new sc_signal<Tcontrol_t>     (rename.c_str());
     }
 
@@ -86,15 +86,15 @@
   
   (*(_Two_Level_Branch_Predictor->in_CLOCK))        (*(CLOCK));
-
-    for (uint32_t i=0; i<param._nb_prediction; i++)
-      {
-	(*(_Two_Level_Branch_Predictor-> in_PREDICT_VAL                 [i])) (*(PREDICT_VAL                  [i]));
-	(*(_Two_Level_Branch_Predictor->out_PREDICT_ACK                 [i])) (*(PREDICT_ACK                  [i]));
-	(*(_Two_Level_Branch_Predictor-> in_PREDICT_ADDRESS             [i])) (*(PREDICT_ADDRESS              [i]));
-	if (param._have_bht)						       				       
-	(*(_Two_Level_Branch_Predictor->out_PREDICT_BHT_HISTORY         [i])) (*(PREDICT_BHT_HISTORY          [i]));
-	if (param._have_pht)						       				       
-	(*(_Two_Level_Branch_Predictor->out_PREDICT_PHT_HISTORY         [i])) (*(PREDICT_PHT_HISTORY          [i]));
-      }
+  
+  for (uint32_t i=0; i<param._nb_prediction; i++)
+    {
+      (*(_Two_Level_Branch_Predictor-> in_PREDICT_VAL                 [i])) (*(PREDICT_VAL                  [i]));
+      (*(_Two_Level_Branch_Predictor->out_PREDICT_ACK                 [i])) (*(PREDICT_ACK                  [i]));
+      (*(_Two_Level_Branch_Predictor-> in_PREDICT_ADDRESS             [i])) (*(PREDICT_ADDRESS              [i]));
+      if (param._have_bht)						       				       
+      (*(_Two_Level_Branch_Predictor->out_PREDICT_BHT_HISTORY         [i])) (*(PREDICT_BHT_HISTORY          [i]));
+      if (param._have_pht)
+      (*(_Two_Level_Branch_Predictor->out_PREDICT_PHT_HISTORY         [i])) (*(PREDICT_PHT_HISTORY          [i]));
+    }
 
     for (uint32_t i=0; i<param._nb_branch_complete; i++)
@@ -105,7 +105,7 @@
 	if (param._have_bht)						       					
 	(*(_Two_Level_Branch_Predictor-> in_BRANCH_COMPLETE_BHT_HISTORY [i])) (*(BRANCH_COMPLETE_BHT_HISTORY  [i]));
-	if (param._have_bht)						       					
+	if (param._have_pht)						       					
 	(*(_Two_Level_Branch_Predictor-> in_BRANCH_COMPLETE_PHT_HISTORY [i])) (*(BRANCH_COMPLETE_PHT_HISTORY  [i]));
-	(*(_Two_Level_Branch_Predictor-> in_BRANCH_COMPLETE_HIT         [i])) (*(BRANCH_COMPLETE_HIT          [i]));
+	(*(_Two_Level_Branch_Predictor-> in_BRANCH_COMPLETE_DIRECTION   [i])) (*(BRANCH_COMPLETE_DIRECTION    [i]));
       }
 
@@ -121,4 +121,9 @@
 
   srand(seed);
+
+  const uint32_t   num_port_predict         = rand()%param._nb_prediction;
+  const uint32_t   num_port_branch_complete = rand()%param._nb_branch_complete;
+  const Taddress_t address                  = rand()%param._size_address;
+        Tcontrol_t direction;
 
   sc_start(0);
@@ -133,10 +138,48 @@
 
   // Step 1
-  BRANCH_COMPLETE_VAL          [0]->write(1);
-  BRANCH_COMPLETE_HIT          [0]->write(0);
+  BRANCH_COMPLETE_VAL          [num_port_branch_complete]->write(1);
+  BRANCH_COMPLETE_DIRECTION    [num_port_branch_complete]->write(0);
+
+  if (param._have_pht)						       					
+    {
+      // Step 1.1 -> pattern_history_table
+
+      // Step 1.1.1 compute number of group.
+      uint32_t size_address_shift=0;
+
+      if (param._have_bht)
+	size_address_shift=param._param_two_level_branch_predictor_glue->_pht_size_address_shift;
+
+      uint32_t nb_group        = (1<<size_address_shift);
+      uint32_t nb_reg_by_group = (1<<(param._pht_size_address-size_address_shift));
+
+      _Two_Level_Branch_Predictor->vhdl_testbench_label("Init pht");
+      cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} Init pht" << endl;
+      
+      BRANCH_COMPLETE_PHT_HISTORY  [num_port_branch_complete]->write(0);
+
+      // Step 1.1.2 for all group ...
+      for (uint32_t i=0; i<nb_group; i++)
+	{
+	  if (param._have_bht)
+	    BRANCH_COMPLETE_BHT_HISTORY  [num_port_branch_complete]->write(i);
+
+	  for (uint32_t j=0; j<nb_reg_by_group; j++)
+	    {
+	      BRANCH_COMPLETE_ADDRESS [num_port_branch_complete]->write(j);
+	      
+	      sc_start(1);
+
+	      // wait ackwolegde
+	      while (BRANCH_COMPLETE_ACK [num_port_branch_complete] -> read() == 0)
+		sc_start(1);
+	    }
+	}
+    }
 
   if (param._have_bht)						       					
     {
-      BRANCH_COMPLETE_BHT_HISTORY  [0]->write(0);
+      // Step 1.2 -> branch_history_table
+      BRANCH_COMPLETE_BHT_HISTORY  [num_port_branch_complete]->write(0);
       
       _Two_Level_Branch_Predictor->vhdl_testbench_label("Init bht");
@@ -145,5 +188,5 @@
       for (uint32_t i=0; i<param._bht_nb_shifter; i++)
 	{
-	  BRANCH_COMPLETE_ADDRESS [0]->write(i);
+	  BRANCH_COMPLETE_ADDRESS [num_port_branch_complete]->write(i);
 
 	  sc_start(1);
@@ -151,39 +194,82 @@
 
       // wait ackwolegde
-      while (BRANCH_COMPLETE_ACK [0] -> read() == 0)
+      while (BRANCH_COMPLETE_ACK [num_port_branch_complete] -> read() == 0)
 	sc_start(1);
     }
 
-  if (param._have_pht)						       					
-    {
-      BRANCH_COMPLETE_BHT_HISTORY  [0]->write(0);
-      BRANCH_COMPLETE_PHT_HISTORY  [0]->write(0);
-      
-      _Two_Level_Branch_Predictor->vhdl_testbench_label("Init bht");
-      cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} Init bht" << endl;
-      
-      for (uint32_t i=0; i<param._bht_nb_shifter; i++)
-	{
-	  BRANCH_COMPLETE_ADDRESS [0]->write(i);
-
-	  sc_start(1);
-	}
+  // Step 2
+  BRANCH_COMPLETE_VAL          [num_port_branch_complete]->write(0);
+  PREDICT_ADDRESS              [num_port_predict        ]->write(address);
+  BRANCH_COMPLETE_ADDRESS      [num_port_branch_complete]->write(address);
+
+  _Two_Level_Branch_Predictor->vhdl_testbench_label("Loop of Test");
+  cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} Loop of Test" << endl
+       << " * predict_address : " << hex << address << dec << endl;
+  
+  // A lot of prediction
+  Tbht_history_t bht_history = 0;
+  Tpht_history_t pht_history [1<<param._bht_size_shifter];
+  
+  for (uint32_t i=0; i<static_cast<uint32_t>(1<<param._bht_size_shifter); i++)
+    pht_history [i] = 0;
+
+  for (uint32_t iteration=0; iteration<NB_ITERATION; iteration ++)
+    {
+      _Two_Level_Branch_Predictor->vhdl_testbench_label("Iteration "+toString(iteration));
+
+      cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} Predict          : bht_history " << bht_history << " - pht_history " << pht_history[bht_history] << endl; 
+
+      // Ask a new prediction
+      PREDICT_VAL                  [num_port_predict        ]->write(1);
+
+      sc_start(1);
 
       // wait ackwolegde
-      while (BRANCH_COMPLETE_ACK [0] -> read() == 0)
+      while (PREDICT_ACK [num_port_predict] -> read() == 0)
 	sc_start(1);
-    }
-
-
-
-  // Step 2
-  _Two_Level_Branch_Predictor->vhdl_testbench_label("Loop of Test");
-  cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} Loop of Test" << endl;
-
-  for (uint32_t iteration=0; iteration<NB_ITERATION; iteration ++)
-    {
-      _Two_Level_Branch_Predictor->vhdl_testbench_label("Iteration "+toString(iteration));
+      PREDICT_ACK                  [num_port_predict        ]->write(0);
+
+      sc_start(0);
+
+      // Test
+      if (param._have_bht)
+      TEST(Tbht_history_t,bht_history             ,PREDICT_BHT_HISTORY[num_port_predict]->read());
+      if (param._have_pht)
+      TEST(Tpht_history_t,pht_history[bht_history],PREDICT_PHT_HISTORY[num_port_predict]->read());
+
+      // update
+      direction = ((rand()%2)==1);
+
+      BRANCH_COMPLETE_VAL          [num_port_branch_complete]->write(1);
+      if (param._have_bht)
+      BRANCH_COMPLETE_BHT_HISTORY  [num_port_branch_complete]->write(bht_history             );
+
+
+      if (param._have_pht)
+      BRANCH_COMPLETE_PHT_HISTORY  [num_port_branch_complete]->write(pht_history[bht_history]);
+      BRANCH_COMPLETE_DIRECTION    [num_port_branch_complete]->write(direction);
+
+      if (param._have_pht)
+      if (direction == 0)
+	{
+	  if (pht_history[bht_history] > 0)
+	    pht_history[bht_history] --;
+	}
+      else
+	{
+	  if (pht_history[bht_history] < (static_cast<Tpht_history_t>(1<<param._pht_size_counter)-1))
+	    pht_history[bht_history] ++;
+	}
+
+      if (param._have_bht)
+      bht_history              = (((bht_history) << 1) | direction) & gen_mask<Tbht_history_t>(param._bht_size_shifter);
 
       sc_start(1);
+
+      // wait ackwolegde
+      while (BRANCH_COMPLETE_ACK [num_port_branch_complete] -> read() == 0)
+	sc_start(1);
+
+      BRANCH_COMPLETE_VAL          [num_port_branch_complete]->write(0);
     }
 
