112855Sgabeblack@google.com
212855Sgabeblack@google.com#include <systemc.h>
312855Sgabeblack@google.com
412855Sgabeblack@google.com// Tests for 2.0.1 extended coding styles, illustrating that SystemC is a class library, not a syntax
512855Sgabeblack@google.com
612855Sgabeblack@google.comstatic int global_count = 0;
712855Sgabeblack@google.com
812855Sgabeblack@google.comSC_MODULE(Mod)
912855Sgabeblack@google.com{
1012855Sgabeblack@google.com  SC_CTOR(Mod)
1112855Sgabeblack@google.com  {
1212855Sgabeblack@google.com    sc_assert(std::string(this->kind()) == "sc_module");
1312855Sgabeblack@google.com  }
1412855Sgabeblack@google.com};
1512855Sgabeblack@google.com
1612855Sgabeblack@google.com
1712855Sgabeblack@google.com
1812855Sgabeblack@google.comSC_MODULE(Mod0)
1912855Sgabeblack@google.com{
2012855Sgabeblack@google.com  SC_CTOR(Mod0)
2112855Sgabeblack@google.com  {
2212855Sgabeblack@google.com    sc_assert(std::string(basename()) == "mod0");
2312855Sgabeblack@google.com    SC_METHOD(method);
2412855Sgabeblack@google.com    dont_initialize();
2512855Sgabeblack@google.com    method();             //// Calling an SC_METHOD member function directly DOULOS009
2612855Sgabeblack@google.com
2712855Sgabeblack@google.com    for (int i = 0; i < 3; i++)
2812855Sgabeblack@google.com    {
2912855Sgabeblack@google.com      SC_THREAD(thread);  //// Registering the same function multiple times DOULOS046
3012855Sgabeblack@google.com                          //// Get warnings re-defining sc_object names, multiple threads created
3112855Sgabeblack@google.com    }
3212855Sgabeblack@google.com    SC_THREAD(thread);
3312855Sgabeblack@google.com    SC_THREAD(thread);  //// Compile-time error - 'threadhandle' redefinition
3412855Sgabeblack@google.com
3512855Sgabeblack@google.com    f();
3612855Sgabeblack@google.com  }
3712855Sgabeblack@google.com  void method(void) {
3812855Sgabeblack@google.com    sc_assert(sc_get_current_process_handle().proc_kind() == SC_METHOD_PROC_);
3912855Sgabeblack@google.com  ++ global_count;
4012855Sgabeblack@google.com  }
4112855Sgabeblack@google.com  void thread(void) {
4212855Sgabeblack@google.com  sc_assert(sc_get_current_process_handle().proc_kind() == SC_THREAD_PROC_);
4312855Sgabeblack@google.com  ++ global_count;
4412855Sgabeblack@google.com  }
4512855Sgabeblack@google.com
4612855Sgabeblack@google.com  void f() { SC_THREAD(g); } //// Process registered in member function called from constructor DOULOS007
4712855Sgabeblack@google.com  void g()
4812855Sgabeblack@google.com  {
4912855Sgabeblack@google.com    sc_assert(std::string(sc_get_current_process_handle().name()) == "top.mod0.g");
5012855Sgabeblack@google.com  ++ global_count;
5112855Sgabeblack@google.com  }
5212855Sgabeblack@google.com};
5312855Sgabeblack@google.com
5412855Sgabeblack@google.com
5512855Sgabeblack@google.comstruct Chan               //// Pseudo-channel used for port-less interprocess communication
5612855Sgabeblack@google.com                          //// but not derived from sc_module, sc_prim_channel or sc_interface DOULOS048
5712855Sgabeblack@google.com{
5812855Sgabeblack@google.com  void write(int i) { wait(10, SC_NS); data = i; e.notify(); }
5912855Sgabeblack@google.com  void read(int& i) { wait(e); i = data; }
6012855Sgabeblack@google.com  int data;
6112855Sgabeblack@google.com  bool wr, re;
6212855Sgabeblack@google.com  sc_event e;
6312855Sgabeblack@google.com};
6412855Sgabeblack@google.com
6512855Sgabeblack@google.comstruct MyMod: Mod         //// Class derived from an SC_MODULE DOULOS050
6612855Sgabeblack@google.com{
6712855Sgabeblack@google.com  sc_in<bool> p;
6812855Sgabeblack@google.com
6912855Sgabeblack@google.com  MyMod(sc_module_name n)
7012855Sgabeblack@google.com  : Mod(n)
7112855Sgabeblack@google.com  {
7212855Sgabeblack@google.com    SC_THREAD(p1);
7312855Sgabeblack@google.com    SC_THREAD(p2);
7412855Sgabeblack@google.com  }
7512855Sgabeblack@google.com
7612855Sgabeblack@google.com  Chan ch;                //// Instance of pseudo-channel DOULOS048
7712855Sgabeblack@google.com  void p1() { ch.write(333); }
7812855Sgabeblack@google.com  void p2() { int i; ch.read(i); sc_assert(i == 333); }
7912855Sgabeblack@google.com
8012855Sgabeblack@google.com  SC_HAS_PROCESS(MyMod);
8112855Sgabeblack@google.com};
8212855Sgabeblack@google.com
8312855Sgabeblack@google.com
8412855Sgabeblack@google.com
8512855Sgabeblack@google.comstruct C0: sc_module, virtual sc_interface //// Combining channel and interface in one class DOULOS015
8612855Sgabeblack@google.com{
8712855Sgabeblack@google.com  void write(int i) { data = i; }
8812855Sgabeblack@google.com  void read(int& i) { i = data; }
8912855Sgabeblack@google.com  int data;
9012855Sgabeblack@google.com
9112855Sgabeblack@google.com  SC_CTOR(C0)
9212855Sgabeblack@google.com  {
9312855Sgabeblack@google.com    SC_THREAD(action);
9412855Sgabeblack@google.com  }
9512855Sgabeblack@google.com  void action() {
9612855Sgabeblack@google.com  sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "action");
9712855Sgabeblack@google.com  }
9812855Sgabeblack@google.com};
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com
10112855Sgabeblack@google.comstruct C1: virtual public sc_interface //// Combining channel and interface in one class DOULOS015
10212855Sgabeblack@google.com{
10312855Sgabeblack@google.com  void write(int i) { data = i; }
10412855Sgabeblack@google.com  void read(int& i) { i = data; }
10512855Sgabeblack@google.com  int data;
10612855Sgabeblack@google.com};
10712855Sgabeblack@google.com
10812855Sgabeblack@google.com
10912855Sgabeblack@google.comstruct I_F: virtual public sc_interface
11012855Sgabeblack@google.com{
11112855Sgabeblack@google.com  virtual void method() = 0;
11212855Sgabeblack@google.com};
11312855Sgabeblack@google.com
11412855Sgabeblack@google.comstruct C2: I_F            //// Channel derived from neither sc_module nor sc_prim_channel DOULOS049
11512855Sgabeblack@google.com{
11612855Sgabeblack@google.com  void method() {}
11712855Sgabeblack@google.com};
11812855Sgabeblack@google.com
11912855Sgabeblack@google.comstruct C3: sc_object, I_F //// Channel derived from sc_object only
12012855Sgabeblack@google.com                          //// (and derived from neither sc_module nor sc_prim_channel) DOULOS049
12112855Sgabeblack@google.com{
12212855Sgabeblack@google.com  void method() {}
12312855Sgabeblack@google.com};
12412855Sgabeblack@google.com
12512855Sgabeblack@google.com
12612855Sgabeblack@google.comvoid check_form_of_suffix(std::string s)
12712855Sgabeblack@google.com{
12812855Sgabeblack@google.com  std::string charset = "0123456789";
12912855Sgabeblack@google.com  while (!s.empty())
13012855Sgabeblack@google.com  {
13112855Sgabeblack@google.com    sc_assert(s[0] == '_');
13212855Sgabeblack@google.com    s = s.substr(1);
13312855Sgabeblack@google.com    sc_assert(!s.empty());
13412855Sgabeblack@google.com    do
13512855Sgabeblack@google.com    {
13612855Sgabeblack@google.com      sc_assert(charset.find(s[0]) < charset.size());
13712855Sgabeblack@google.com      s = s.substr(1);
13812855Sgabeblack@google.com    } while (!s.empty() && (s[0] != '_'));
13912855Sgabeblack@google.com  }
14012855Sgabeblack@google.com}
14112855Sgabeblack@google.com
14212855Sgabeblack@google.comstruct Modtype: sc_module
14312855Sgabeblack@google.com{
14412855Sgabeblack@google.com  Modtype(sc_module_name n = sc_gen_unique_name("Modtype"))
14512855Sgabeblack@google.com  {
14612855Sgabeblack@google.com    if (global_count == 0)
14712855Sgabeblack@google.com      sc_assert(std::string(basename()) == "mt");
14812855Sgabeblack@google.com    else
14912855Sgabeblack@google.com    {
15012855Sgabeblack@google.com      std::string s = std::string(basename());
15112855Sgabeblack@google.com      sc_assert(s.substr(0,7) == "Modtype");
15212855Sgabeblack@google.com      sc_assert(s.size() > 7);
15312855Sgabeblack@google.com      check_form_of_suffix(s.substr(7));
15412855Sgabeblack@google.com    }
15512855Sgabeblack@google.com    ++ global_count;
15612855Sgabeblack@google.com  }
15712855Sgabeblack@google.com  void dump() {
15812855Sgabeblack@google.com    sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "thread");
15912855Sgabeblack@google.com    ++ global_count;
16012855Sgabeblack@google.com  }
16112855Sgabeblack@google.com};
16212855Sgabeblack@google.com
16312855Sgabeblack@google.comtypedef sc_signal<Modtype*> MS; //// Pointer-to-module used as the type of a signal DOULOS051
16412855Sgabeblack@google.com
16512855Sgabeblack@google.com
16612855Sgabeblack@google.com
16712855Sgabeblack@google.comtemplate<class T>
16812855Sgabeblack@google.comstruct S
16912855Sgabeblack@google.com{
17012855Sgabeblack@google.com  T t;
17112855Sgabeblack@google.com};
17212855Sgabeblack@google.com
17312855Sgabeblack@google.com
17412855Sgabeblack@google.com
17512855Sgabeblack@google.comSC_MODULE(Moda)
17612855Sgabeblack@google.com{
17712855Sgabeblack@google.com  sc_port<C0> p0;
17812855Sgabeblack@google.com  sc_port<C1> p1;
17912855Sgabeblack@google.com  sc_port<C2> p2;
18012855Sgabeblack@google.com  sc_port<C3> p3;
18112855Sgabeblack@google.com  sc_port<MS> p4;
18212855Sgabeblack@google.com
18312855Sgabeblack@google.com  Modtype mt;
18412855Sgabeblack@google.com
18512855Sgabeblack@google.com  SC_CTOR(Moda): mt("mt")
18612855Sgabeblack@google.com  {
18712855Sgabeblack@google.com  sc_assert(std::string(name()) == "top.moda");
18812855Sgabeblack@google.com    SC_THREAD(thread);
18912855Sgabeblack@google.com  }
19012855Sgabeblack@google.com  void thread();
19112855Sgabeblack@google.com};
19212855Sgabeblack@google.com
19312855Sgabeblack@google.comSC_MODULE(Modb)
19412855Sgabeblack@google.com{
19512855Sgabeblack@google.com  sc_port<C0> p0;
19612855Sgabeblack@google.com  sc_port<C1> p1;
19712855Sgabeblack@google.com  sc_port<C2> p2;
19812855Sgabeblack@google.com  sc_port<C3> p3;
19912855Sgabeblack@google.com  sc_port<MS> p4;
20012855Sgabeblack@google.com
20112855Sgabeblack@google.com  SC_CTOR(Modb)
20212855Sgabeblack@google.com  {
20312855Sgabeblack@google.com  sc_assert(std::string(name()) == "top.modb");
20412855Sgabeblack@google.com    SC_THREAD(thread);
20512855Sgabeblack@google.com    SC_THREAD(funny);
20612855Sgabeblack@google.com  }
20712855Sgabeblack@google.com  void thread();
20812855Sgabeblack@google.com  void funny();
20912855Sgabeblack@google.com};
21012855Sgabeblack@google.com
21112855Sgabeblack@google.comvoid Moda::thread()
21212855Sgabeblack@google.com{
21312855Sgabeblack@google.com  p1->write(999);
21412855Sgabeblack@google.com  p2->method();
21512855Sgabeblack@google.com  p3->method();
21612855Sgabeblack@google.com  p4->write(&mt);
21712855Sgabeblack@google.com}
21812855Sgabeblack@google.comvoid Modb::thread()
21912855Sgabeblack@google.com{
22012855Sgabeblack@google.com  wait(SC_ZERO_TIME);
22112855Sgabeblack@google.com  int i; p1->read(i);
22212855Sgabeblack@google.com  sc_assert(i == 999);
22312855Sgabeblack@google.com  p2->method();
22412855Sgabeblack@google.com  p3->method();
22512855Sgabeblack@google.com  wait(SC_ZERO_TIME);
22612855Sgabeblack@google.com  (p4->read())->dump();
22712855Sgabeblack@google.com}
22812855Sgabeblack@google.com
22912855Sgabeblack@google.comvoid Modb::funny()  { C1 c1; C2 c2; C3 c3; }
23012855Sgabeblack@google.com
23112855Sgabeblack@google.com
23212855Sgabeblack@google.com
23312855Sgabeblack@google.com
23412855Sgabeblack@google.comstruct Link
23512855Sgabeblack@google.com{
23612855Sgabeblack@google.com  Link *link;
23712855Sgabeblack@google.com  sc_module      *m;       //// Pointer-to-module DOULOS006
23812855Sgabeblack@google.com  sc_signal<int> *s;       //// Pointer-to-signal
23912855Sgabeblack@google.com  sc_in<int>     *p;       //// Pointer-to-port DOULOS008
24012855Sgabeblack@google.com};
24112855Sgabeblack@google.com
24212855Sgabeblack@google.comSC_MODULE(Top)
24312855Sgabeblack@google.com{
24412855Sgabeblack@google.com
24512855Sgabeblack@google.com  SC_MODULE(Nested)        //// Nested modules DOULOS005
24612855Sgabeblack@google.com  {
24712855Sgabeblack@google.com    sc_in<int> *pp;        //// Pointer-to-port DOULOS008
24812855Sgabeblack@google.com
24912855Sgabeblack@google.com    SC_CTOR(Nested)
25012855Sgabeblack@google.com    {
25112855Sgabeblack@google.com      SC_METHOD(action);
25212855Sgabeblack@google.com
25312855Sgabeblack@google.com      pp = new sc_in<int>; //// Dynamic port instantiation DOULOS008
25412855Sgabeblack@google.com
25512855Sgabeblack@google.com      sensitive << *pp;    //// Sensitivity separated from SC_METHOD DOULOS011
25612855Sgabeblack@google.com    }
25712855Sgabeblack@google.com
25812855Sgabeblack@google.com  void action() { op = sc_min(3, (*pp).read() + 1); }
25912855Sgabeblack@google.com
26012855Sgabeblack@google.com    sc_out<int> op;        //// Out-of-order declaration DOULOS052
26112855Sgabeblack@google.com  };
26212855Sgabeblack@google.com
26312855Sgabeblack@google.com
26412855Sgabeblack@google.com  Nested n;
26512855Sgabeblack@google.com  Link* link;
26612855Sgabeblack@google.com  sc_signal<bool> b;
26712855Sgabeblack@google.com  sc_signal<int> *sig;      //// Pointer-to-signal
26812855Sgabeblack@google.com
26912855Sgabeblack@google.com  MyMod mymod;
27012855Sgabeblack@google.com  Moda moda;
27112855Sgabeblack@google.com  Modb modb;
27212855Sgabeblack@google.com  C0 c0;
27312855Sgabeblack@google.com  C1 c1;
27412855Sgabeblack@google.com  C2 c2;
27512855Sgabeblack@google.com  C3 c3;
27612855Sgabeblack@google.com
27712855Sgabeblack@google.com  S<Modtype> Sm;            //// Using sc_module as a template parameter DOULOS051
27812855Sgabeblack@google.com  MS ms;                    //// Pointer-to-module used as the type of a signal DOULOS051
27912855Sgabeblack@google.com
28012855Sgabeblack@google.com  Mod0 mod0;
28112855Sgabeblack@google.com
28212855Sgabeblack@google.com  SC_CTOR(Top)
28312855Sgabeblack@google.com  : n("n"), mymod("mymod"), moda("moda"), modb("modb"), c0("c0"), mod0("mod0")
28412855Sgabeblack@google.com  {
28512855Sgabeblack@google.com    link = new Link;
28612855Sgabeblack@google.com    link->m = new Mod("mod_1");
28712855Sgabeblack@google.com    link->p = new sc_in<int>;
28812855Sgabeblack@google.com    link->link = new Link;
28912855Sgabeblack@google.com    link->link->m = new Mod("mod_2");  //// Buried dynamic module instantiation DOULOS002
29012855Sgabeblack@google.com    link->link->s = new sc_signal<int>;//// Buried dynamic channel instantiation
29112855Sgabeblack@google.com    link->link->p = new sc_in<int>;    //// Buried dynamic port instantiation DOULOS008
29212855Sgabeblack@google.com
29312855Sgabeblack@google.com    sig = new sc_signal<int>;          //// Dynamic channel instantiation
29412855Sgabeblack@google.com    n.op(*sig);
29512855Sgabeblack@google.com    (*(n.pp)).bind(*sig);              //// Binding dynamically allocated port DOULOS008
29612855Sgabeblack@google.com
29712855Sgabeblack@google.com    mymod.p(b);
29812855Sgabeblack@google.com
29912855Sgabeblack@google.com    moda.p0(c0);
30012855Sgabeblack@google.com    moda.p1(c1);
30112855Sgabeblack@google.com    moda.p2(c2);
30212855Sgabeblack@google.com    moda.p3(c3);
30312855Sgabeblack@google.com    moda.p4(ms);
30412855Sgabeblack@google.com
30512855Sgabeblack@google.com    modb.p0(c0);
30612855Sgabeblack@google.com    modb.p1(c1);
30712855Sgabeblack@google.com    modb.p2(c2);
30812855Sgabeblack@google.com    modb.p3(c3);
30912855Sgabeblack@google.com    modb.p4(ms);
31012855Sgabeblack@google.com  }
31112855Sgabeblack@google.com
31212855Sgabeblack@google.com};
31312855Sgabeblack@google.com
31412855Sgabeblack@google.com
31512855Sgabeblack@google.comint sc_main(int argc, char* argv[])
31612855Sgabeblack@google.com{
31712855Sgabeblack@google.com  cout << "Should be silent except for some renaming warnings..." << endl;
31812855Sgabeblack@google.com
31912855Sgabeblack@google.com  sc_signal<int> s;
32012855Sgabeblack@google.com  Top top("top");
32112855Sgabeblack@google.com  top.link->p->bind(s);
32212855Sgabeblack@google.com  top.link->link->p->bind(s);         //// Binding dynamically allocated port DOULOS008
32312855Sgabeblack@google.com
32412855Sgabeblack@google.com  sc_start();
32512855Sgabeblack@google.com  sc_assert(global_count == 10);
32612855Sgabeblack@google.com  sc_assert(top.sig->read() == 3);
32712855Sgabeblack@google.com
32812855Sgabeblack@google.com  cout << endl << "Success" << endl;
32912855Sgabeblack@google.com  return 0;
33012855Sgabeblack@google.com}
331