#include <systemc>
#include <signal.h>
#include <sys/time.h>
#include <cstdlib>
#include <cstdarg>

#include "topcell_.h"

bool stop;
void run(sc_core::sc_signal<bool> &resetn)
{
#ifdef SYSTEMCASS
	sc_core::sc_start(0);
	resetn = false;
	sc_core::sc_start(1);
	resetn = true;
#else
	sc_core::sc_start(sc_core::sc_time(0, sc_core::SC_NS));
	resetn = false;
	sc_core::sc_start(sc_core::sc_time(1, sc_core::SC_NS));
	resetn = true;
#endif

#ifdef SOCVIEW
	debug();
#else
	const char *t = getenv("STATS_EVERY");
	if ( t ) {
		int delta = atoi(t);
		while (!stop) {
			struct timezone tz;
			struct timeval end, begin, tp;
			gettimeofday( &begin, &tz );
#ifdef SYSTEMCASS
			sc_core::sc_start(delta);
#else
			sc_core::sc_start(sc_core::sc_time(delta, sc_core::SC_NS));
#endif
			gettimeofday( &end, &tz );
			timersub( &end, &begin, &tp );
			long ms = (tp.tv_sec*1000+tp.tv_usec/1000);
			std::cout << std::dec << delta << " cycles in " << ms << " ms: " << ((double)delta*1000/ms) << " Hz" << std::endl;
		}
	} else {
		sc_core::sc_start();
	}
#endif
}

int _main(int argc, char **argv)
{
	sc_core::sc_signal<bool> resetn;
	sc_core::sc_clock clock;

	topcell_ top0("top0");

	top0.p_resetn(resetn);
	top0.p_clock(clock);

	run(resetn);

	return 0;
}

void quit(int)
{
	sc_core::sc_stop();
    stop = true;
}

int sc_main (int argc, char *argv[])
{
	signal(SIGINT, quit);
	atexit(sc_core::sc_stop);
    stop = false;

	try {
		return _main(argc, argv);
	} catch (std::exception &e) {
		std::cout << e.what() << std::endl;
	} catch (...) {
		std::cout << "Unknown exception occured" << std::endl;
		throw;
	}
	return 1;
}
