#ifdef VHDL_TESTBENCH

/*
 * $Id$
 *
 * [ Description ]
 * 
 */

#include "Behavioural/include/Interfaces.h"

namespace morpheo              {
namespace behavioural          {

  void Interfaces::testbench_generate_file  (void)  
  {
    log_printf(FUNC,Behavioural,"generate_file","Begin");

    Vhdl   * vhdl        = new Vhdl(_name+"_Testbench");
    string   counter     = "counter";
    Signal * clock       = this->get_clock();
    Signal * reset       = this->get_reset();
    string   clock_name  = clock->get_name();
    string   reset_name  = reset->get_name();
    uint32_t cycle       = this->get_cycle();

    vhdl->set_signal    (clock_name, 1, 0);
    vhdl->set_signal    (reset_name, 1, 0);
    vhdl->set_signal    (counter, "natural");
    this->set_signal    (vhdl);

    vhdl->set_body("");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("-- Component - Intanciation");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("");

    list<string> * list_signal = new list<string>;
    this->get_signal (list_signal);

    vhdl->set_library_work (_name + "_Pack");
    vhdl->set_body("instance_"+_name+" : "+_name);
    vhdl->set_body("port map (");

    list<string>::iterator i   = list_signal->begin();
    if (i != list_signal->end())
      {
        vhdl->set_body("\t "+*i+"\t=>\t"+*i);
        ++i;
      }
    while (i != list_signal->end())
      {
        vhdl->set_body("\t,"+*i+"\t=>\t"+*i);
        ++i;
      }
    vhdl->set_body("         );");

    delete list_signal;

    string test_name = this->testbench_body(vhdl,counter, reset_name);

    vhdl->set_body("");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("-- reset");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("");
    vhdl->set_body("-- if the systemC simulate have multiple reset, we make the last");
    vhdl->set_body(reset_name+" <= '1' after 150 ns;");    

    vhdl->set_body("");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("-- process clock_name");
    vhdl->set_body("------------------------------------------------------");
    vhdl->set_body("");
    vhdl->set_body(clock_name+" <= not "+clock_name+" after 50 ns;");
    vhdl->set_body("");
    vhdl->set_body("process ("+clock_name+")");
    vhdl->set_body("begin");
    vhdl->set_body("\tif ("+clock_name+"'event and "+clock_name+" = '1') then");
    vhdl->set_body("");
    vhdl->set_body("\t\tif ("+reset_name+" = '0') then");
    vhdl->set_body("");
    vhdl->set_body("\t\t\t"+counter+" <= "+toString(reset->get_reset_cycle(true))+";");
    vhdl->set_body("");
    vhdl->set_body("\t\telse");
    vhdl->set_body("");
    vhdl->set_body("\t\t\t"+counter+" <= "+counter+"+1;");
    vhdl->set_body("");
    vhdl->set_body("\t\t\tassert not ("+counter+" >= "+toString(cycle)+") report \"Test OK\" severity FAILURE;");
    vhdl->set_body("\t\t\tassert not ("+test_name+" = '0') report \"Test KO\" severity FAILURE;");

#ifdef VHDL_TESTBENCH_ASSERT
    vhdl->set_body("\t\t\t-- Assert ...");
    for (uint32_t cpt=0; cpt<=cycle; cpt++)
      vhdl->set_body("\t\t\tassert not ("+counter+" = "+toString(cpt)+") report \"===== Test number "+toString(cpt)+" =====\" severity NOTE;");
#endif

    vhdl->set_body("");
    vhdl->set_body("\t\tend if;");
    vhdl->set_body("\tend if;");
    vhdl->set_body("end process;");

    vhdl->generate_file(false,true);

    delete vhdl;
    
    log_printf(FUNC,Behavioural,"generate_file","End");
  };

}; // end namespace behavioural          
}; // end namespace morpheo              

#endif
