source: sources/src/global_functions.cc @ 37

Last change on this file since 37 was 36, checked in by joel.porquet@…, 15 years ago

Make dynamic compile&link work on x86 32 bits.

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