source: sources/src/sc_module.cc @ 3

Last change on this file since 3 was 1, checked in by buchmann, 17 years ago

Initial import from CVS repository

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