/*
 * $Id: main.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/OOO_Engine_Glue/SelfTest/include/test.h"

#define NB_PARAMS 9

void usage (int argc, char * argv[])
{
  err (_("<Usage> %s name_instance list_params.\n"),argv[0]);
  err (_("list_params is :\n"));
  err (_(" * nb_front_end                                     (uint32_t)\n"));
  err (_(" * nb_context                      [nb_front_end]   (uint32_t)\n"));
  err (_(" * nb_rename_unit                                   (uint32_t)\n"));
  err (_(" * nb_inst_decod                   [nb_front_end]   (uint32_t)\n"));
  err (_(" * nb_inst_insert                  [nb_rename_unit] (uint32_t)\n"));
  err (_(" * nb_inst_retire                  [nb_rename_unit] (uint32_t)\n"));
  err (_(" * size_general_data                                (uint32_t)\n"));
  err (_(" * size_special_data                                (uint32_t)\n"));
  err (_(" * link_rename_unit_with_front_end [nb_front_end]   (uint32_t)\n"));
  err (_(" * size_packet_id                                   (uint32_t)\n"));
  err (_(" * size_general_register                            (uint32_t)\n"));
  err (_(" * size_special_register                            (uint32_t)\n"));
  err (_(" * size_store_queue_ptr                             (uint32_t)\n"));
  err (_(" * size_load_queue_ptr                              (uint32_t)\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_front_end                    = fromString<uint32_t>(argv[x++]);

  if (argc <= static_cast<int>(2+NB_PARAMS+3*_nb_front_end))
    usage (argc, argv);

  uint32_t              * _nb_context                      = new uint32_t [_nb_front_end];
  for (uint32_t i=0; i<_nb_front_end; ++i)
    _nb_context [i] = fromString<uint32_t>(argv[x++]);
  uint32_t                _nb_rename_unit                  = fromString<uint32_t>(argv[x++]);

  if (argc != static_cast<int>(2+NB_PARAMS+3*_nb_front_end+2*_nb_rename_unit))
    usage (argc, argv);

  uint32_t              * _nb_inst_decod                   = new uint32_t [_nb_front_end];
  for (uint32_t i=0; i<_nb_front_end; ++i)
    _nb_inst_decod [i] = fromString<uint32_t>(argv[x++]);
  uint32_t              * _nb_inst_insert                  = new uint32_t [_nb_rename_unit];
  for (uint32_t i=0; i<_nb_rename_unit; ++i)
    _nb_inst_insert [i] = fromString<uint32_t>(argv[x++]);
  uint32_t              * _nb_inst_retire                  = new uint32_t [_nb_rename_unit];
  for (uint32_t i=0; i<_nb_rename_unit; ++i)
    _nb_inst_retire [i] = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_general_data               = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_special_data               = fromString<uint32_t>(argv[x++]);
  uint32_t              * _link_rename_unit_with_front_end = new uint32_t [_nb_front_end];
  std::vector<uint32_t> * _translate_front_end_id_from_rename_unit = new std::vector<uint32_t> [_nb_rename_unit];
  for (uint32_t i=0; i<_nb_front_end; ++i)
    {
      _link_rename_unit_with_front_end [i] = fromString<uint32_t>(argv[x++]);
      _translate_front_end_id_from_rename_unit[_link_rename_unit_with_front_end[i]].push_back(i);
    }

  uint32_t                _size_packet_id                  = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_general_register           = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_special_register           = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_store_queue_ptr            = fromString<uint32_t>(argv[x++]);
  uint32_t                _size_load_queue_ptr             = fromString<uint32_t>(argv[x++]);

  int _return = EXIT_SUCCESS;
  try 
    {
      morpheo::behavioural::core::multi_ooo_engine::ooo_engine::ooo_engine_glue::Parameters * param = new morpheo::behavioural::core::multi_ooo_engine::ooo_engine::ooo_engine_glue::Parameters
	(_nb_front_end                     ,
         _nb_context                       ,
         _nb_rename_unit                   ,
         _nb_inst_decod                    ,
         _nb_inst_insert                   ,
         _nb_inst_retire                   ,
         _size_general_data                ,
         _size_special_data                ,
         _link_rename_unit_with_front_end  ,
         _translate_front_end_id_from_rename_unit  ,
         _size_packet_id                   ,
         _size_general_register            ,
         _size_special_register            ,
         _size_store_queue_ptr             ,
         _size_load_queue_ptr              ,
         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("OOO_Engine_Glue : no error");
      else
	TEST_KO("OOO_Engine_Glue : a lot of error");
    }
  catch (morpheo::ErrorMorpheo & error)
    {
//       msg (_("<%s> :\n%s"),name.c_str(), error.what ());
      _return = EXIT_FAILURE;
    }

  delete [] _translate_front_end_id_from_rename_unit;
  delete [] _link_rename_unit_with_front_end;
  delete [] _nb_inst_retire                 ;
  delete [] _nb_inst_insert                 ;
  delete [] _nb_inst_decod                  ;
  delete [] _nb_context                     ;


  return (_return);
}
