source: sources/src/sc_module.cc @ 54

Last change on this file since 54 was 52, checked in by meunier, 12 years ago

Code formatting in all source files.

File size: 14.2 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                   sc_module.cc                    |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Taktak Sami                       |
9|                                                             |
10| Date    :                   09_07_2004                      |
11|                                                             |
12\------------------------------------------------------------*/
13
14/*
15 * This file is part of the Disydent Project
16 * Copyright (C) Laboratoire LIP6 - Département ASIM
17 * Universite Pierre et Marie Curie
18 *
19 * Home page          : http://www-asim.lip6.fr/disydent
20 * E-mail             : mailto:richard.buchmann@lip6.fr
21 *
22 * This library is free software; you  can redistribute it and/or modify it
23 * under the terms  of the GNU Library General Public  License as published
24 * by the Free Software Foundation; either version 2 of the License, or (at
25 * your option) any later version.
26 *
27 * Disydent is distributed  in the hope  that it  will be
28 * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
30 * Public License for more details.
31 *
32 * You should have received a copy  of the GNU General Public License along
33 * with the GNU C Library; see the  file COPYING. If not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37#include <stdarg.h>
38#include <vector>
39#include <set>
40
41#include "sc_module.h"
42#include "sc_module_name.h"
43#include "sc_sensitive.h"
44#include "module_hierarchy.h"
45#include "serialization.h" // set_save_handler
46#include "sc_port.h"
47#include "sc_signal.h"
48#include "sc_clock.h" // is_clock
49#include "entity.h"
50#include <cassert>
51
52#ifdef HAVE_CONFIG_H
53#include "config.h"
54#endif
55
56//
57using namespace std;
58
59// ----------------------------------------------------------------------------
60//
61//                                               
62// ----------------------------------------------------------------------------
63
64namespace sc_core {
65
66instances_set_t instances_set;   
67instances_list_t temp_list;   
68method_process_list_t method_process_list;
69module_name_stack_t module_name_stack;
70modules_stack_t modules_stack;
71method_process_t * method;
72
73void declare_method_process(const char * name, SC_ENTRY_FUNC func, sc_module & module) {
74  method = create_method_process(name, func, module);
75  method_process_list.push_back(method); 
76}
77
78
79ostream & operator << (ostream &o, instances_set_t &l) {
80  instances_set_t::iterator i;
81  for (i = l.begin(); i != l.end(); ++i) {
82    o << (*i)->name() << " ";
83  }
84  return o << endl;
85}
86
87
88template <typename T>
89static std::ostream& operator << (std::ostream & o, const list<T> &l) {
90  typename list<T>::const_iterator i;
91  for (i = l.begin(); i != l.end(); ++i) {
92    o << (*i) << " ";
93  }
94  return o << endl;
95}
96
97
98template <typename T>
99static std::ostream& operator << (std::ostream &o, const list<T *> &l) {
100  typename list<T *>::const_iterator i;
101  for (i = l.begin(); i != l.end(); ++i) {
102    o << (**i) << " ";
103  }
104  return o << endl;
105}
106
107
108bool is_clock (const sc_interface & inter) {
109    equi_t & e = get_equi(inter);
110    equi_t::iterator i;
111    for (i = e.begin(); i != e.end(); ++i) {
112        if (i->kind() == sc_clock::kind_string) {
113            return true;
114        }
115    }
116    return false;
117}
118
119
120// ----------------------------------------------------------------------------
121//  CLASS : method_process_t
122//                                               
123// ----------------------------------------------------------------------------
124method_process_t::method_process_t(const char * nm, SC_ENTRY_FUNC fn, sc_module & mod) {
125  name = nm;
126  func = fn; 
127  module = &mod;
128  dont_initialize = false;
129}
130
131
132static bool is_register (const sc_interface & inter) {
133    equi_t & e = get_equi(inter);
134    if (e.size() != 1) {
135        return false;
136    }
137   
138    sc_object & obj = *(e.begin()->object);
139    if (obj.kind() != sc_signal_base::kind_string) {
140        return false;
141    }
142    return true;
143}
144
145
146bool method_process_t::is_combinational(void) {
147    if (sensitivity_list.empty()) {
148        return false;
149    }
150    sensitivity_list_t::iterator i;
151    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
152#if defined(CONFIG_DEBUG) && 0
153        if (i->get_interface() == NULL) {
154            cerr << "'" << i << "' is unbound.\n";
155            exit(121);
156        }
157#endif
158        if ((i->get_flag() == sc_event::VAL) && (!is_register(i->get_interface()))) {
159            return true;
160        }
161    }
162    return false;
163}
164
165
166bool method_process_t::is_transition(void) {
167    if (sensitivity_list.empty()) {
168        return false;
169    }
170    sensitivity_list_t::iterator i;
171    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
172        if (i->get_flag() != sc_event::POS) {
173            return false;
174        }
175        // check if the port is a clock
176        if (is_clock(i->get_interface()) == false) {
177            return false;
178        }
179    }
180    return true;
181}
182
183
184bool method_process_t::is_genmoore(void) {
185    // sensitivity list of moore functions includes :
186    // - register (signal unconnected)
187    // - negative edge of port which is bound to a clock signal
188    if (sensitivity_list.empty()) {
189        return false;
190    }
191    sensitivity_list_t::iterator i;
192    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
193        if ((i->get_flag() == sc_event::VAL) && (is_register(i->get_interface()))) {
194            continue;
195        }
196        if ((i->get_flag() == sc_event::NEG) && (is_clock(i->get_interface()) == true)) {
197            continue;
198        }
199        return false;
200    }
201    return true;
202}
203
204
205std::ostream & operator << (std::ostream & o, const method_process_t & m) {
206    return o << *(m.module) 
207        << "->" 
208        << m.name
209        << "() when " 
210        << m.sensitivity_list;
211}
212
213
214// ----------------------------------------------------------------------------
215//  CLASS : sc_module
216//                                               
217// ----------------------------------------------------------------------------
218
219
220sc_module::sc_module(void) :
221    sc_object(NULL),
222    sensitive(this) {
223  init();
224}
225
226sc_module::sc_module(const char * nm) :
227    sc_object(NULL),
228    sensitive(this) {
229  assert(nm != NULL);
230  init();
231}
232
233
234sc_module::sc_module(const sc_module_name & nm) :
235    sc_object(NULL),
236    sensitive(this) {
237  init();
238}
239
240
241void sc_module::init() {
242    instances_set.insert(this);
243    temp_list.push_back(this);
244    modules_stack.top() = this;
245    set_save_handler(*this, NULL);
246}
247
248void sc_module::dont_initialize() {
249    sc_core::valid_method_process();
250}
251
252
253void declare_save_handler(const char * name, save_fct_t1 func, sc_module & module) {
254    sc_core::set_save_handler(module, func);
255}
256
257typedef std::list<sc_port_base*> port_list_t;
258
259// Build a port list owned by the module mod
260static void get_port_list(const sc_module & mod, port_list_t & pl) {
261    port2module_t::iterator i;
262    for (i = port2module.begin(); i != port2module.end(); ++i) {
263        if (i->second == &mod) {
264            pl.push_back((sc_port_base *) (i->first));
265        }
266    }
267}
268
269
270#define BIND(sig) bind(*this, p, port_list, sig)
271
272static void bind(sc_module & mod, 
273        port_list_t::iterator & port_it, 
274        port_list_t & port_list, 
275        sc_bind_proxy & sig) {
276    if (&sig == &SC_BIND_PROXY_NIL) { 
277        return;
278    }
279    if (port_it == port_list.end()) {
280        cerr << "error : binding port in ";
281        cerr << mod.name();
282        cerr << " module.\n";
283        exit(7);
284    }
285    bind(**(port_it++), sig);
286}
287
288
289void sc_module::operator () ( /* const */ sc_bind_proxy & p001,
290        /* const */ sc_bind_proxy & p002,
291        /* const */ sc_bind_proxy & p003,
292        /* const */ sc_bind_proxy & p004,
293        /* const */ sc_bind_proxy & p005,
294        /* const */ sc_bind_proxy & p006,
295        /* const */ sc_bind_proxy & p007,
296        /* const */ sc_bind_proxy & p008,
297        /* const */ sc_bind_proxy & p009,
298        /* const */ sc_bind_proxy & p010,
299        /* const */ sc_bind_proxy & p011,
300        /* const */ sc_bind_proxy & p012,
301        /* const */ sc_bind_proxy & p013,
302        /* const */ sc_bind_proxy & p014,
303        /* const */ sc_bind_proxy & p015,
304        /* const */ sc_bind_proxy & p016,
305        /* const */ sc_bind_proxy & p017,
306        /* const */ sc_bind_proxy & p018,
307        /* const */ sc_bind_proxy & p019,
308        /* const */ sc_bind_proxy & p020,
309        /* const */ sc_bind_proxy & p021,
310        /* const */ sc_bind_proxy & p022,
311        /* const */ sc_bind_proxy & p023,
312        /* const */ sc_bind_proxy & p024,
313        /* const */ sc_bind_proxy & p025,
314        /* const */ sc_bind_proxy & p026,
315        /* const */ sc_bind_proxy & p027,
316        /* const */ sc_bind_proxy & p028,
317        /* const */ sc_bind_proxy & p029,
318        /* const */ sc_bind_proxy & p030,
319        /* const */ sc_bind_proxy & p031,
320        /* const */ sc_bind_proxy & p032,
321        /* const */ sc_bind_proxy & p033,
322        /* const */ sc_bind_proxy & p034,
323        /* const */ sc_bind_proxy & p035,
324        /* const */ sc_bind_proxy & p036,
325        /* const */ sc_bind_proxy & p037,
326        /* const */ sc_bind_proxy & p038,
327        /* const */ sc_bind_proxy & p039,
328        /* const */ sc_bind_proxy & p040,
329        /* const */ sc_bind_proxy & p041,
330        /* const */ sc_bind_proxy & p042,
331        /* const */ sc_bind_proxy & p043,
332        /* const */ sc_bind_proxy & p044,
333        /* const */ sc_bind_proxy & p045,
334        /* const */ sc_bind_proxy & p046,
335        /* const */ sc_bind_proxy & p047,
336        /* const */ sc_bind_proxy & p048,
337        /* const */ sc_bind_proxy & p049,
338        /* const */ sc_bind_proxy & p050,
339        /* const */ sc_bind_proxy & p051,
340        /* const */ sc_bind_proxy & p052,
341        /* const */ sc_bind_proxy & p053,
342        /* const */ sc_bind_proxy & p054,
343        /* const */ sc_bind_proxy & p055,
344        /* const */ sc_bind_proxy & p056,
345        /* const */ sc_bind_proxy & p057,
346        /* const */ sc_bind_proxy & p058,
347        /* const */ sc_bind_proxy & p059,
348        /* const */ sc_bind_proxy & p060,
349        /* const */ sc_bind_proxy & p061,
350        /* const */ sc_bind_proxy & p062,
351        /* const */ sc_bind_proxy & p063,
352        /* const */ sc_bind_proxy & p064)
353{
354    port_list_t port_list;
355    get_port_list(*this, port_list);
356    cerr << "port list : " << port_list << endl;
357    port_list_t::iterator p = port_list.begin();
358    BIND(p001);
359    BIND(p002);
360    BIND(p003);
361    BIND(p004);
362    BIND(p005);
363    BIND(p006);
364    BIND(p007);
365    BIND(p008);
366    BIND(p009);
367    BIND(p010);
368    BIND(p011);
369    BIND(p012);
370    BIND(p013);
371    BIND(p014);
372    BIND(p015);
373    BIND(p016);
374    BIND(p017);
375    BIND(p018);
376    BIND(p019);
377    BIND(p020);
378    BIND(p021);
379    BIND(p022);
380    BIND(p023);
381    BIND(p024);
382    BIND(p025);
383    BIND(p026);
384    BIND(p027);
385    BIND(p028);
386    BIND(p029);
387    BIND(p030);
388    BIND(p031);
389    BIND(p032);
390    BIND(p033);
391    BIND(p034);
392    BIND(p035);
393    BIND(p036);
394    BIND(p037);
395    BIND(p038);
396    BIND(p039);
397    BIND(p040);
398    BIND(p041);
399    BIND(p042);
400    BIND(p043);
401    BIND(p044);
402    BIND(p045);
403    BIND(p046);
404    BIND(p047);
405    BIND(p048);
406    BIND(p049);
407    BIND(p050);
408    BIND(p051);
409    BIND(p052);
410    BIND(p053);
411    BIND(p054);
412    BIND(p055);
413    BIND(p056);
414    BIND(p057);
415    BIND(p058);
416    BIND(p059);
417    BIND(p060);
418    BIND(p061);
419    BIND(p062);
420    BIND(p063);
421    BIND(p064);
422}
423
424
425ostream & operator << (ostream & o, const sc_module & m) {
426    return o << m.name();
427}
428
429
430// ----------------------------------------------------------------------------
431//  CLASS : sc_module_name
432//                                               
433// ----------------------------------------------------------------------------
434
435sc_module_name::sc_module_name(const char * name_) : m_pushed(true) {
436    m_name = name_;
437    init();
438}
439
440
441sc_module_name::sc_module_name(const sc_module_name & module) : m_pushed(false) {
442    m_name = module.m_name;
443}
444
445
446void sc_module_name::init() {
447    sc_core::module_name_stack.push_back(m_name);
448    modules_stack.push(NULL);
449}
450
451
452sc_module_name::~sc_module_name() {
453    if (m_pushed == false) {
454        return;
455    }
456    assert(sc_core::module_name_stack.empty() == false);
457    sc_core::module_name_stack.pop_back();
458    modules_stack.pop();
459    assert(temp_list.empty() == false);
460    sc_module * last1 = temp_list.back();
461    temp_list.pop_back();
462    sc_module * last2 = (temp_list.empty()) ? NULL : temp_list.back();
463    set_parent(*last1, last2);
464}
465
466
467std::ostream & operator << (std::ostream & o, const sc_core::sc_module_name & n) {
468    return o << (const char *) n;
469}
470
471/////////////////////////////////////////:
472
473static void check_method_process(const method_process_t & m) {
474    if (m.dont_initialize == false) {
475        assert(m.module != NULL);
476#ifdef CONFIG_DEBUG
477        std::cerr << "Warning : SystemCASS doesn't perform SC_METHOD(S) initializations.\n"
478            << "Please turn off automatic initialization for '" << m.name
479            << "' method of '" << m.module->name() << "' module"
480            " by calling 'dont_initialize()' function.\n"
481            "Example :\n"
482            "  SC_METHOD(transition);\n"
483            "  sensitive << clk;\n"
484            "  dont_initialize();\n";
485#endif
486    }
487}
488
489
490void check_all_method_process() {
491    method_process_list_t::const_iterator i;
492    for (i = sc_core::method_process_list.begin(); i != sc_core::method_process_list.end(); ++i) {
493        check_method_process(**i);
494    }
495}
496
497
498void valid_method_process() {
499    method_process_t * m = sc_core::method_process_list.back();
500    m->dont_initialize = true;
501}
502
503
504method_process_t * create_method_process(const char * name, SC_ENTRY_FUNC func, sc_module & module) {
505    return new method_process_t(name, func, module);
506}
507
508
509} // end of sc_core namespace
510
511/*
512# Local Variables:
513# tab-width: 4;
514# c-basic-offset: 4;
515# c-file-offsets:((innamespace . 0)(inline-open . 0));
516# indent-tabs-mode: nil;
517# End:
518#
519# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
520*/
521
Note: See TracBrowser for help on using the repository browser.