source: sources/src/global_functions.cc @ 32

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

Changes:

  • rename pending_write into pending_write_t
  • indent code
File size: 11.0 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                 global_functions.cc               |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Nicolas Pouillon                  |
9|                                                             |
10| Date    :                   21_09_2005                      |
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 <iostream>
38#include <dlfcn.h>
39#include "schedulers.h" // get_scheduling & run_schedule_editor
40#include "sc_module.h" // check_all_method_process
41#include "gen_code.h"  // gen_scheduling_code_for_dynamic_link & gen_scheduling_code_for_static_func
42#include "sc_clock_ext.h" // clock list
43#include "usage.h"
44#include "module_hierarchy2dot.h"
45#include "assert.h"
46#ifdef HAVE_CONFIG_H
47#include "config.h"
48#endif
49
50#ifdef CONFIG_CHECK_FSM_RULES
51#include "fsm_rules.h"
52#endif
53
54using namespace std;
55
56namespace sc_core {
57
58const char *temporary_dir = "/tmp";
59const char *generated_files_dir = "./generated_by_systemcass";
60
61static usage_t usage;
62
63/* ***************************** */
64/* Dumping functions (for debug) */
65/* ***************************** */
66
67template <typename T>
68ostream& operator << (ostream &o, const vector<T*> &v)
69{
70  typename vector<T*>::const_iterator i;
71  for (i = v.begin(); i != v.end(); ++i) {
72    o << **i << " ";
73  }
74  return o;
75}
76
77/* ************ */
78/*  clock list  */
79/****************/
80
81typedef std::set<const sc_clock*> clock_list_t;
82
83ostream& 
84operator << (ostream &o,
85             const clock_list_t &cl)
86{
87  clock_list_t::const_iterator i;
88  for (i = cl.begin(); i != cl.end(); ++i) {
89    o << (*i)->name () << " ";
90  }
91  return o;
92}
93
94// clock list
95void 
96create_clock_list (clock_list_t  &c,
97                   const equi_list_t &el)
98{
99        equi_list_t::const_iterator i;
100        for (i = el.begin (); i != el.end(); ++i) {
101                equi_t::const_iterator j;
102                for (j = i->begin (); j != i->end (); ++j) {
103                        if (j->kind () == sc_clock::kind_string)
104                                c.insert ((const sc_clock*)j->object);
105          }
106        }
107}
108
109/* ************ */
110/*  functions   */
111/****************/
112
113// function pointer to the simulation core (compiled and linked dynamically)
114evaluation_fct_t func_simulate_1_cycle = NULL;
115evaluation_fct_t func_combinationals = NULL;
116
117/* ************ */
118/* dynamic link */
119/* ************ */
120
121static void *handle = NULL;
122
123static
124void 
125link (const char *lib)
126{
127  // chargement du code de simulate_1_cycle
128  handle = dlopen(lib, RTLD_GLOBAL | RTLD_NOW);
129  //handle = dlopen(lib, RTLD_LAZY | RTLD_GLOBAL | RTLD_NOW);
130 
131  if (handle == NULL) {
132    const char *error = dlerror ();
133    if (error)
134      fprintf (stderr, "dlopen: %s\n",error);
135    fprintf (stderr, 
136             "Is there -rdynamic option into your command line ? "
137             "If not, please do it.\n");
138    exit(18);
139  }
140
141  union uni_fct_t {
142    evaluation_fct_t fct_type;
143    void            *dl_pointer_type;
144  };
145  uni_fct_t        temp; 
146  temp.dl_pointer_type = dlsym (handle,"initialize");
147  if (temp.dl_pointer_type == NULL) {
148    const char *error = dlerror ();
149    if (error)
150      fprintf (stderr, "dlsym: %s\n",error);
151    exit(19);
152  }
153  evaluation_fct_t func_initialize;
154  func_initialize = temp.fct_type;
155  func_initialize ();
156
157  temp.dl_pointer_type = dlsym (handle,"simulate_1_cycle");
158  if (temp.dl_pointer_type == NULL) {
159    const char *error = dlerror ();
160    if (error)
161      fprintf (stderr, "dlsym: %s\n",error);
162    exit(20);
163  }
164  func_simulate_1_cycle = temp.fct_type;
165 
166  temp.dl_pointer_type = dlsym (handle,"mealy_generation");
167  if (temp.dl_pointer_type == NULL) {
168    const char *error = dlerror ();
169    if (error)
170      fprintf (stderr, "dlsym: %s\n",error);
171    exit(21);
172  } 
173  func_combinationals = temp.fct_type;
174
175  /*
176   *
177   */
178  if (dump_stage)
179    cerr << "dynamic link done\n";
180}
181
182static
183void
184unlink ()
185{
186  if (handle)
187  {
188    if (dlclose (handle) != 0)
189      cerr << "Warning : dlclose returns an error.\n" 
190           << dlerror () << endl;
191    handle = NULL;
192  }
193}
194
195/* ************ */
196/* initializing */
197/* ************ */
198
199bool  already_initialized = false;
200
201static
202void
203use_static_func ()
204{
205  if (dump_stage)
206    cerr << "Using static functions to schedule SystemC processes.\n";
207  if (scheduling_method == CASS_SCHEDULING)
208  {
209    func_simulate_1_cycle = (evaluation_fct_t)sc_core::quasistatic_simulate_1_cycle;
210    func_combinationals   = (evaluation_fct_t)sc_core::quasistatic_mealy_generation;
211  } else {
212    func_simulate_1_cycle = (evaluation_fct_t)sc_core::static_simulate_1_cycle;
213    func_combinationals   = (evaluation_fct_t)sc_core::static_mealy_generation;
214  }
215}
216
217static
218void
219compile_and_link (const char *base_name)
220{
221  if (dump_stage)
222    cerr << "Using dynamically loaded functions to schedule SystemC processes.\n";
223  // compilation du code de simulate_1_cycle
224  compile_code(base_name);
225   
226  char lib_absolutepath[256]; 
227#if defined(CONFIG_OS_DARWIN)
228  sprintf(lib_absolutepath, "/tmp/%s.so", base_name);
229#elif defined(CONFIG_OS_LINUX)
230  sprintf(lib_absolutepath, "/tmp/%s.so", base_name);
231#else
232  cerr << "ERROR\n"; exit (126);
233#endif
234 
235        link (lib_absolutepath);
236}
237
238static
239void 
240internal_sc_initialize (void) 
241{
242  sort_equi_list ();
243
244  check_all_method_process ();
245
246  if (dump_netlist_info)
247    cerr << "Module instance list\n"
248         << "--------------------\n" 
249         << instances_set << endl;
250 
251  /*
252   * Initialize the signals table
253   */
254  create_signals_table ();
255  bind_to_table ();
256  if (dump_netlist_info)
257  {
258    print_table (cerr);
259    cerr << endl;
260    print_table_stats (cerr);
261    cerr << endl;
262  }
263
264  // Init variables to be able to run combinational functions
265#ifdef CONFIG_CHECK_FSM_RULES
266  casc_fsm_step = STIMULI;
267#endif
268
269  pending_write_vector_capacity = get_signal_table_size ();
270#if 0
271  cerr << "pending_write_vector_capacity = " << pending_write_vector_capacity
272<< "\n";
273#endif
274  if (pending_write_vector_capacity == 0)
275    pending_write_vector = NULL;
276  else
277    pending_write_vector = (pending_write_vector_t) realloc (pending_write_vector, sizeof (pending_write_t) * pending_write_vector_capacity);
278       
279  // create the clock list
280  clock_list_t clock_list;
281  create_clock_list (clock_list, get_equi_list ());
282  if (dump_netlist_info)
283    cerr << "Clock list\n"
284         << "----------\n"
285         << clock_list << "\n\n";
286
287  // Check if a clock exists in the system
288  if (clock_list.empty ()) {
289    cerr << "System need a clock.\n"
290         << "Please define system clock using special type \"sc_clock\".\n";
291    exit (22);
292  }
293
294  // Check if any constructor wrote into registers
295  if (pending_write_vector_nb != 0)
296        {
297                cerr << "Error : Register/Signal writing is not allowed before sc_initialize.\n"
298                        "Move initializations from constructors/sc_main to module reset sequences.\n";
299                // we are unable to dump register(s) name(s)
300                // because the table binding is not yet completed.
301                exit (24);
302        }
303 
304  string base_name = get_scheduling (scheduling_method);
305
306  if (dynamic_link_of_scheduling_code)
307    compile_and_link (base_name.c_str());
308  else
309    use_static_func ();
310 
311  pending_write_vector_nb = 0;
312 
313  check_all_ports ();
314  usage.start ();
315
316  if (dump_stage)
317    cerr << "sc_initialize () done.\n";
318
319  already_initialized = true;
320}
321
322inline
323void
324check_and_initialize ()
325{
326  if (already_initialized == false) {
327#if defined(SYSTEMC_VERSION_1_0)
328    std::cerr << "Warning : call sc_initialize before executiong simulation.\n";
329#endif
330    internal_sc_initialize ();
331    if (dump_module_hierarchy)
332      module_hierarchy2dot (dump_module_hierarchy);
333    if (nosimulation)
334    {
335      exit (0);
336    }
337  }
338}
339
340void sc_initialize(void) 
341{
342  cerr << "Warning : 'sc_initialize' function is deprecated since SystemC 2.1.\n"; 
343  cerr << "Use 'sc_start(0)' instead.\n"; 
344  check_and_initialize ();
345}
346
347/* ********** */
348/* simulating */
349/* ********** */
350
351inline 
352void 
353sc_cycle( double duration)
354{
355  check_and_initialize ();
356  sc_core::internal_sc_cycle0(duration);
357}
358
359inline
360void 
361sc_cycle( double       duration,
362          sc_time_unit time_unit )
363{
364  check_and_initialize ();
365  sc_core::internal_sc_cycle0(duration);
366}
367
368void 
369sc_start(double d_val)
370{
371  sc_cycle (d_val);
372#ifdef DUMP_SIGNAL_STATS
373  print_registers_writing_stats (cerr);
374#endif
375#ifdef DUMP_SCHEDULE_STATS
376  print_schedule_stats (cerr);
377#endif
378}
379
380void 
381sc_start()
382{
383  sc_cycle (-1);
384#ifdef DUMP_SIGNAL_STATS
385  print_registers_writing_stats (cerr);
386#endif
387#ifdef DUMP_SCHEDULE_STATS
388  print_schedule_stats (cerr);
389#endif
390}
391
392void
393sc_start (double       d_val,
394          sc_time_unit d_tu)
395{
396  sc_start (sc_time (d_val, d_tu));
397}
398
399void
400sc_start( const sc_time& duration )
401{
402  sc_cycle ((double)duration);
403#ifdef DUMP_SIGNAL_STATS
404  print_registers_writing_stats (cerr);
405#endif
406#ifdef DUMP_SCHEDULE_STATS
407  print_schedule_stats (cerr);
408#endif
409}
410
411/* ****************** */
412/* stoping simulation */
413/* ****************** */
414
415bool         have_to_stop = false;
416sc_stop_mode stop_mode    = SC_STOP_FINISH_DELTA;
417
418void
419sc_stop ()
420{
421  switch (stop_mode)
422  {
423  case SC_STOP_IMMEDIATE    :
424    exit (54);
425    break;
426  case SC_STOP_FINISH_DELTA :
427  default :
428    have_to_stop = true;
429    break;
430  }
431}
432
433void
434sc_set_stop_mode (sc_stop_mode new_mode)
435{
436  if (new_mode == SC_STOP_IMMEDIATE)
437    stop_mode = SC_STOP_IMMEDIATE;
438}
439
440sc_stop_mode
441sc_get_stop_mode ()
442{
443  return stop_mode;
444}
445
446void
447close_systemcass ()
448{
449  unlink ();
450  if (print_user_resources)
451  {
452    usage.stop ();
453    unsigned int d = usage;
454    cerr << "Performances\n"
455            "------------\n";
456    cerr << "Time elapsed (sec) : " << d << endl;
457    cerr << "Cycles done        : " << nb_cycles << endl;
458    //sc_simulation_time () << endl;
459    if (d == 0)
460      cerr << "Performance (c/s)  : N/A" << endl;
461    else
462      cerr << "Performance (c/s)  : " << nb_cycles / d << endl;
463//    cerr << "Memory used        : " << usage.get_memory_size () << endl;
464  }
465}
466
467/////////////////////////
468
469} // end of sc_core namespace
470
Note: See TracBrowser for help on using the repository browser.