source: branches/with_autoconf/src/sc_module.cc @ 8

Last change on this file since 8 was 8, checked in by nipo, 16 years ago

Checkin autotools magic

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