1 2// General tests combining features of SystemC 2.1 and 1666 3 4 5#define SC_INCLUDE_DYNAMIC_PROCESSES 6 7#include <systemc> 8using sc_core::sc_interface; 9using sc_core::sc_object; 10using sc_core::sc_port; 11using sc_core::sc_export; 12using sc_core::sc_module; 13using sc_core::sc_module_name; 14using sc_core::sc_in; 15using sc_core::sc_in_clk; 16using sc_core::sc_signal; 17using sc_core::sc_prim_channel; 18using sc_core::sc_event; 19using sc_core::sc_delta_count; 20using sc_core::sc_is_running; 21using sc_core::sc_get_top_level_objects; 22using sc_core::sc_find_object; 23using sc_core::sc_report; 24using sc_core::sc_report_handler; 25using sc_core::sc_actions; 26using sc_core::SC_INFO; 27using sc_core::SC_UNSPECIFIED; 28using sc_core::SC_THROW; 29using sc_core::sc_spawn; 30using sc_core::sc_process_handle; 31using sc_core::sc_get_current_process_handle; 32using sc_core::sc_time; 33using sc_core::sc_time_stamp; 34using sc_core::SC_ZERO_TIME; 35using sc_core::SC_PS; 36using sc_core::SC_NS; 37using sc_core::SC_US; 38using sc_core::sc_start_of_simulation_invoked; 39using sc_core::sc_end_of_simulation_invoked; 40using sc_core::sc_start; 41using sc_core::sc_stop; 42using sc_core::sc_copyright; 43using sc_core::sc_version; 44using sc_core::sc_release; 45using sc_dt::sc_abs; 46using sc_dt::sc_max; 47using sc_dt::sc_min; 48using sc_dt::sc_int; 49using sc_dt::sc_bigint; 50using std::cout; 51using std::endl; 52 53#if defined(IEEE_1666_CPLUSPLUS) && IEEE_1666_CPLUSPLUS >= 201103L 54// dynamic process macros have been moved to functions on C++11 55using sc_core::sc_bind; 56using sc_core::sc_ref; 57using sc_core::sc_cref; 58#endif // IEEE_1666_CPLUSPLUS 59 60struct i_f: virtual sc_interface 61{ 62 virtual void write() = 0; 63}; 64 65void check_form_of_suffix(std::string s) 66{ 67 std::string charset = "0123456789"; 68 while (!s.empty()) 69 { 70 sc_assert(s[0] == '_'); 71 s = s.substr(1); 72 sc_assert(!s.empty()); 73 do 74 { 75 sc_assert(charset.find(s[0]) < charset.size()); 76 s = s.substr(1); 77 } while (!s.empty() && (s[0] != '_')); 78 } 79} 80 81struct Chan: i_f, sc_object 82{ 83 virtual void write() 84 { 85 sc_assert(std::string(name()).substr(0,17) == "top.m_dest.object"); 86 check_form_of_suffix(std::string(name()).substr(17)); 87 } 88}; 89 90struct M_src: sc_core::sc_behavior 91{ 92 sc_port<i_f>* p; 93 SC_HAS_PROCESS(M_src); 94 95 M_src(sc_module_name _name) 96 { 97 p = new sc_port<i_f>; 98 99 SC_THREAD(T); 100 } 101 void T() 102 { 103 (*p)->write(); 104 } 105}; 106 107struct M_dest: sc_core::sc_channel 108{ 109 sc_export<i_f>* xp; 110 SC_HAS_PROCESS(M_dest); 111 112 M_dest(sc_module_name _name) 113 { 114 xp = new sc_export<i_f>; 115 Chan* ch = new Chan; 116 xp->bind(*ch); 117 } 118}; 119 120void f() 121{ 122 ::sc_core::wait(33, SC_PS); 123} 124 125struct Prim: sc_prim_channel 126{ 127 Prim() : cref_arg(1) {} 128 129 void write() { request_update(); } 130 131 void update() 132 { 133 sc_spawn(sc_bind(&Prim::proc, this)); 134 } 135 136 void proc() 137 { 138 ev.notify(SC_ZERO_TIME); 139 wait(ev); 140 cout << "Prim::Proc spawned and resumed" << endl; 141 SC_FORK 142 sc_spawn(sc_bind(&Prim::Th, this, 1)), 143 sc_spawn(sc_bind(&Prim::Th, this, 2)) 144 SC_JOIN 145 sc_spawn(sc_bind(&Prim::Th_ref, this, sc_ref(ref_arg))); 146 sc_spawn(sc_bind(&Prim::Th_cref, this, sc_cref(cref_arg))); 147 wait(1, SC_NS); 148 sc_assert(ref_arg == 99); 149 } 150 sc_event ev; 151 void Th(int i) 152 { 153 cout << "Th::i=" << i << endl; 154 } 155 void Th_ref(int& arg) 156 { 157 arg = 99; 158 sc_time t(sc_time_stamp()); 159 sc_process_handle h = sc_spawn(&f); 160 wait(h.terminated_event()); 161 sc_assert(sc_time_stamp() == t + sc_time(33, SC_PS)); 162 } 163 void Th_cref(const int& arg) 164 { 165 } 166 int ref_arg; 167 const int cref_arg; 168}; 169 170SC_MODULE(M) 171{ 172 Prim prim; 173 SC_CTOR(M) 174 { 175 SC_THREAD(T); 176 } 177 178 void T() 179 { 180 wait(10, SC_NS); 181 try { 182 sc_report_handler::set_actions("msg_type", SC_INFO, SC_THROW); 183 SC_REPORT_INFO("msg_type", "msg"); 184 } 185 catch (sc_report& rpt) { 186 cout << "Caught rpt " << rpt.what() << endl; 187 sc_assert(rpt.get_severity() == SC_INFO); 188 sc_assert(std::string(rpt.get_msg_type()) == "msg_type"); 189 sc_assert(std::string(rpt.get_msg()) == "msg"); 190 sc_assert(rpt.get_time() == sc_time(10, SC_NS)); 191 sc_assert(std::string(rpt.get_process_name()) == "top.m.T"); 192 193 sc_assert(sc_report_handler::get_count(SC_INFO) == 1); 194 sc_report rpt2 = rpt; // Copy constructor 195 196 prim.write(); 197 198 sc_spawn(sc_bind(&M::proc, this, &rpt2)); 199 wait(100, SC_NS); 200 } 201 } 202 void proc(sc_report* rpt) 203 { 204 sc_assert(rpt->get_severity() == SC_INFO); 205 sc_assert(std::string(rpt->get_msg_type()) == "msg_type"); 206 sc_assert(std::string(rpt->get_msg()) == "msg"); 207 sc_assert(rpt->get_time() == sc_time(10, SC_NS)); 208 sc_assert(std::string(rpt->get_process_name()) == "top.m.T"); 209 rpt->get_file_name(); 210 rpt->get_line_number(); 211 } 212}; 213 214struct CM: sc_module 215{ 216 sc_in_clk clk; 217 sc_in<bool> reset; 218 219 SC_HAS_PROCESS(CM); 220 221 CM(sc_module_name _name) 222 : first(true) 223 { 224 SC_CTHREAD(CT, clk.pos()); 225 reset_signal_is(reset, true); 226 227 sc_assert(sc_start_of_simulation_invoked() == false); 228 sc_assert(sc_end_of_simulation_invoked() == false); 229 sc_assert(sc_is_running() == false); 230 } 231 232 bool first; 233 234 void CT() 235 { 236 if (first) 237 sc_assert(sc_time_stamp() == sc_time(5, SC_US)); 238 else 239 sc_assert(sc_time_stamp() == sc_time(30, SC_US)); 240 first = false; 241 242 sc_assert(sc_start_of_simulation_invoked() == true); 243 sc_assert(sc_end_of_simulation_invoked() == false); 244 sc_assert(sc_is_running() == true); 245 246 while(1) 247 { 248 wait(); 249 sc_assert(sc_time_stamp() == sc_time(15, SC_US)); 250 wait(); 251 sc_assert(sc_time_stamp() == sc_time(25, SC_US)); 252 wait(); 253 sc_assert(false); 254 } 255 } 256 257 void start_of_simulation() 258 { 259 sc_assert(sc_start_of_simulation_invoked() == false); 260 sc_assert(sc_end_of_simulation_invoked() == false); 261 sc_assert(sc_is_running() == false); 262 } 263 264 void end_of_simulation() 265 { 266 sc_assert(sc_start_of_simulation_invoked() == true); 267 sc_assert(sc_end_of_simulation_invoked() == false); 268 sc_assert(sc_is_running() == false); 269 } 270}; 271 272SC_MODULE(Top) 273{ 274 M *m; 275 CM *cm; 276 277 M_src m_src; 278 M_dest m_dest; 279 280 sc_signal<bool> clk, reset; 281 282 SC_CTOR(Top) 283 : m_src("m_src"), m_dest("m_dest") 284 { 285 m = new M("m"); 286 cm = new CM("cm"); 287 cm->clk(clk); 288 cm->reset(reset); 289 290 m_src.p->bind( *(m_dest.xp) ); // Port-export binding 291 292 SC_THREAD(T); 293 SC_THREAD(T2); 294 } 295 void T() 296 { 297 clk = false; 298 reset = true; 299 wait(5, SC_US); 300 clk = true; 301 wait(5, SC_US); 302 clk = false; 303 reset = false; 304 wait(5, SC_US); 305 clk = true; 306 wait(5, SC_US); 307 clk = false; 308 wait(5, SC_US); 309 clk = true; 310 wait(5, SC_US); 311 clk = false; 312 reset = true; 313 wait(10, SC_US); 314 } 315 void T2() 316 { 317 sc_assert(sc_min(-1,1) == -1); 318 sc_assert(sc_max(-1,1) == 1); 319 sc_assert(sc_abs(-1) == 1); 320 321 sc_assert(sc_min(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(-1)); 322 sc_assert(sc_max(sc_int<8>(-1),sc_int<8>(1)) == sc_int<8>(1)); 323 sc_assert(sc_abs(sc_int<8>(-1)) == sc_int<8>(1)); 324 325 sc_assert(sc_min(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(-1)); 326 sc_assert(sc_max(sc_bigint<256>(-1),sc_bigint<256>(1)) == sc_bigint<256>(1)); 327 sc_assert(sc_abs(sc_bigint<256>(-1)) == sc_bigint<256>(1)); 328 } 329}; 330 331int sc_main(int argc, char* argv[]) 332{ 333 sc_assert(sc_delta_count() == 0); 334 sc_assert(sc_is_running() == 0); 335 sc_assert(sc_time_stamp() == sc_time(SC_ZERO_TIME)); 336 sc_assert(sc_report_handler::get_count(SC_INFO) == 0); 337 sc_assert(sc_report_handler::get_count("foo") == 0); 338 339 sc_actions act1 = sc_report_handler::get_new_action_id(); 340 sc_actions act2 = sc_report_handler::get_new_action_id(); 341 while (act2 != SC_UNSPECIFIED) 342 { 343 sc_assert(act2 != act1); 344 act2 = sc_report_handler::get_new_action_id(); 345 } 346 sc_assert(sc_report_handler::get_log_file_name() == 0); 347 sc_assert(sc_get_top_level_objects().size() == 0); 348 sc_assert(sc_find_object("foo") == 0); 349 sc_assert(!sc_get_current_process_handle().valid()); 350 351 sc_copyright(); 352 sc_version(); 353 std::string release = sc_release(); 354 int n = release.find('.'); 355 std::string major = release.substr(0,n); 356 release = release.substr(n+1,release.size()-1); 357 n = release.find('.'); 358 std::string minor = release.substr(0,n); 359 release = release.substr(n+1,release.size()-1); 360 n = release.find('-'); 361 std::string patch = release.substr(0,n); 362 std::string originator = release.substr(n+1,release.size()); 363 364 std::string charset = 365 "abcdefghijklmnopqrstuvwxyzABSCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; 366 367 for (unsigned int i = 0; i < major.size(); i++) 368 sc_assert(charset.find(major[i]) < charset.size()); 369 for (unsigned int i = 0; i < minor.size(); i++) 370 sc_assert(charset.find(minor[i]) < charset.size()); 371 for (unsigned int i = 0; i < patch.size(); i++) 372 sc_assert(charset.find(patch[i]) < charset.size()); 373 for (unsigned int i = 0; i < originator.size(); i++) 374 sc_assert(charset.find(originator[i]) < charset.size()); 375 376 Top top("top"); 377 sc_start(); 378 379 sc_stop(); 380 sc_assert(sc_end_of_simulation_invoked() == true); 381 382 cout << endl << "Success" << endl; 383 return 0; 384} 385