source: sources/src/global_functions.cc @ 29

Last change on this file since 29 was 27, checked in by buchmann, 16 years ago

SystemCASS now uses autoconf/automake to build the API. Regression tests still
use the old Makefiles.
(thanks to Nicolas Pouillon)

The library directory no longer is "lib-arch-system". The directory now is "lib-linux". Everyone needs to pay attention about SYSTEMCASS environment variable.

Changes:

  • system header includes
  • Add includes to config.h (generated by autoconf/automake)
  • test:
    • linux preprocessor macro instead of _WIN32
    • CONFIG_DEBUG instead of DEBUG

Removes:

  • Makefile
  • guess_endianness.cc
  • guess_os.sh
  • assert.h (we now use standard assert.h)
  • Options.def
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  // Init variables to be able to run combinational functions
264#ifdef CONFIG_CHECK_FSM_RULES
265        casc_fsm_step = STIMULI;
266#endif
267
268  pending_write_vector_capacity = get_signal_table_size ();
269#if 0
270  cerr << "pending_write_vector_capacity = " << pending_write_vector_capacity
271<< "\n";
272#endif
273  if (pending_write_vector_capacity == 0)
274    pending_write_vector = NULL;
275  else
276                pending_write_vector = (pending_write_vector_t) realloc (pending_write_vector, sizeof (pending_write) * pending_write_vector_capacity);
277       
278  // create the clock list
279        clock_list_t clock_list;
280  create_clock_list (clock_list, get_equi_list ());
281  if (dump_netlist_info)
282    cerr << "Clock list\n"
283         << "----------\n"
284         << clock_list << "\n\n";
285
286  // Check if a clock exists in the system
287  if (clock_list.empty ()) {
288    cerr << "System need a clock.\n"
289         << "Please define system clock using special type \"sc_clock\".\n";
290    exit (22);
291  }
292
293        // Check if any constructor wrote into registers
294        if (pending_write_vector_nb != 0)
295        {
296                cerr << "Error : Register/Signal writing is not allowed before sc_initialize.\n"
297                        "Move initializations from constructors/sc_main to module reset sequences.\n";
298                // we are unable to dump register(s) name(s)
299                // because the table binding is not yet completed.
300                exit (24);
301        }
302 
303  string base_name = get_scheduling (scheduling_method);
304
305  if (dynamic_link_of_scheduling_code)
306    compile_and_link (base_name.c_str());
307  else
308    use_static_func ();
309 
310        pending_write_vector_nb = 0;
311 
312  check_all_ports ();
313  usage.start ();
314  if (dump_stage)
315    cerr << "sc_initialize () done.\n";
316  already_initialized = true;
317}
318
319inline
320void
321check_and_initialize ()
322{
323  if (already_initialized == false) {
324#if defined(SYSTEMC_VERSION_1_0)
325                std::cerr << "Warning : call sc_initialize before executiong simulation.\n";
326#endif
327    internal_sc_initialize ();
328    if (dump_module_hierarchy)
329      module_hierarchy2dot (dump_module_hierarchy);
330    if (nosimulation)
331    {
332      exit (0);
333    }
334        }
335}
336
337void sc_initialize(void) 
338{
339  cerr << "Warning : 'sc_initialize' function is deprecated since SystemC 2.1.\n"; 
340  cerr << "Use 'sc_start(0)' instead.\n"; 
341  check_and_initialize ();
342}
343
344/* ********** */
345/* simulating */
346/* ********** */
347
348inline 
349void 
350sc_cycle( double duration)
351{
352  check_and_initialize ();
353  sc_core::internal_sc_cycle0(duration);
354}
355
356inline
357void 
358sc_cycle( double       duration,
359          sc_time_unit time_unit )
360{
361  check_and_initialize ();
362  sc_core::internal_sc_cycle0(duration);
363}
364
365void 
366sc_start(double d_val)
367{
368        sc_cycle (d_val);
369#ifdef DUMP_SIGNAL_STATS
370        print_registers_writing_stats (cerr);
371#endif
372#ifdef DUMP_SCHEDULE_STATS
373        print_schedule_stats (cerr);
374#endif
375}
376
377void 
378sc_start()
379{
380        sc_cycle (-1);
381#ifdef DUMP_SIGNAL_STATS
382        print_registers_writing_stats (cerr);
383#endif
384#ifdef DUMP_SCHEDULE_STATS
385        print_schedule_stats (cerr);
386#endif
387}
388
389void
390sc_start (double       d_val,
391          sc_time_unit d_tu)
392{
393  sc_start (sc_time (d_val, d_tu));
394}
395
396void
397sc_start( const sc_time& duration )
398{
399        sc_cycle ((double)duration);
400#ifdef DUMP_SIGNAL_STATS
401        print_registers_writing_stats (cerr);
402#endif
403#ifdef DUMP_SCHEDULE_STATS
404        print_schedule_stats (cerr);
405#endif
406}
407
408/* ****************** */
409/* stoping simulation */
410/* ****************** */
411
412bool         have_to_stop = false;
413sc_stop_mode stop_mode    = SC_STOP_FINISH_DELTA;
414
415void
416sc_stop ()
417{
418  switch (stop_mode)
419  {
420  case SC_STOP_IMMEDIATE    :
421    exit (54);
422    break;
423  case SC_STOP_FINISH_DELTA :
424  default :
425    have_to_stop = true;
426    break;
427  }
428}
429
430void
431sc_set_stop_mode (sc_stop_mode new_mode)
432{
433  if (new_mode == SC_STOP_IMMEDIATE)
434    stop_mode = SC_STOP_IMMEDIATE;
435}
436
437sc_stop_mode
438sc_get_stop_mode ()
439{
440  return stop_mode;
441}
442
443void
444close_systemcass ()
445{
446  unlink ();
447  if (print_user_resources)
448  {
449    usage.stop ();
450    unsigned int d = usage;
451    cerr << "Performances\n"
452            "------------\n";
453    cerr << "Time elapsed (sec) : " << d << endl;
454    cerr << "Cycles done        : " << nb_cycles << endl;
455    //sc_simulation_time () << endl;
456    if (d == 0)
457      cerr << "Performance (c/s)  : N/A" << endl;
458    else
459      cerr << "Performance (c/s)  : " << nb_cycles / d << endl;
460//    cerr << "Memory used        : " << usage.get_memory_size () << endl;
461  }
462}
463
464/////////////////////////
465
466} // end of sc_core namespace
467
Note: See TracBrowser for help on using the repository browser.