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

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

#define NB_PARAMS 17

void usage (int argc, char * argv[])
{
  err (_("<Usage> %s name_instance list_params.\n"),argv[0]);
  err (_("list_params is :\n"));
  err (_(" * nb_context                                            (uint32_t         )\n"));
  err (_(" * nb_front_end                                          (uint32_t         )\n"));
  err (_(" * nb_rename_unit                                        (uint32_t         )\n"));
  err (_(" * size_queue                                            (uint32_t         )\n"));
  err (_(" * nb_bank                                               (uint32_t         )\n"));
  err (_(" * size_packet                                           (uint32_t         )\n"));
  err (_(" * size_general_data                                     (uint32_t         )\n"));
  err (_(" * size_special_data                                     (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"));
  err (_(" * nb_inst_issue                                         (uint32_t         )\n"));
  err (_(" * nb_inst_rename        [nb_rename_unit]                (uint32_t         )\n"));
  err (_(" * nb_inst_reexecute                                     (uint32_t         )\n"));
  err (_(" * nb_rename_unit_select                                 (uint32_t         )\n"));
  err (_(" * priority                                              (Tpriority_t      )\n"));
  err (_(" * load_balancing                                        (Tload_balancing_t)\n"));
  err (_(" * table_routing         [nb_rename_unit][nb_inst_issue] (bool             )\n"));
  err (_(" * table_routing         [nb_inst_issue][nb_type]        (bool             )\n"));
  err (_("   * TYPE_ALU    \n"));
  err (_("   * TYPE_SHIFT  \n"));
  err (_("   * TYPE_MOVE   \n"));
  err (_("   * TYPE_TEST   \n"));
  err (_("   * TYPE_MUL    \n"));
  err (_("   * TYPE_DIV    \n"));
  err (_("   * TYPE_EXTEND \n"));
  err (_("   * TYPE_FIND   \n"));
  err (_("   * TYPE_SPECIAL\n"));
  err (_("   * TYPE_CUSTOM \n"));
  err (_("   * TYPE_BRANCH \n"));
  err (_("   * TYPE_MEMORY \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_context             = fromString<uint32_t         >(argv[x++]);
  uint32_t          _nb_front_end           = fromString<uint32_t         >(argv[x++]);
  uint32_t          _nb_rename_unit         = fromString<uint32_t         >(argv[x++]);

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

  uint32_t          _size_queue             = fromString<uint32_t         >(argv[x++]);
  uint32_t          _nb_bank                = fromString<uint32_t         >(argv[x++]);
  uint32_t          _size_packet            = 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          _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++]);
  uint32_t          _nb_inst_issue          = fromString<uint32_t         >(argv[x++]);
  uint32_t        * _nb_inst_rename         = new uint32_t [_nb_rename_unit];
  for (uint32_t i=0; i<_nb_rename_unit; i++)
    _nb_inst_rename [i] = fromString<uint32_t>(argv[x++]);
  uint32_t          _nb_inst_reexecute      = fromString<uint32_t         >(argv[x++]);
  uint32_t          _nb_rename_unit_select  = fromString<uint32_t         >(argv[x++]);
  Tpriority_t       _priority               = fromString<Tpriority_t      >(argv[x++]);
  Tload_balancing_t _load_balancing         = fromString<Tload_balancing_t>(argv[x++]);

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

  bool           ** _table_routing          = new bool * [_nb_rename_unit];
  for (uint32_t i=0; i<_nb_rename_unit; i++)
    {
      _table_routing [i] = new bool [_nb_inst_issue];
      for (uint32_t j=0; j<_nb_inst_issue; j++)
	_table_routing [i][j] = fromString<bool>(argv[x++]);
    }

  bool           ** _table_issue_type          = new bool * [_nb_inst_issue];
  for (uint32_t i=0; i<_nb_inst_issue; i++)
    {
      _table_issue_type [i] = new bool [_nb_inst_issue];

      _table_issue_type [i][TYPE_ALU    ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_SHIFT  ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_MOVE   ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_TEST   ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_MUL    ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_DIV    ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_EXTEND ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_FIND   ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_SPECIAL] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_CUSTOM ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_BRANCH ] = fromString<bool>(argv[x++]);
      _table_issue_type [i][TYPE_MEMORY ] = fromString<bool>(argv[x++]);
    }

  int _return = EXIT_SUCCESS;
  try 
    {
      morpheo::behavioural::core::multi_ooo_engine::ooo_engine::issue_queue::Parameters * param = new morpheo::behavioural::core::multi_ooo_engine::ooo_engine::issue_queue::Parameters
	(_nb_context            ,
	 _nb_front_end          ,
	 _nb_rename_unit        ,
	 _size_queue            ,
	 _nb_bank               ,
	 _size_packet           ,
	 _size_general_data     ,
	 _size_special_data     ,
	 _size_general_register ,
	 _size_special_register ,
	 _size_store_queue_ptr  ,
	 _size_load_queue_ptr   ,
	 _nb_inst_issue         ,
	 _nb_inst_rename        ,
	 _nb_inst_reexecute     ,
	 _nb_rename_unit_select ,
	 _priority              ,
	 _load_balancing        ,
	 _table_routing         ,
	 _table_issue_type      ,
         true // is_toplevel
         );
      
      msg(_("%s"),param->print(1).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("Issue_queue : no error");
      else
	TEST_KO("Issue_queue : a lot of error");
    }
  catch (morpheo::ErrorMorpheo & error)
    {
      msg (_("<%s> :\n%s"),name.c_str(), error.what ());
      _return = EXIT_FAILURE;
    }

  delete [] _nb_inst_rename;

  for (uint32_t i=0; i<_nb_rename_unit; i++)
    delete [] _table_routing [i];
  delete [] _table_routing   ;
  for (uint32_t i=0; i<_nb_inst_issue; i++)
    delete [] _table_issue_type [i];
  delete [] _table_issue_type;

  return (_return);
}
