blob: 6541e9e0d666a7bad6fa93803fba8c4e7bdc072c [file] [log] [blame]
// General tests combining features of SystemC 2.1 and 1666
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include <systemc>
using sc_core::sc_interface;
using sc_core::sc_object;
using sc_core::sc_port;
using sc_core::sc_export;
using sc_core::sc_module;
using sc_core::sc_module_name;
using sc_core::sc_in;
using sc_core::sc_in_clk;
using sc_core::sc_signal;
using sc_core::sc_prim_channel;
using sc_core::sc_event;
using sc_core::sc_delta_count;
using sc_core::sc_is_running;
using sc_core::sc_get_top_level_objects;
using sc_core::sc_find_object;
using sc_core::sc_report;
using sc_core::sc_report_handler;
using sc_core::sc_actions;
using sc_core::SC_INFO;
using sc_core::SC_UNSPECIFIED;
using sc_core::SC_THROW;
using sc_core::sc_spawn;
using sc_core::sc_process_handle;
using sc_core::sc_get_current_process_handle;
using sc_core::sc_time;
using sc_core::sc_time_stamp;
using sc_core::SC_ZERO_TIME;
using sc_core::SC_PS;
using sc_core::SC_NS;
using sc_core::SC_US;
using sc_core::sc_start_of_simulation_invoked;
using sc_core::sc_end_of_simulation_invoked;
using sc_core::sc_start;
using sc_core::sc_stop;
using sc_core::sc_copyright;
using sc_core::sc_version;
using sc_core::sc_release;
using sc_dt::sc_abs;
using sc_dt::sc_max;
using sc_dt::sc_min;
using sc_dt::sc_int;
using sc_dt::sc_bigint;
using std::cout;
using std::endl;
#if defined(IEEE_1666_CPLUSPLUS) && IEEE_1666_CPLUSPLUS >= 201103L
// dynamic process macros have been moved to functions on C++11
using sc_core::sc_bind;
using sc_core::sc_ref;
using sc_core::sc_cref;
#endif // IEEE_1666_CPLUSPLUS
struct i_f: virtual sc_interface
{
virtual void write() = 0;
};
void check_form_of_suffix(std::string s)
{
std::string charset = "0123456789";
while (!s.empty())
{
sc_assert(s[0] == '_');
s = s.substr(1);
sc_assert(!s.empty());
do
{
sc_assert(charset.find(s[0]) < charset.size());
s = s.substr(1);
} while (!s.empty() && (s[0] != '_'));
}
}
struct Chan: i_f, sc_object
{
virtual void write()
{
sc_assert(std::string(name()).substr(0,17) == "top.m_dest.object");
check_form_of_suffix(std::string(name()).substr(17));
}
};
struct M_src: sc_core::sc_behavior
{
sc_port<i_f>* p;
SC_HAS_PROCESS(M_src);
M_src(sc_module_name _name)
{
p = new sc_port<i_f>;
SC_THREAD(T);
}
void T()
{
(*p)->write();
}
};
struct M_dest: sc_core::sc_channel
{
sc_export<i_f>* xp;
SC_HAS_PROCESS(M_dest);
M_dest(sc_module_name _name)
{
xp = new sc_export<i_f>;
Chan* ch = new Chan;
xp->bind(*ch);
}
};
void f()
{
::sc_core::wait(33, SC_PS);
}
struct Prim: sc_prim_channel
{
Prim() : cref_arg(1) {}
void write() { request_update(); }
void update()
{
sc_spawn(sc_bind(&Prim::proc, this));
}
void proc()
{
ev.notify(SC_ZERO_TIME);
wait(ev);
cout << "Prim::Proc spawned and resumed" << endl;
SC_FORK
sc_spawn(sc_bind(&Prim::Th, this, 1)),
sc_spawn(sc_bind(&Prim::Th, this, 2))
SC_JOIN
sc_spawn(sc_bind(&Prim::Th_ref, this, sc_ref(ref_arg)));
sc_spawn(sc_bind(&Prim::Th_cref, this, sc_cref(cref_arg)));
wait(1, SC_NS);
sc_assert(ref_arg == 99);
}
sc_event ev;
void Th(int i)
{
cout << "Th::i=" << i << endl;
}
void Th_ref(int& arg)
{
arg = 99;
sc_time t(sc_time_stamp());
sc_process_handle h = sc_spawn(&f);
wait(h.terminated_event());
sc_assert(sc_time_stamp() == t + sc_time(33, SC_PS));
}
void Th_cref(const int& arg)
{
}
int ref_arg;
const int cref_arg;
};
SC_MODULE(M)
{
Prim prim;
SC_CTOR(M)
{
SC_THREAD(T);
}
void T()
{
wait(10, SC_NS);
try {
sc_report_handler::set_actions("msg_type", SC_INFO, SC_THROW);
SC_REPORT_INFO("msg_type", "msg");
}
catch (sc_report& rpt) {
cout << "Caught rpt " << rpt.what() << endl;
sc_assert(rpt.get_severity() == SC_INFO);
sc_assert(std::string(rpt.get_msg_type()) == "msg_type");
sc_assert(std::string(rpt.get_msg()) == "msg");
sc_assert(rpt.get_time() == sc_time(10, SC_NS));
sc_assert(std::string(rpt.get_process_name()) == "top.m.T");
sc_assert(sc_report_handler::get_count(SC_INFO) == 1);
sc_report rpt2 = rpt; // Copy constructor
prim.write();
sc_spawn(sc_bind(&M::proc, this, &rpt2));
wait(100, SC_NS);
}
}
void proc(sc_report* rpt)
{
sc_assert(rpt->get_severity() == SC_INFO);
sc_assert(std::string(rpt->get_msg_type()) == "msg_type");
sc_assert(std::string(rpt->get_msg()) == "msg");
sc_assert(rpt->get_time() == sc_time(10, SC_NS));
sc_assert(std::string(rpt->get_process_name()) == "top.m.T");
rpt->get_file_name();
rpt->get_line_number();
}
};
struct CM: sc_module
{
sc_in_clk clk;
sc_in<bool> reset;
SC_HAS_PROCESS(CM);
CM(sc_module_name _name)
: first(true)
{
SC_CTHREAD(CT, clk.pos());
reset_signal_is(reset, true);
sc_assert(sc_start_of_simulation_invoked() == false);
sc_assert(sc_end_of_simulation_invoked() == false);
sc_assert(sc_is_running() == false);
}
bool first;
void CT()
{
if (first)
sc_assert(sc_time_stamp() == sc_time(5, SC_US));
else
sc_assert(sc_time_stamp() == sc_time(30, SC_US));
first = false;
sc_assert(sc_start_of_simulation_invoked() == true);
sc_assert(sc_end_of_simulation_invoked() == false);
sc_assert(sc_is_running() == true);
while(1)
{
wait();
sc_assert(sc_time_stamp() == sc_time(15, SC_US));
wait();
sc_assert(sc_time_stamp() == sc_time(25, SC_US));
wait();
sc_assert(false);
}
}
void start_of_simulation()
{
sc_assert(sc_start_of_simulation_invoked() == false);
sc_assert(sc_end_of_simulation_invoked() == false);
sc_assert(sc_is_running() == false);
}
void end_of_simulation()
{
sc_assert(sc_start_of_simulation_invoked() == true);
sc_assert(sc_end_of_simulation_invoked() == false);
sc_assert(sc_is_running() == false);
}
};
SC_MODULE(Top)
{
M *m;
CM *cm;
M_src m_src;
M_dest m_dest;
sc_signal<bool> clk, reset;
SC_CTOR(Top)
: m_src("m_src"), m_dest("m_dest")
{
m = new M("m");
cm = new CM("cm");
cm->clk(clk);
cm->reset(reset);
m_src.p->bind( *(m_dest.xp) ); // Port-export binding
SC_THREAD(T);
SC_THREAD(T2);
}
void T()
{
clk = false;
reset = true;
wait(5, SC_US);
clk = true;
wait(5, SC_US);
clk = false;
reset = false;
wait(5, SC_US);
clk = true;
wait(5, SC_US);
clk = false;
wait(5, SC_US);
clk = true;
wait(5, SC_US);
clk = false;
reset = true;
wait(10, SC_US);
}
void T2()
{
sc_assert(sc_min(-1,1) == -1);
sc_assert(sc_max(-1,1) == 1);
sc_assert(sc_abs(-1) == 1);
sc_assert(sc_min(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(-1));
sc_assert(sc_max(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(1));
sc_assert(sc_abs(sc_int<8>(-1)) == sc_int<8>(1));
sc_assert(sc_min(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(-1));
sc_assert(sc_max(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(1));
sc_assert(sc_abs(sc_bigint<256>(-1)) == sc_bigint<256>(1));
}
};
int sc_main(int argc, char* argv[])
{
sc_assert(sc_delta_count() == 0);
sc_assert(sc_is_running() == 0);
sc_assert(sc_time_stamp() == sc_time(SC_ZERO_TIME));
sc_assert(sc_report_handler::get_count(SC_INFO) == 0);
sc_assert(sc_report_handler::get_count("foo") == 0);
sc_actions act1 = sc_report_handler::get_new_action_id();
sc_actions act2 = sc_report_handler::get_new_action_id();
while (act2 != SC_UNSPECIFIED)
{
sc_assert(act2 != act1);
act2 = sc_report_handler::get_new_action_id();
}
sc_assert(sc_report_handler::get_log_file_name() == 0);
sc_assert(sc_get_top_level_objects().size() == 0);
sc_assert(sc_find_object("foo") == 0);
sc_assert(!sc_get_current_process_handle().valid());
sc_copyright();
sc_version();
std::string release = sc_release();
int n = release.find('.');
std::string major = release.substr(0,n);
release = release.substr(n+1,release.size()-1);
n = release.find('.');
std::string minor = release.substr(0,n);
release = release.substr(n+1,release.size()-1);
n = release.find('-');
std::string patch = release.substr(0,n);
std::string originator = release.substr(n+1,release.size());
std::string charset =
"abcdefghijklmnopqrstuvwxyzABSCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
for (unsigned int i = 0; i < major.size(); i++)
sc_assert(charset.find(major[i]) < charset.size());
for (unsigned int i = 0; i < minor.size(); i++)
sc_assert(charset.find(minor[i]) < charset.size());
for (unsigned int i = 0; i < patch.size(); i++)
sc_assert(charset.find(patch[i]) < charset.size());
for (unsigned int i = 0; i < originator.size(); i++)
sc_assert(charset.find(originator[i]) < charset.size());
Top top("top");
sc_start();
sc_stop();
sc_assert(sc_end_of_simulation_invoked() == true);
cout << endl << "Success" << endl;
return 0;
}