#include // Tests for 2.0.1 extended coding styles, illustrating that SystemC is a class library, not a syntax static int global_count = 0; SC_MODULE(Mod) { SC_CTOR(Mod) { sc_assert(std::string(this->kind()) == "sc_module"); } }; SC_MODULE(Mod0) { SC_CTOR(Mod0) { sc_assert(std::string(basename()) == "mod0"); SC_METHOD(method); dont_initialize(); method(); //// Calling an SC_METHOD member function directly DOULOS009 for (int i = 0; i < 3; i++) { SC_THREAD(thread); //// Registering the same function multiple times DOULOS046 //// Get warnings re-defining sc_object names, multiple threads created } SC_THREAD(thread); SC_THREAD(thread); //// Compile-time error - 'threadhandle' redefinition f(); } void method(void) { sc_assert(sc_get_current_process_handle().proc_kind() == SC_METHOD_PROC_); ++ global_count; } void thread(void) { sc_assert(sc_get_current_process_handle().proc_kind() == SC_THREAD_PROC_); ++ global_count; } void f() { SC_THREAD(g); } //// Process registered in member function called from constructor DOULOS007 void g() { sc_assert(std::string(sc_get_current_process_handle().name()) == "top.mod0.g"); ++ global_count; } }; struct Chan //// Pseudo-channel used for port-less interprocess communication //// but not derived from sc_module, sc_prim_channel or sc_interface DOULOS048 { void write(int i) { wait(10, SC_NS); data = i; e.notify(); } void read(int& i) { wait(e); i = data; } int data; bool wr, re; sc_event e; }; struct MyMod: Mod //// Class derived from an SC_MODULE DOULOS050 { sc_in p; MyMod(sc_module_name n) : Mod(n) { SC_THREAD(p1); SC_THREAD(p2); } Chan ch; //// Instance of pseudo-channel DOULOS048 void p1() { ch.write(333); } void p2() { int i; ch.read(i); sc_assert(i == 333); } SC_HAS_PROCESS(MyMod); }; struct C0: sc_module, virtual sc_interface //// Combining channel and interface in one class DOULOS015 { void write(int i) { data = i; } void read(int& i) { i = data; } int data; SC_CTOR(C0) { SC_THREAD(action); } void action() { sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "action"); } }; struct C1: virtual public sc_interface //// Combining channel and interface in one class DOULOS015 { void write(int i) { data = i; } void read(int& i) { i = data; } int data; }; struct I_F: virtual public sc_interface { virtual void method() = 0; }; struct C2: I_F //// Channel derived from neither sc_module nor sc_prim_channel DOULOS049 { void method() {} }; struct C3: sc_object, I_F //// Channel derived from sc_object only //// (and derived from neither sc_module nor sc_prim_channel) DOULOS049 { void method() {} }; 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 Modtype: sc_module { Modtype(sc_module_name n = sc_gen_unique_name("Modtype")) { if (global_count == 0) sc_assert(std::string(basename()) == "mt"); else { std::string s = std::string(basename()); sc_assert(s.substr(0,7) == "Modtype"); sc_assert(s.size() > 7); check_form_of_suffix(s.substr(7)); } ++ global_count; } void dump() { sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "thread"); ++ global_count; } }; typedef sc_signal MS; //// Pointer-to-module used as the type of a signal DOULOS051 template struct S { T t; }; SC_MODULE(Moda) { sc_port p0; sc_port p1; sc_port p2; sc_port p3; sc_port p4; Modtype mt; SC_CTOR(Moda): mt("mt") { sc_assert(std::string(name()) == "top.moda"); SC_THREAD(thread); } void thread(); }; SC_MODULE(Modb) { sc_port p0; sc_port p1; sc_port p2; sc_port p3; sc_port p4; SC_CTOR(Modb) { sc_assert(std::string(name()) == "top.modb"); SC_THREAD(thread); SC_THREAD(funny); } void thread(); void funny(); }; void Moda::thread() { p1->write(999); p2->method(); p3->method(); p4->write(&mt); } void Modb::thread() { wait(SC_ZERO_TIME); int i; p1->read(i); sc_assert(i == 999); p2->method(); p3->method(); wait(SC_ZERO_TIME); (p4->read())->dump(); } void Modb::funny() { C1 c1; C2 c2; C3 c3; } struct Link { Link *link; sc_module *m; //// Pointer-to-module DOULOS006 sc_signal *s; //// Pointer-to-signal sc_in *p; //// Pointer-to-port DOULOS008 }; SC_MODULE(Top) { SC_MODULE(Nested) //// Nested modules DOULOS005 { sc_in *pp; //// Pointer-to-port DOULOS008 SC_CTOR(Nested) { SC_METHOD(action); pp = new sc_in; //// Dynamic port instantiation DOULOS008 sensitive << *pp; //// Sensitivity separated from SC_METHOD DOULOS011 } void action() { op = sc_min(3, (*pp).read() + 1); } sc_out op; //// Out-of-order declaration DOULOS052 }; Nested n; Link* link; sc_signal b; sc_signal *sig; //// Pointer-to-signal MyMod mymod; Moda moda; Modb modb; C0 c0; C1 c1; C2 c2; C3 c3; S Sm; //// Using sc_module as a template parameter DOULOS051 MS ms; //// Pointer-to-module used as the type of a signal DOULOS051 Mod0 mod0; SC_CTOR(Top) : n("n"), mymod("mymod"), moda("moda"), modb("modb"), c0("c0"), mod0("mod0") { link = new Link; link->m = new Mod("mod_1"); link->p = new sc_in; link->link = new Link; link->link->m = new Mod("mod_2"); //// Buried dynamic module instantiation DOULOS002 link->link->s = new sc_signal;//// Buried dynamic channel instantiation link->link->p = new sc_in; //// Buried dynamic port instantiation DOULOS008 sig = new sc_signal; //// Dynamic channel instantiation n.op(*sig); (*(n.pp)).bind(*sig); //// Binding dynamically allocated port DOULOS008 mymod.p(b); moda.p0(c0); moda.p1(c1); moda.p2(c2); moda.p3(c3); moda.p4(ms); modb.p0(c0); modb.p1(c1); modb.p2(c2); modb.p3(c3); modb.p4(ms); } }; int sc_main(int argc, char* argv[]) { cout << "Should be silent except for some renaming warnings..." << endl; sc_signal s; Top top("top"); top.link->p->bind(s); top.link->link->p->bind(s); //// Binding dynamically allocated port DOULOS008 sc_start(); sc_assert(global_count == 10); sc_assert(top.sig->read() == 3); cout << endl << "Success" << endl; return 0; }