/* -*- c++ -*-
 *
 * SOCLIB_LGPL_HEADER_BEGIN
 * 
 * This file is part of SoCLib, GNU LGPLv2.1.
 * 
 * SoCLib is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 of the License.
 * 
 * SoCLib is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with SoCLib; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * SOCLIB_LGPL_HEADER_END
 *
 * Copyright (c) Telecom ParisTech, Comelec 
 *         Jeremie Brunel <jeremie.brunel@telecom-paristech.fr>, 2013
 *
 */
#ifndef SOCLIB_CABA_TESTER_TGT
#define SOCLIB_CABA_TESTER_TGT

#include <systemc>
#include "caba_base_module.h"
#include "vcd_parser.h"
#include "vci_initiator.h"

namespace soclib {
    namespace caba {
        using namespace sc_core;
        
        template<typename vci_param>
            class VciTesterTgt
            : public BaseModule
            {

                protected:
                    SC_HAS_PROCESS(VciTesterTgt);

                public:
                    sc_in<bool> p_resetn;
                    sc_in<bool> p_clk;
                    VciInitiator<vci_param> p_vci;

                    sc_in<bool> p_synchro;
                    sc_out<uint32_t> p_time;

                    VciTesterTgt(sc_module_name insname, const std::string &filename, const std::string &name);

                    ~VciTesterTgt();
                private:
                    enum tester_state_e
                    {
                        TESTER_IDLE,
                        TESTER_FIRST_READ,
                        TESTER_HANDLE_RESET,
                        TESTER_WAIT_INIT,
                        TESTER_WPLAY,
                        TESTER_PLAY,
                        TESTER_RSPWAIT,
                        TESTER_ERROR,
                        TESTER_PLAYSENARIO,
                        TESTER_END
                    };

                    enum output_tester_e
                    {
                        O_FALSE,
                        O_TRUE,
                        O_WAIT
                    };

                    std::string m_name;
                    uint32_t m_time;
                    sc_signal<tester_state_e> m_tester_fsm;
                    common::VcdParser m_parser;
                    std::map<std::string, uint32_t> next_io_level;
                    std::map<std::string, uint32_t> current_io_level;
                    std::map<std::string, uint32_t> old_io_level;

                    std::vector<std::map<std::string, uint32_t> > m_senario;
                    size_t m_it;

                    void transition();
                    void genMoore();

                    uint32_t test_my_io();
                    void gen_io(const std::map<std::string, uint32_t> &m);

                    uint32_t wave;
                    bool compare_io(const std::map<std::string, uint32_t> &m);
                    std::string merge_sc_name(const char *sc_name);
            };

    }
}

#endif 
