source: sources/src/sc_module.cc @ 22

Last change on this file since 22 was 12, checked in by buchmann, 16 years ago

Changes:

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