source: sources/src/global_functions.cc @ 16

Last change on this file since 16 was 4, checked in by nipo, 17 years ago

Towards SystemC-2.2 LRM:

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