source: sources/src/sc_module.cc @ 59

Last change on this file since 59 was 59, checked in by meunier, 7 years ago
  • Fixed memory leaks
  • Fixed indentation in some 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;
69std::vector<const char *> allocated_names;
70module_name_stack_t module_name_stack;
71modules_stack_t modules_stack;
72method_process_t * method;
73
74void declare_method_process(const char * name, SC_ENTRY_FUNC func, sc_module & module) {
75  method = create_method_process(name, func, module);
76  method_process_list.push_back(method);
77}
78
79
80ostream & operator << (ostream &o, instances_set_t &l) {
81  instances_set_t::iterator i;
82  for (i = l.begin(); i != l.end(); ++i) {
83    o << (*i)->name() << " ";
84  }
85  return o << endl;
86}
87
88
89template <typename T>
90static std::ostream& operator << (std::ostream & o, const list<T> &l) {
91  typename list<T>::const_iterator i;
92  for (i = l.begin(); i != l.end(); ++i) {
93    o << (*i) << " ";
94  }
95  return o << endl;
96}
97
98
99template <typename T>
100static std::ostream& operator << (std::ostream &o, const list<T *> &l) {
101  typename list<T *>::const_iterator i;
102  for (i = l.begin(); i != l.end(); ++i) {
103    o << (**i) << " ";
104  }
105  return o << endl;
106}
107
108
109bool is_clock (const sc_interface & inter) {
110    equi_t & e = get_equi(inter);
111    equi_t::iterator i;
112    for (i = e.begin(); i != e.end(); ++i) {
113        if (i->kind() == sc_clock::kind_string) {
114            return true;
115        }
116    }
117    return false;
118}
119
120
121// ----------------------------------------------------------------------------
122//  CLASS : method_process_t
123//                                               
124// ----------------------------------------------------------------------------
125method_process_t::method_process_t(const char * nm, SC_ENTRY_FUNC fn, sc_module & mod) {
126  name = nm;
127  func = fn; 
128  module = &mod;
129  dont_initialize = false;
130}
131
132
133static bool is_register (const sc_interface & inter) {
134    equi_t & e = get_equi(inter);
135    if (e.size() != 1) {
136        return false;
137    }
138   
139    sc_object & obj = *(e.begin()->object);
140    if (obj.kind() != sc_signal_base::kind_string) {
141        return false;
142    }
143    return true;
144}
145
146
147bool method_process_t::is_combinational(void) {
148    if (sensitivity_list.empty()) {
149        return false;
150    }
151    sensitivity_list_t::iterator i;
152    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
153#if defined(CONFIG_DEBUG) && 0
154        if (i->get_interface() == NULL) {
155            cerr << "'" << i << "' is unbound.\n";
156            exit(121);
157        }
158#endif
159        if ((i->get_flag() == sc_event::VAL) && (!is_register(i->get_interface()))) {
160            return true;
161        }
162    }
163    return false;
164}
165
166
167bool method_process_t::is_transition(void) {
168    if (sensitivity_list.empty()) {
169        return false;
170    }
171    sensitivity_list_t::iterator i;
172    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
173        if (i->get_flag() != sc_event::POS) {
174            return false;
175        }
176        // check if the port is a clock
177        if (is_clock(i->get_interface()) == false) {
178            return false;
179        }
180    }
181    return true;
182}
183
184
185bool method_process_t::is_genmoore(void) {
186    // sensitivity list of moore functions includes :
187    // - register (signal unconnected)
188    // - negative edge of port which is bound to a clock signal
189    if (sensitivity_list.empty()) {
190        return false;
191    }
192    sensitivity_list_t::iterator i;
193    for (i = sensitivity_list.begin(); i != sensitivity_list.end(); ++i) {
194        if ((i->get_flag() == sc_event::VAL) && (is_register(i->get_interface()))) {
195            continue;
196        }
197        if ((i->get_flag() == sc_event::NEG) && (is_clock(i->get_interface()) == true)) {
198            continue;
199        }
200        return false;
201    }
202    return true;
203}
204
205
206std::ostream & operator << (std::ostream & o, const method_process_t & m) {
207    return o << *(m.module) 
208        << "->" 
209        << m.name
210        << "() when " 
211        << m.sensitivity_list;
212}
213
214
215// ----------------------------------------------------------------------------
216//  CLASS : sc_module
217//                                               
218// ----------------------------------------------------------------------------
219
220
221sc_module::sc_module(void) :
222    sc_object(NULL),
223    sensitive(this) {
224  init();
225}
226
227sc_module::sc_module(const char * nm) :
228    sc_object(NULL),
229    sensitive(this) {
230  assert(nm != NULL);
231  init();
232}
233
234
235sc_module::sc_module(const sc_module_name & nm) :
236    sc_object(NULL),
237    sensitive(this) {
238  init();
239}
240
241
242void sc_module::init() {
243    instances_set.insert(this);
244    temp_list.push_back(this);
245    modules_stack.top() = this;
246    set_save_handler(*this, NULL);
247}
248
249void sc_module::dont_initialize() {
250    sc_core::valid_method_process();
251}
252
253
254void declare_save_handler(const char * name, save_fct_t1 func, sc_module & module) {
255    sc_core::set_save_handler(module, func);
256}
257
258typedef std::list<sc_port_base*> port_list_t;
259
260// Build a port list owned by the module mod
261static void get_port_list(const sc_module & mod, port_list_t & pl) {
262    port2module_t::iterator i;
263    for (i = port2module.begin(); i != port2module.end(); ++i) {
264        if (i->second == &mod) {
265            pl.push_back((sc_port_base *) (i->first));
266        }
267    }
268}
269
270
271#define BIND(sig) bind(*this, p, port_list, sig)
272
273static void bind(sc_module & mod, 
274        port_list_t::iterator & port_it, 
275        port_list_t & port_list, 
276        sc_bind_proxy & sig) {
277    if (&sig == &SC_BIND_PROXY_NIL) { 
278        return;
279    }
280    if (port_it == port_list.end()) {
281        cerr << "error : binding port in ";
282        cerr << mod.name();
283        cerr << " module.\n";
284        exit(7);
285    }
286    bind(**(port_it++), sig);
287}
288
289
290void sc_module::operator () ( /* const */ sc_bind_proxy & p001,
291        /* const */ sc_bind_proxy & p002,
292        /* const */ sc_bind_proxy & p003,
293        /* const */ sc_bind_proxy & p004,
294        /* const */ sc_bind_proxy & p005,
295        /* const */ sc_bind_proxy & p006,
296        /* const */ sc_bind_proxy & p007,
297        /* const */ sc_bind_proxy & p008,
298        /* const */ sc_bind_proxy & p009,
299        /* const */ sc_bind_proxy & p010,
300        /* const */ sc_bind_proxy & p011,
301        /* const */ sc_bind_proxy & p012,
302        /* const */ sc_bind_proxy & p013,
303        /* const */ sc_bind_proxy & p014,
304        /* const */ sc_bind_proxy & p015,
305        /* const */ sc_bind_proxy & p016,
306        /* const */ sc_bind_proxy & p017,
307        /* const */ sc_bind_proxy & p018,
308        /* const */ sc_bind_proxy & p019,
309        /* const */ sc_bind_proxy & p020,
310        /* const */ sc_bind_proxy & p021,
311        /* const */ sc_bind_proxy & p022,
312        /* const */ sc_bind_proxy & p023,
313        /* const */ sc_bind_proxy & p024,
314        /* const */ sc_bind_proxy & p025,
315        /* const */ sc_bind_proxy & p026,
316        /* const */ sc_bind_proxy & p027,
317        /* const */ sc_bind_proxy & p028,
318        /* const */ sc_bind_proxy & p029,
319        /* const */ sc_bind_proxy & p030,
320        /* const */ sc_bind_proxy & p031,
321        /* const */ sc_bind_proxy & p032,
322        /* const */ sc_bind_proxy & p033,
323        /* const */ sc_bind_proxy & p034,
324        /* const */ sc_bind_proxy & p035,
325        /* const */ sc_bind_proxy & p036,
326        /* const */ sc_bind_proxy & p037,
327        /* const */ sc_bind_proxy & p038,
328        /* const */ sc_bind_proxy & p039,
329        /* const */ sc_bind_proxy & p040,
330        /* const */ sc_bind_proxy & p041,
331        /* const */ sc_bind_proxy & p042,
332        /* const */ sc_bind_proxy & p043,
333        /* const */ sc_bind_proxy & p044,
334        /* const */ sc_bind_proxy & p045,
335        /* const */ sc_bind_proxy & p046,
336        /* const */ sc_bind_proxy & p047,
337        /* const */ sc_bind_proxy & p048,
338        /* const */ sc_bind_proxy & p049,
339        /* const */ sc_bind_proxy & p050,
340        /* const */ sc_bind_proxy & p051,
341        /* const */ sc_bind_proxy & p052,
342        /* const */ sc_bind_proxy & p053,
343        /* const */ sc_bind_proxy & p054,
344        /* const */ sc_bind_proxy & p055,
345        /* const */ sc_bind_proxy & p056,
346        /* const */ sc_bind_proxy & p057,
347        /* const */ sc_bind_proxy & p058,
348        /* const */ sc_bind_proxy & p059,
349        /* const */ sc_bind_proxy & p060,
350        /* const */ sc_bind_proxy & p061,
351        /* const */ sc_bind_proxy & p062,
352        /* const */ sc_bind_proxy & p063,
353        /* const */ sc_bind_proxy & p064)
354{
355    port_list_t port_list;
356    get_port_list(*this, port_list);
357    cerr << "port list : " << port_list << endl;
358    port_list_t::iterator p = port_list.begin();
359    BIND(p001);
360    BIND(p002);
361    BIND(p003);
362    BIND(p004);
363    BIND(p005);
364    BIND(p006);
365    BIND(p007);
366    BIND(p008);
367    BIND(p009);
368    BIND(p010);
369    BIND(p011);
370    BIND(p012);
371    BIND(p013);
372    BIND(p014);
373    BIND(p015);
374    BIND(p016);
375    BIND(p017);
376    BIND(p018);
377    BIND(p019);
378    BIND(p020);
379    BIND(p021);
380    BIND(p022);
381    BIND(p023);
382    BIND(p024);
383    BIND(p025);
384    BIND(p026);
385    BIND(p027);
386    BIND(p028);
387    BIND(p029);
388    BIND(p030);
389    BIND(p031);
390    BIND(p032);
391    BIND(p033);
392    BIND(p034);
393    BIND(p035);
394    BIND(p036);
395    BIND(p037);
396    BIND(p038);
397    BIND(p039);
398    BIND(p040);
399    BIND(p041);
400    BIND(p042);
401    BIND(p043);
402    BIND(p044);
403    BIND(p045);
404    BIND(p046);
405    BIND(p047);
406    BIND(p048);
407    BIND(p049);
408    BIND(p050);
409    BIND(p051);
410    BIND(p052);
411    BIND(p053);
412    BIND(p054);
413    BIND(p055);
414    BIND(p056);
415    BIND(p057);
416    BIND(p058);
417    BIND(p059);
418    BIND(p060);
419    BIND(p061);
420    BIND(p062);
421    BIND(p063);
422    BIND(p064);
423}
424
425
426ostream & operator << (ostream & o, const sc_module & m) {
427    return o << m.name();
428}
429
430
431// ----------------------------------------------------------------------------
432//  CLASS : sc_module_name
433//                                               
434// ----------------------------------------------------------------------------
435
436sc_module_name::sc_module_name(const char * name_) : m_pushed(true) {
437    m_name = name_;
438    init();
439}
440
441
442sc_module_name::sc_module_name(const sc_module_name & module) : m_pushed(false) {
443    m_name = module.m_name;
444}
445
446
447void sc_module_name::init() {
448    sc_core::module_name_stack.push_back(m_name);
449    modules_stack.push(NULL);
450}
451
452
453sc_module_name::~sc_module_name() {
454    if (m_pushed == false) {
455        return;
456    }
457    assert(sc_core::module_name_stack.empty() == false);
458    sc_core::module_name_stack.pop_back();
459    modules_stack.pop();
460    assert(temp_list.empty() == false);
461    sc_module * last1 = temp_list.back();
462    temp_list.pop_back();
463    sc_module * last2 = (temp_list.empty()) ? NULL : temp_list.back();
464    set_parent(*last1, last2);
465}
466
467
468std::ostream & operator << (std::ostream & o, const sc_core::sc_module_name & n) {
469    return o << (const char *) n;
470}
471
472/////////////////////////////////////////:
473
474static void check_method_process(const method_process_t & m) {
475    if (m.dont_initialize == false) {
476        assert(m.module != NULL);
477#ifdef CONFIG_DEBUG
478        std::cerr << "Warning : SystemCASS doesn't perform SC_METHOD(S) initializations.\n"
479            << "Please turn off automatic initialization for '" << m.name
480            << "' method of '" << m.module->name() << "' module"
481            " by calling 'dont_initialize()' function.\n"
482            "Example :\n"
483            "  SC_METHOD(transition);\n"
484            "  sensitive << clk;\n"
485            "  dont_initialize();\n";
486#endif
487    }
488}
489
490
491void check_all_method_process() {
492    method_process_list_t::const_iterator i;
493    for (i = sc_core::method_process_list.begin(); i != sc_core::method_process_list.end(); ++i) {
494        check_method_process(**i);
495    }
496}
497
498
499void valid_method_process() {
500    method_process_t * m = sc_core::method_process_list.back();
501    m->dont_initialize = true;
502}
503
504
505method_process_t * create_method_process(const char * name, SC_ENTRY_FUNC func, sc_module & module) {
506    return new method_process_t(name, func, module);
507}
508
509
510} // end of sc_core namespace
511
512/*
513# Local Variables:
514# tab-width: 4;
515# c-basic-offset: 4;
516# c-file-offsets:((innamespace . 0)(inline-open . 0));
517# indent-tabs-mode: nil;
518# End:
519#
520# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
521*/
522
Note: See TracBrowser for help on using the repository browser.