source: sources/src/sc_module.cc @ 65

Last change on this file since 65 was 65, checked in by bouyer, 5 years ago

Various performance improvements for the parallel systemcass: cache-aligned
data structures, write only when needed, disable some unneeded barriers.

Fix bug in the non-openmp case: a pointer was not initialized

various style updates

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