source: sources/src/sc_module.cc @ 46

Last change on this file since 46 was 35, checked in by buchmann, 15 years ago

Code cleanup.

Add --dynamiclink option to systemcass executable.

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