/*
 * $Id: main.cpp 111 2009-02-27 18:37:40Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor/SelfTest/include/test.h"
#include "Behavioural/include/Selftest.h"

#define NB_PARAMS 11

void usage (int argc, char * argv[])
{
  err (_("<Usage> %s name_instance list_params.\n"),argv[0]);
  err (_("list_params is :\n"));
  err (_(" * nb_inst_predict        (uint32_t)\n"));
  err (_(" * nb_inst_update         (uint32_t)\n"));
  err (_(" * size_address           (uint32_t)\n"));
  err (_(" * have_bht               (bool    )\n"));
  err (_(" * bht_size_shifter       (uint32_t)\n"));
  err (_(" * bht_nb_shifter         (uint32_t)\n"));
  err (_(" * have_pht               (bool    )\n"));
  err (_(" * pht_size_counter       (uint32_t)\n"));
  err (_(" * pht_nb_counter         (uint32_t)\n"));
  err (_(" * pht_size_address_share (uint32_t)\n"));
  err (_(" * update_on_prediction   (bool    )\n"));

  exit (1);
}

#ifndef SYSTEMC
int main    (int argc, char * argv[])
#else
int sc_main (int argc, char * argv[])
#endif
{
  if (argc != static_cast<int>(2+NB_PARAMS))
    usage (argc, argv);

  uint32_t x = 1;

  string name = argv[x++];

  uint32_t nb_inst_predict       ;
  uint32_t nb_inst_update        ;
  uint32_t size_address          ;
  bool     have_bht              ;
  uint32_t bht_size_shifter      ;
  uint32_t bht_nb_shifter        ;
  bool     have_pht              ;
  uint32_t pht_size_counter      ;
  uint32_t pht_nb_counter        ;
  uint32_t pht_size_address_share;
  bool     update_on_prediction  ;

  SELFTEST0(nb_inst_predict       ,uint32_t,argv,x);
  SELFTEST0(nb_inst_update        ,uint32_t,argv,x);
  SELFTEST0(size_address          ,uint32_t,argv,x);
  SELFTEST0(have_bht              ,bool    ,argv,x);
  SELFTEST0(bht_size_shifter      ,uint32_t,argv,x);
  SELFTEST0(bht_nb_shifter        ,uint32_t,argv,x);
  SELFTEST0(have_pht              ,bool    ,argv,x);
  SELFTEST0(pht_size_counter      ,uint32_t,argv,x);
  SELFTEST0(pht_nb_counter        ,uint32_t,argv,x);
  SELFTEST0(pht_size_address_share,uint32_t,argv,x);
  SELFTEST0(update_on_prediction  ,bool    ,argv,x);

  int _return = EXIT_SUCCESS;
  try 
    {
      morpheo::behavioural::core::multi_front_end::front_end::prediction_unit::direction::meta_predictor::two_level_branch_predictor::Parameters * param = new morpheo::behavioural::core::multi_front_end::front_end::prediction_unit::direction::meta_predictor::two_level_branch_predictor::Parameters
	(
         nb_inst_predict       ,
         nb_inst_update        ,
         size_address          ,
         have_bht              ,
         bht_size_shifter      ,
         bht_nb_shifter        ,
         have_pht              ,
         pht_size_counter      ,
         pht_nb_counter        ,
         pht_size_address_share,
         update_on_prediction  ,
         true //is_toplevel
        );
      
      msg(_("%s"),param->print(0).c_str());
      
      test (name,param);
    }
  catch (morpheo::ErrorMorpheo & error)
    {
      msg (_("<%s> :\n%s"),name.c_str(), error.what ());
      _return = EXIT_FAILURE;
    }
  
  try 
    {
      if (_return == EXIT_SUCCESS)
	TEST_OK("Two_Level_Branch_Predictor : no error");
      else
	TEST_KO("Two_Level_Branch_Predictor : a lot of error");
    }
  catch (morpheo::ErrorMorpheo & error)
    {
//       msg (_("<%s> :\n%s"),name.c_str(), error.what ());
      _return = EXIT_FAILURE;
    }

  return (_return);
}
