112855Sgabeblack@google.com 212855Sgabeblack@google.com// General tests combining features of SystemC 2.1 and 1666 312855Sgabeblack@google.com 412855Sgabeblack@google.com 512855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES 612855Sgabeblack@google.com 712855Sgabeblack@google.com#include <systemc> 812855Sgabeblack@google.comusing sc_core::sc_interface; 912855Sgabeblack@google.comusing sc_core::sc_object; 1012855Sgabeblack@google.comusing sc_core::sc_port; 1112855Sgabeblack@google.comusing sc_core::sc_export; 1212855Sgabeblack@google.comusing sc_core::sc_module; 1312855Sgabeblack@google.comusing sc_core::sc_module_name; 1412855Sgabeblack@google.comusing sc_core::sc_in; 1512855Sgabeblack@google.comusing sc_core::sc_in_clk; 1612855Sgabeblack@google.comusing sc_core::sc_signal; 1712855Sgabeblack@google.comusing sc_core::sc_prim_channel; 1812855Sgabeblack@google.comusing sc_core::sc_event; 1912855Sgabeblack@google.comusing sc_core::sc_delta_count; 2012855Sgabeblack@google.comusing sc_core::sc_is_running; 2112855Sgabeblack@google.comusing sc_core::sc_get_top_level_objects; 2212855Sgabeblack@google.comusing sc_core::sc_find_object; 2312855Sgabeblack@google.comusing sc_core::sc_report; 2412855Sgabeblack@google.comusing sc_core::sc_report_handler; 2512855Sgabeblack@google.comusing sc_core::sc_actions; 2612855Sgabeblack@google.comusing sc_core::SC_INFO; 2712855Sgabeblack@google.comusing sc_core::SC_UNSPECIFIED; 2812855Sgabeblack@google.comusing sc_core::SC_THROW; 2912855Sgabeblack@google.comusing sc_core::sc_spawn; 3012855Sgabeblack@google.comusing sc_core::sc_process_handle; 3112855Sgabeblack@google.comusing sc_core::sc_get_current_process_handle; 3212855Sgabeblack@google.comusing sc_core::sc_time; 3312855Sgabeblack@google.comusing sc_core::sc_time_stamp; 3412855Sgabeblack@google.comusing sc_core::SC_ZERO_TIME; 3512855Sgabeblack@google.comusing sc_core::SC_PS; 3612855Sgabeblack@google.comusing sc_core::SC_NS; 3712855Sgabeblack@google.comusing sc_core::SC_US; 3812855Sgabeblack@google.comusing sc_core::sc_start_of_simulation_invoked; 3912855Sgabeblack@google.comusing sc_core::sc_end_of_simulation_invoked; 4012855Sgabeblack@google.comusing sc_core::sc_start; 4112855Sgabeblack@google.comusing sc_core::sc_stop; 4212855Sgabeblack@google.comusing sc_core::sc_copyright; 4312855Sgabeblack@google.comusing sc_core::sc_version; 4412855Sgabeblack@google.comusing sc_core::sc_release; 4512855Sgabeblack@google.comusing sc_dt::sc_abs; 4612855Sgabeblack@google.comusing sc_dt::sc_max; 4712855Sgabeblack@google.comusing sc_dt::sc_min; 4812855Sgabeblack@google.comusing sc_dt::sc_int; 4912855Sgabeblack@google.comusing sc_dt::sc_bigint; 5012855Sgabeblack@google.comusing std::cout; 5112855Sgabeblack@google.comusing std::endl; 5212855Sgabeblack@google.com 5312855Sgabeblack@google.com#if defined(IEEE_1666_CPLUSPLUS) && IEEE_1666_CPLUSPLUS >= 201103L 5412855Sgabeblack@google.com// dynamic process macros have been moved to functions on C++11 5512855Sgabeblack@google.comusing sc_core::sc_bind; 5612855Sgabeblack@google.comusing sc_core::sc_ref; 5712855Sgabeblack@google.comusing sc_core::sc_cref; 5812855Sgabeblack@google.com#endif // IEEE_1666_CPLUSPLUS 5912855Sgabeblack@google.com 6012855Sgabeblack@google.comstruct i_f: virtual sc_interface 6112855Sgabeblack@google.com{ 6212855Sgabeblack@google.com virtual void write() = 0; 6312855Sgabeblack@google.com}; 6412855Sgabeblack@google.com 6512855Sgabeblack@google.comvoid check_form_of_suffix(std::string s) 6612855Sgabeblack@google.com{ 6712855Sgabeblack@google.com std::string charset = "0123456789"; 6812855Sgabeblack@google.com while (!s.empty()) 6912855Sgabeblack@google.com { 7012855Sgabeblack@google.com sc_assert(s[0] == '_'); 7112855Sgabeblack@google.com s = s.substr(1); 7212855Sgabeblack@google.com sc_assert(!s.empty()); 7312855Sgabeblack@google.com do 7412855Sgabeblack@google.com { 7512855Sgabeblack@google.com sc_assert(charset.find(s[0]) < charset.size()); 7612855Sgabeblack@google.com s = s.substr(1); 7712855Sgabeblack@google.com } while (!s.empty() && (s[0] != '_')); 7812855Sgabeblack@google.com } 7912855Sgabeblack@google.com} 8012855Sgabeblack@google.com 8112855Sgabeblack@google.comstruct Chan: i_f, sc_object 8212855Sgabeblack@google.com{ 8312855Sgabeblack@google.com virtual void write() 8412855Sgabeblack@google.com { 8512855Sgabeblack@google.com sc_assert(std::string(name()).substr(0,17) == "top.m_dest.object"); 8612855Sgabeblack@google.com check_form_of_suffix(std::string(name()).substr(17)); 8712855Sgabeblack@google.com } 8812855Sgabeblack@google.com}; 8912855Sgabeblack@google.com 9012855Sgabeblack@google.comstruct M_src: sc_core::sc_behavior 9112855Sgabeblack@google.com{ 9212855Sgabeblack@google.com sc_port<i_f>* p; 9312855Sgabeblack@google.com SC_HAS_PROCESS(M_src); 9412855Sgabeblack@google.com 9512855Sgabeblack@google.com M_src(sc_module_name _name) 9612855Sgabeblack@google.com { 9712855Sgabeblack@google.com p = new sc_port<i_f>; 9812855Sgabeblack@google.com 9912855Sgabeblack@google.com SC_THREAD(T); 10012855Sgabeblack@google.com } 10112855Sgabeblack@google.com void T() 10212855Sgabeblack@google.com { 10312855Sgabeblack@google.com (*p)->write(); 10412855Sgabeblack@google.com } 10512855Sgabeblack@google.com}; 10612855Sgabeblack@google.com 10712855Sgabeblack@google.comstruct M_dest: sc_core::sc_channel 10812855Sgabeblack@google.com{ 10912855Sgabeblack@google.com sc_export<i_f>* xp; 11012855Sgabeblack@google.com SC_HAS_PROCESS(M_dest); 11112855Sgabeblack@google.com 11212855Sgabeblack@google.com M_dest(sc_module_name _name) 11312855Sgabeblack@google.com { 11412855Sgabeblack@google.com xp = new sc_export<i_f>; 11512855Sgabeblack@google.com Chan* ch = new Chan; 11612855Sgabeblack@google.com xp->bind(*ch); 11712855Sgabeblack@google.com } 11812855Sgabeblack@google.com}; 11912855Sgabeblack@google.com 12012855Sgabeblack@google.comvoid f() 12112855Sgabeblack@google.com{ 12212855Sgabeblack@google.com ::sc_core::wait(33, SC_PS); 12312855Sgabeblack@google.com} 12412855Sgabeblack@google.com 12512855Sgabeblack@google.comstruct Prim: sc_prim_channel 12612855Sgabeblack@google.com{ 12712855Sgabeblack@google.com Prim() : cref_arg(1) {} 12812855Sgabeblack@google.com 12912855Sgabeblack@google.com void write() { request_update(); } 13012855Sgabeblack@google.com 13112855Sgabeblack@google.com void update() 13212855Sgabeblack@google.com { 13312855Sgabeblack@google.com sc_spawn(sc_bind(&Prim::proc, this)); 13412855Sgabeblack@google.com } 13512855Sgabeblack@google.com 13612855Sgabeblack@google.com void proc() 13712855Sgabeblack@google.com { 13812855Sgabeblack@google.com ev.notify(SC_ZERO_TIME); 13912855Sgabeblack@google.com wait(ev); 14012855Sgabeblack@google.com cout << "Prim::Proc spawned and resumed" << endl; 14112855Sgabeblack@google.com SC_FORK 14212855Sgabeblack@google.com sc_spawn(sc_bind(&Prim::Th, this, 1)), 14312855Sgabeblack@google.com sc_spawn(sc_bind(&Prim::Th, this, 2)) 14412855Sgabeblack@google.com SC_JOIN 14512855Sgabeblack@google.com sc_spawn(sc_bind(&Prim::Th_ref, this, sc_ref(ref_arg))); 14612855Sgabeblack@google.com sc_spawn(sc_bind(&Prim::Th_cref, this, sc_cref(cref_arg))); 14712855Sgabeblack@google.com wait(1, SC_NS); 14812855Sgabeblack@google.com sc_assert(ref_arg == 99); 14912855Sgabeblack@google.com } 15012855Sgabeblack@google.com sc_event ev; 15112855Sgabeblack@google.com void Th(int i) 15212855Sgabeblack@google.com { 15312855Sgabeblack@google.com cout << "Th::i=" << i << endl; 15412855Sgabeblack@google.com } 15512855Sgabeblack@google.com void Th_ref(int& arg) 15612855Sgabeblack@google.com { 15712855Sgabeblack@google.com arg = 99; 15812855Sgabeblack@google.com sc_time t(sc_time_stamp()); 15912855Sgabeblack@google.com sc_process_handle h = sc_spawn(&f); 16012855Sgabeblack@google.com wait(h.terminated_event()); 16112855Sgabeblack@google.com sc_assert(sc_time_stamp() == t + sc_time(33, SC_PS)); 16212855Sgabeblack@google.com } 16312855Sgabeblack@google.com void Th_cref(const int& arg) 16412855Sgabeblack@google.com { 16512855Sgabeblack@google.com } 16612855Sgabeblack@google.com int ref_arg; 16712855Sgabeblack@google.com const int cref_arg; 16812855Sgabeblack@google.com}; 16912855Sgabeblack@google.com 17012855Sgabeblack@google.comSC_MODULE(M) 17112855Sgabeblack@google.com{ 17212855Sgabeblack@google.com Prim prim; 17312855Sgabeblack@google.com SC_CTOR(M) 17412855Sgabeblack@google.com { 17512855Sgabeblack@google.com SC_THREAD(T); 17612855Sgabeblack@google.com } 17712855Sgabeblack@google.com 17812855Sgabeblack@google.com void T() 17912855Sgabeblack@google.com { 18012855Sgabeblack@google.com wait(10, SC_NS); 18112855Sgabeblack@google.com try { 18212855Sgabeblack@google.com sc_report_handler::set_actions("msg_type", SC_INFO, SC_THROW); 18312855Sgabeblack@google.com SC_REPORT_INFO("msg_type", "msg"); 18412855Sgabeblack@google.com } 18512855Sgabeblack@google.com catch (sc_report& rpt) { 18612855Sgabeblack@google.com cout << "Caught rpt " << rpt.what() << endl; 18712855Sgabeblack@google.com sc_assert(rpt.get_severity() == SC_INFO); 18812855Sgabeblack@google.com sc_assert(std::string(rpt.get_msg_type()) == "msg_type"); 18912855Sgabeblack@google.com sc_assert(std::string(rpt.get_msg()) == "msg"); 19012855Sgabeblack@google.com sc_assert(rpt.get_time() == sc_time(10, SC_NS)); 19112855Sgabeblack@google.com sc_assert(std::string(rpt.get_process_name()) == "top.m.T"); 19212855Sgabeblack@google.com 19312855Sgabeblack@google.com sc_assert(sc_report_handler::get_count(SC_INFO) == 1); 19412855Sgabeblack@google.com sc_report rpt2 = rpt; // Copy constructor 19512855Sgabeblack@google.com 19612855Sgabeblack@google.com prim.write(); 19712855Sgabeblack@google.com 19812855Sgabeblack@google.com sc_spawn(sc_bind(&M::proc, this, &rpt2)); 19912855Sgabeblack@google.com wait(100, SC_NS); 20012855Sgabeblack@google.com } 20112855Sgabeblack@google.com } 20212855Sgabeblack@google.com void proc(sc_report* rpt) 20312855Sgabeblack@google.com { 20412855Sgabeblack@google.com sc_assert(rpt->get_severity() == SC_INFO); 20512855Sgabeblack@google.com sc_assert(std::string(rpt->get_msg_type()) == "msg_type"); 20612855Sgabeblack@google.com sc_assert(std::string(rpt->get_msg()) == "msg"); 20712855Sgabeblack@google.com sc_assert(rpt->get_time() == sc_time(10, SC_NS)); 20812855Sgabeblack@google.com sc_assert(std::string(rpt->get_process_name()) == "top.m.T"); 20912855Sgabeblack@google.com rpt->get_file_name(); 21012855Sgabeblack@google.com rpt->get_line_number(); 21112855Sgabeblack@google.com } 21212855Sgabeblack@google.com}; 21312855Sgabeblack@google.com 21412855Sgabeblack@google.comstruct CM: sc_module 21512855Sgabeblack@google.com{ 21612855Sgabeblack@google.com sc_in_clk clk; 21712855Sgabeblack@google.com sc_in<bool> reset; 21812855Sgabeblack@google.com 21912855Sgabeblack@google.com SC_HAS_PROCESS(CM); 22012855Sgabeblack@google.com 22112855Sgabeblack@google.com CM(sc_module_name _name) 22212855Sgabeblack@google.com : first(true) 22312855Sgabeblack@google.com { 22412855Sgabeblack@google.com SC_CTHREAD(CT, clk.pos()); 22512855Sgabeblack@google.com reset_signal_is(reset, true); 22612855Sgabeblack@google.com 22712855Sgabeblack@google.com sc_assert(sc_start_of_simulation_invoked() == false); 22812855Sgabeblack@google.com sc_assert(sc_end_of_simulation_invoked() == false); 22912855Sgabeblack@google.com sc_assert(sc_is_running() == false); 23012855Sgabeblack@google.com } 23112855Sgabeblack@google.com 23212855Sgabeblack@google.com bool first; 23312855Sgabeblack@google.com 23412855Sgabeblack@google.com void CT() 23512855Sgabeblack@google.com { 23612855Sgabeblack@google.com if (first) 23712855Sgabeblack@google.com sc_assert(sc_time_stamp() == sc_time(5, SC_US)); 23812855Sgabeblack@google.com else 23912855Sgabeblack@google.com sc_assert(sc_time_stamp() == sc_time(30, SC_US)); 24012855Sgabeblack@google.com first = false; 24112855Sgabeblack@google.com 24212855Sgabeblack@google.com sc_assert(sc_start_of_simulation_invoked() == true); 24312855Sgabeblack@google.com sc_assert(sc_end_of_simulation_invoked() == false); 24412855Sgabeblack@google.com sc_assert(sc_is_running() == true); 24512855Sgabeblack@google.com 24612855Sgabeblack@google.com while(1) 24712855Sgabeblack@google.com { 24812855Sgabeblack@google.com wait(); 24912855Sgabeblack@google.com sc_assert(sc_time_stamp() == sc_time(15, SC_US)); 25012855Sgabeblack@google.com wait(); 25112855Sgabeblack@google.com sc_assert(sc_time_stamp() == sc_time(25, SC_US)); 25212855Sgabeblack@google.com wait(); 25312855Sgabeblack@google.com sc_assert(false); 25412855Sgabeblack@google.com } 25512855Sgabeblack@google.com } 25612855Sgabeblack@google.com 25712855Sgabeblack@google.com void start_of_simulation() 25812855Sgabeblack@google.com { 25912855Sgabeblack@google.com sc_assert(sc_start_of_simulation_invoked() == false); 26012855Sgabeblack@google.com sc_assert(sc_end_of_simulation_invoked() == false); 26112855Sgabeblack@google.com sc_assert(sc_is_running() == false); 26212855Sgabeblack@google.com } 26312855Sgabeblack@google.com 26412855Sgabeblack@google.com void end_of_simulation() 26512855Sgabeblack@google.com { 26612855Sgabeblack@google.com sc_assert(sc_start_of_simulation_invoked() == true); 26712855Sgabeblack@google.com sc_assert(sc_end_of_simulation_invoked() == false); 26812855Sgabeblack@google.com sc_assert(sc_is_running() == false); 26912855Sgabeblack@google.com } 27012855Sgabeblack@google.com}; 27112855Sgabeblack@google.com 27212855Sgabeblack@google.comSC_MODULE(Top) 27312855Sgabeblack@google.com{ 27412855Sgabeblack@google.com M *m; 27512855Sgabeblack@google.com CM *cm; 27612855Sgabeblack@google.com 27712855Sgabeblack@google.com M_src m_src; 27812855Sgabeblack@google.com M_dest m_dest; 27912855Sgabeblack@google.com 28012855Sgabeblack@google.com sc_signal<bool> clk, reset; 28112855Sgabeblack@google.com 28212855Sgabeblack@google.com SC_CTOR(Top) 28312855Sgabeblack@google.com : m_src("m_src"), m_dest("m_dest") 28412855Sgabeblack@google.com { 28512855Sgabeblack@google.com m = new M("m"); 28612855Sgabeblack@google.com cm = new CM("cm"); 28712855Sgabeblack@google.com cm->clk(clk); 28812855Sgabeblack@google.com cm->reset(reset); 28912855Sgabeblack@google.com 29012855Sgabeblack@google.com m_src.p->bind( *(m_dest.xp) ); // Port-export binding 29112855Sgabeblack@google.com 29212855Sgabeblack@google.com SC_THREAD(T); 29312855Sgabeblack@google.com SC_THREAD(T2); 29412855Sgabeblack@google.com } 29512855Sgabeblack@google.com void T() 29612855Sgabeblack@google.com { 29712855Sgabeblack@google.com clk = false; 29812855Sgabeblack@google.com reset = true; 29912855Sgabeblack@google.com wait(5, SC_US); 30012855Sgabeblack@google.com clk = true; 30112855Sgabeblack@google.com wait(5, SC_US); 30212855Sgabeblack@google.com clk = false; 30312855Sgabeblack@google.com reset = false; 30412855Sgabeblack@google.com wait(5, SC_US); 30512855Sgabeblack@google.com clk = true; 30612855Sgabeblack@google.com wait(5, SC_US); 30712855Sgabeblack@google.com clk = false; 30812855Sgabeblack@google.com wait(5, SC_US); 30912855Sgabeblack@google.com clk = true; 31012855Sgabeblack@google.com wait(5, SC_US); 31112855Sgabeblack@google.com clk = false; 31212855Sgabeblack@google.com reset = true; 31312855Sgabeblack@google.com wait(10, SC_US); 31412855Sgabeblack@google.com } 31512855Sgabeblack@google.com void T2() 31612855Sgabeblack@google.com { 31712855Sgabeblack@google.com sc_assert(sc_min(-1,1) == -1); 31812855Sgabeblack@google.com sc_assert(sc_max(-1,1) == 1); 31912855Sgabeblack@google.com sc_assert(sc_abs(-1) == 1); 32012855Sgabeblack@google.com 32112855Sgabeblack@google.com sc_assert(sc_min(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(-1)); 32212855Sgabeblack@google.com sc_assert(sc_max(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(1)); 32312855Sgabeblack@google.com sc_assert(sc_abs(sc_int<8>(-1)) == sc_int<8>(1)); 32412855Sgabeblack@google.com 32512855Sgabeblack@google.com sc_assert(sc_min(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(-1)); 32612855Sgabeblack@google.com sc_assert(sc_max(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(1)); 32712855Sgabeblack@google.com sc_assert(sc_abs(sc_bigint<256>(-1)) == sc_bigint<256>(1)); 32812855Sgabeblack@google.com } 32912855Sgabeblack@google.com}; 33012855Sgabeblack@google.com 33112855Sgabeblack@google.comint sc_main(int argc, char* argv[]) 33212855Sgabeblack@google.com{ 33312855Sgabeblack@google.com sc_assert(sc_delta_count() == 0); 33412855Sgabeblack@google.com sc_assert(sc_is_running() == 0); 33512855Sgabeblack@google.com sc_assert(sc_time_stamp() == sc_time(SC_ZERO_TIME)); 33612855Sgabeblack@google.com sc_assert(sc_report_handler::get_count(SC_INFO) == 0); 33712855Sgabeblack@google.com sc_assert(sc_report_handler::get_count("foo") == 0); 33812855Sgabeblack@google.com 33912855Sgabeblack@google.com sc_actions act1 = sc_report_handler::get_new_action_id(); 34012855Sgabeblack@google.com sc_actions act2 = sc_report_handler::get_new_action_id(); 34112855Sgabeblack@google.com while (act2 != SC_UNSPECIFIED) 34212855Sgabeblack@google.com { 34312855Sgabeblack@google.com sc_assert(act2 != act1); 34412855Sgabeblack@google.com act2 = sc_report_handler::get_new_action_id(); 34512855Sgabeblack@google.com } 34612855Sgabeblack@google.com sc_assert(sc_report_handler::get_log_file_name() == 0); 34712855Sgabeblack@google.com sc_assert(sc_get_top_level_objects().size() == 0); 34812855Sgabeblack@google.com sc_assert(sc_find_object("foo") == 0); 34912855Sgabeblack@google.com sc_assert(!sc_get_current_process_handle().valid()); 35012855Sgabeblack@google.com 35112855Sgabeblack@google.com sc_copyright(); 35212855Sgabeblack@google.com sc_version(); 35312855Sgabeblack@google.com std::string release = sc_release(); 35412855Sgabeblack@google.com int n = release.find('.'); 35512855Sgabeblack@google.com std::string major = release.substr(0,n); 35612855Sgabeblack@google.com release = release.substr(n+1,release.size()-1); 35712855Sgabeblack@google.com n = release.find('.'); 35812855Sgabeblack@google.com std::string minor = release.substr(0,n); 35912855Sgabeblack@google.com release = release.substr(n+1,release.size()-1); 36012855Sgabeblack@google.com n = release.find('-'); 36112855Sgabeblack@google.com std::string patch = release.substr(0,n); 36212855Sgabeblack@google.com std::string originator = release.substr(n+1,release.size()); 36312855Sgabeblack@google.com 36412855Sgabeblack@google.com std::string charset = 36512855Sgabeblack@google.com "abcdefghijklmnopqrstuvwxyzABSCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; 36612855Sgabeblack@google.com 36712855Sgabeblack@google.com for (unsigned int i = 0; i < major.size(); i++) 36812855Sgabeblack@google.com sc_assert(charset.find(major[i]) < charset.size()); 36912855Sgabeblack@google.com for (unsigned int i = 0; i < minor.size(); i++) 37012855Sgabeblack@google.com sc_assert(charset.find(minor[i]) < charset.size()); 37112855Sgabeblack@google.com for (unsigned int i = 0; i < patch.size(); i++) 37212855Sgabeblack@google.com sc_assert(charset.find(patch[i]) < charset.size()); 37312855Sgabeblack@google.com for (unsigned int i = 0; i < originator.size(); i++) 37412855Sgabeblack@google.com sc_assert(charset.find(originator[i]) < charset.size()); 37512855Sgabeblack@google.com 37612855Sgabeblack@google.com Top top("top"); 37712855Sgabeblack@google.com sc_start(); 37812855Sgabeblack@google.com 37912855Sgabeblack@google.com sc_stop(); 38012855Sgabeblack@google.com sc_assert(sc_end_of_simulation_invoked() == true); 38112855Sgabeblack@google.com 38212855Sgabeblack@google.com cout << endl << "Success" << endl; 38312855Sgabeblack@google.com return 0; 38412855Sgabeblack@google.com} 385