test001.cpp revision 12855:588919e0e4aa
1 2#include <systemc.h> 3 4// Tests for 2.0.1 extended coding styles, illustrating that SystemC is a class library, not a syntax 5 6static int global_count = 0; 7 8SC_MODULE(Mod) 9{ 10 SC_CTOR(Mod) 11 { 12 sc_assert(std::string(this->kind()) == "sc_module"); 13 } 14}; 15 16 17 18SC_MODULE(Mod0) 19{ 20 SC_CTOR(Mod0) 21 { 22 sc_assert(std::string(basename()) == "mod0"); 23 SC_METHOD(method); 24 dont_initialize(); 25 method(); //// Calling an SC_METHOD member function directly DOULOS009 26 27 for (int i = 0; i < 3; i++) 28 { 29 SC_THREAD(thread); //// Registering the same function multiple times DOULOS046 30 //// Get warnings re-defining sc_object names, multiple threads created 31 } 32 SC_THREAD(thread); 33 SC_THREAD(thread); //// Compile-time error - 'threadhandle' redefinition 34 35 f(); 36 } 37 void method(void) { 38 sc_assert(sc_get_current_process_handle().proc_kind() == SC_METHOD_PROC_); 39 ++ global_count; 40 } 41 void thread(void) { 42 sc_assert(sc_get_current_process_handle().proc_kind() == SC_THREAD_PROC_); 43 ++ global_count; 44 } 45 46 void f() { SC_THREAD(g); } //// Process registered in member function called from constructor DOULOS007 47 void g() 48 { 49 sc_assert(std::string(sc_get_current_process_handle().name()) == "top.mod0.g"); 50 ++ global_count; 51 } 52}; 53 54 55struct Chan //// Pseudo-channel used for port-less interprocess communication 56 //// but not derived from sc_module, sc_prim_channel or sc_interface DOULOS048 57{ 58 void write(int i) { wait(10, SC_NS); data = i; e.notify(); } 59 void read(int& i) { wait(e); i = data; } 60 int data; 61 bool wr, re; 62 sc_event e; 63}; 64 65struct MyMod: Mod //// Class derived from an SC_MODULE DOULOS050 66{ 67 sc_in<bool> p; 68 69 MyMod(sc_module_name n) 70 : Mod(n) 71 { 72 SC_THREAD(p1); 73 SC_THREAD(p2); 74 } 75 76 Chan ch; //// Instance of pseudo-channel DOULOS048 77 void p1() { ch.write(333); } 78 void p2() { int i; ch.read(i); sc_assert(i == 333); } 79 80 SC_HAS_PROCESS(MyMod); 81}; 82 83 84 85struct C0: sc_module, virtual sc_interface //// Combining channel and interface in one class DOULOS015 86{ 87 void write(int i) { data = i; } 88 void read(int& i) { i = data; } 89 int data; 90 91 SC_CTOR(C0) 92 { 93 SC_THREAD(action); 94 } 95 void action() { 96 sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "action"); 97 } 98}; 99 100 101struct C1: virtual public sc_interface //// Combining channel and interface in one class DOULOS015 102{ 103 void write(int i) { data = i; } 104 void read(int& i) { i = data; } 105 int data; 106}; 107 108 109struct I_F: virtual public sc_interface 110{ 111 virtual void method() = 0; 112}; 113 114struct C2: I_F //// Channel derived from neither sc_module nor sc_prim_channel DOULOS049 115{ 116 void method() {} 117}; 118 119struct C3: sc_object, I_F //// Channel derived from sc_object only 120 //// (and derived from neither sc_module nor sc_prim_channel) DOULOS049 121{ 122 void method() {} 123}; 124 125 126void check_form_of_suffix(std::string s) 127{ 128 std::string charset = "0123456789"; 129 while (!s.empty()) 130 { 131 sc_assert(s[0] == '_'); 132 s = s.substr(1); 133 sc_assert(!s.empty()); 134 do 135 { 136 sc_assert(charset.find(s[0]) < charset.size()); 137 s = s.substr(1); 138 } while (!s.empty() && (s[0] != '_')); 139 } 140} 141 142struct Modtype: sc_module 143{ 144 Modtype(sc_module_name n = sc_gen_unique_name("Modtype")) 145 { 146 if (global_count == 0) 147 sc_assert(std::string(basename()) == "mt"); 148 else 149 { 150 std::string s = std::string(basename()); 151 sc_assert(s.substr(0,7) == "Modtype"); 152 sc_assert(s.size() > 7); 153 check_form_of_suffix(s.substr(7)); 154 } 155 ++ global_count; 156 } 157 void dump() { 158 sc_assert(std::string(sc_get_current_process_handle().get_process_object()->basename()) == "thread"); 159 ++ global_count; 160 } 161}; 162 163typedef sc_signal<Modtype*> MS; //// Pointer-to-module used as the type of a signal DOULOS051 164 165 166 167template<class T> 168struct S 169{ 170 T t; 171}; 172 173 174 175SC_MODULE(Moda) 176{ 177 sc_port<C0> p0; 178 sc_port<C1> p1; 179 sc_port<C2> p2; 180 sc_port<C3> p3; 181 sc_port<MS> p4; 182 183 Modtype mt; 184 185 SC_CTOR(Moda): mt("mt") 186 { 187 sc_assert(std::string(name()) == "top.moda"); 188 SC_THREAD(thread); 189 } 190 void thread(); 191}; 192 193SC_MODULE(Modb) 194{ 195 sc_port<C0> p0; 196 sc_port<C1> p1; 197 sc_port<C2> p2; 198 sc_port<C3> p3; 199 sc_port<MS> p4; 200 201 SC_CTOR(Modb) 202 { 203 sc_assert(std::string(name()) == "top.modb"); 204 SC_THREAD(thread); 205 SC_THREAD(funny); 206 } 207 void thread(); 208 void funny(); 209}; 210 211void Moda::thread() 212{ 213 p1->write(999); 214 p2->method(); 215 p3->method(); 216 p4->write(&mt); 217} 218void Modb::thread() 219{ 220 wait(SC_ZERO_TIME); 221 int i; p1->read(i); 222 sc_assert(i == 999); 223 p2->method(); 224 p3->method(); 225 wait(SC_ZERO_TIME); 226 (p4->read())->dump(); 227} 228 229void Modb::funny() { C1 c1; C2 c2; C3 c3; } 230 231 232 233 234struct Link 235{ 236 Link *link; 237 sc_module *m; //// Pointer-to-module DOULOS006 238 sc_signal<int> *s; //// Pointer-to-signal 239 sc_in<int> *p; //// Pointer-to-port DOULOS008 240}; 241 242SC_MODULE(Top) 243{ 244 245 SC_MODULE(Nested) //// Nested modules DOULOS005 246 { 247 sc_in<int> *pp; //// Pointer-to-port DOULOS008 248 249 SC_CTOR(Nested) 250 { 251 SC_METHOD(action); 252 253 pp = new sc_in<int>; //// Dynamic port instantiation DOULOS008 254 255 sensitive << *pp; //// Sensitivity separated from SC_METHOD DOULOS011 256 } 257 258 void action() { op = sc_min(3, (*pp).read() + 1); } 259 260 sc_out<int> op; //// Out-of-order declaration DOULOS052 261 }; 262 263 264 Nested n; 265 Link* link; 266 sc_signal<bool> b; 267 sc_signal<int> *sig; //// Pointer-to-signal 268 269 MyMod mymod; 270 Moda moda; 271 Modb modb; 272 C0 c0; 273 C1 c1; 274 C2 c2; 275 C3 c3; 276 277 S<Modtype> Sm; //// Using sc_module as a template parameter DOULOS051 278 MS ms; //// Pointer-to-module used as the type of a signal DOULOS051 279 280 Mod0 mod0; 281 282 SC_CTOR(Top) 283 : n("n"), mymod("mymod"), moda("moda"), modb("modb"), c0("c0"), mod0("mod0") 284 { 285 link = new Link; 286 link->m = new Mod("mod_1"); 287 link->p = new sc_in<int>; 288 link->link = new Link; 289 link->link->m = new Mod("mod_2"); //// Buried dynamic module instantiation DOULOS002 290 link->link->s = new sc_signal<int>;//// Buried dynamic channel instantiation 291 link->link->p = new sc_in<int>; //// Buried dynamic port instantiation DOULOS008 292 293 sig = new sc_signal<int>; //// Dynamic channel instantiation 294 n.op(*sig); 295 (*(n.pp)).bind(*sig); //// Binding dynamically allocated port DOULOS008 296 297 mymod.p(b); 298 299 moda.p0(c0); 300 moda.p1(c1); 301 moda.p2(c2); 302 moda.p3(c3); 303 moda.p4(ms); 304 305 modb.p0(c0); 306 modb.p1(c1); 307 modb.p2(c2); 308 modb.p3(c3); 309 modb.p4(ms); 310 } 311 312}; 313 314 315int sc_main(int argc, char* argv[]) 316{ 317 cout << "Should be silent except for some renaming warnings..." << endl; 318 319 sc_signal<int> s; 320 Top top("top"); 321 top.link->p->bind(s); 322 top.link->link->p->bind(s); //// Binding dynamically allocated port DOULOS008 323 324 sc_start(); 325 sc_assert(global_count == 10); 326 sc_assert(top.sig->read() == 3); 327 328 cout << endl << "Success" << endl; 329 return 0; 330} 331