source: sources/src/global_functions.cc @ 47

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

This patch simplifies SystemCASS.

Remove:

  • ckeckings about multiwriting on registers and ports
  • checkings related to FSM modeling
  • regression tests related to the checkings
File size: 10.8 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
51using namespace std;
52
53namespace sc_core {
54
55const char *temporary_dir = "/tmp";
56const char *generated_files_dir = "./generated_by_systemcass";
57
58static usage_t usage;
59
60/* ***************************** */
61/* Dumping functions (for debug) */
62/* ***************************** */
63
64template <typename T>
65ostream& operator << (ostream &o, const vector<T*> &v)
66{
67  typename vector<T*>::const_iterator i;
68  for (i = v.begin(); i != v.end(); ++i) {
69    o << **i << " ";
70  }
71  return o;
72}
73
74/* ************ */
75/*  clock list  */
76/****************/
77
78typedef std::set<const sc_clock*> clock_list_t;
79
80ostream& 
81operator << (ostream &o,
82             const clock_list_t &cl)
83{
84  clock_list_t::const_iterator i;
85  for (i = cl.begin(); i != cl.end(); ++i) {
86    o << (*i)->name () << " ";
87  }
88  return o;
89}
90
91// clock list
92void 
93create_clock_list (clock_list_t  &c,
94                   const equi_list_t &el)
95{
96  equi_list_t::const_iterator i;
97  for (i = el.begin (); i != el.end(); ++i) {
98    equi_t::const_iterator j;
99    for (j = i->begin (); j != i->end (); ++j) {
100      if (j->kind () == sc_clock::kind_string)
101        c.insert ((const sc_clock*)j->object);
102    }
103  }
104}
105
106/* ************ */
107/*  functions   */
108/****************/
109
110// function pointer to the simulation core (compiled and linked dynamically)
111evaluation_fct_t func_simulate_1_cycle = NULL;
112evaluation_fct_t func_combinationals = NULL;
113
114/* ************ */
115/* dynamic link */
116/* ************ */
117
118static void *handle = NULL;
119
120static
121void 
122link (const char *lib)
123{
124  // chargement du code de simulate_1_cycle
125  handle = dlopen(lib, RTLD_GLOBAL | RTLD_NOW);
126  //handle = dlopen(lib, RTLD_LAZY | RTLD_GLOBAL | RTLD_NOW);
127 
128  if (handle == NULL) {
129    const char *error = dlerror ();
130    if (error)
131      fprintf (stderr, "dlopen: %s\n",error);
132    fprintf (stderr, 
133             "Is there -rdynamic option into your command line ? "
134             "If not, please do it.\n");
135    exit(18);
136  }
137
138  union uni_fct_t {
139    evaluation_fct_t fct_type;
140    void            *dl_pointer_type;
141  };
142  uni_fct_t        temp; 
143  temp.dl_pointer_type = dlsym (handle,"initialize");
144  if (temp.dl_pointer_type == NULL) {
145    const char *error = dlerror ();
146    if (error)
147      fprintf (stderr, "dlsym: %s\n",error);
148    exit(19);
149  }
150  evaluation_fct_t func_initialize;
151  func_initialize = temp.fct_type;
152  func_initialize ();
153
154  temp.dl_pointer_type = dlsym (handle,"simulate_1_cycle");
155  if (temp.dl_pointer_type == NULL) {
156    const char *error = dlerror ();
157    if (error)
158      fprintf (stderr, "dlsym: %s\n",error);
159    exit(20);
160  }
161  func_simulate_1_cycle = temp.fct_type;
162 
163  temp.dl_pointer_type = dlsym (handle,"mealy_generation");
164  if (temp.dl_pointer_type == NULL) {
165    const char *error = dlerror ();
166    if (error)
167      fprintf (stderr, "dlsym: %s\n",error);
168    exit(21);
169  } 
170  func_combinationals = temp.fct_type;
171
172  /*
173   *
174   */
175  if (dump_stage)
176    cerr << "dynamic link done\n";
177}
178
179static
180void
181unlink ()
182{
183  if (handle)
184  {
185    if (dlclose (handle) != 0)
186      cerr << "Warning : dlclose returns an error.\n" 
187           << dlerror () << endl;
188    handle = NULL;
189  }
190}
191
192/* ************ */
193/* initializing */
194/* ************ */
195
196bool  already_initialized = false;
197
198static
199void
200use_static_func ()
201{
202  if (dump_stage)
203    cerr << "Using static functions to schedule SystemC processes.\n";
204  if (scheduling_method == CASS_SCHEDULING)
205  {
206    func_simulate_1_cycle = (evaluation_fct_t)sc_core::quasistatic_simulate_1_cycle;
207    func_combinationals   = (evaluation_fct_t)sc_core::quasistatic_mealy_generation;
208  } else {
209    func_simulate_1_cycle = (evaluation_fct_t)sc_core::static_simulate_1_cycle;
210    func_combinationals   = (evaluation_fct_t)sc_core::static_mealy_generation;
211  }
212}
213
214static
215void
216compile_and_link (const char *base_name)
217{
218  if (dump_stage)
219    cerr << "Using dynamically loaded functions to schedule SystemC processes.\n";
220  // compilation du code de simulate_1_cycle
221  compile_code(base_name);
222   
223  char lib_absolutepath[256]; 
224#if defined(CONFIG_OS_DARWIN)
225  sprintf(lib_absolutepath, "/tmp/%s.so", base_name);
226#elif defined(CONFIG_OS_LINUX)
227  sprintf(lib_absolutepath, "/tmp/.libs/%s.so.0", base_name);
228#else
229  cerr << "ERROR\n"; exit (126);
230#endif
231 
232  link (lib_absolutepath);
233}
234
235static
236void 
237internal_sc_initialize (void) 
238{
239  sort_equi_list ();
240
241  check_all_method_process ();
242
243  if (dump_netlist_info)
244    cerr << "Module instance list\n"
245         << "--------------------\n" 
246         << instances_set << endl;
247 
248  /*
249   * Initialize the signals table
250   */
251  create_signals_table ();
252  bind_to_table ();
253  if (dump_netlist_info)
254  {
255    print_table (cerr);
256    cerr << endl;
257    print_table_stats (cerr);
258    cerr << endl;
259  }
260
261  // Init variables to be able to run combinational functions
262  pending_write_vector_capacity = get_signal_table_size ();
263
264  if (pending_write_vector_capacity == 0)
265    pending_write_vector = NULL;
266  else
267    pending_write_vector = (pending_write_vector_t) realloc (pending_write_vector, sizeof (pending_write_t) * pending_write_vector_capacity);
268 
269  // create the clock list
270  clock_list_t clock_list;
271  create_clock_list (clock_list, get_equi_list ());
272  if (dump_netlist_info)
273    cerr << "Clock list\n"
274         << "----------\n"
275         << clock_list << "\n\n";
276
277  // Check if a clock exists in the system
278  if (clock_list.empty ()) {
279    cerr << "System need a clock.\n"
280         << "Please define system clock using special type \"sc_clock\".\n";
281    exit (22);
282  }
283
284  // Check if any constructor wrote into registers
285  if (pending_write_vector_nb != 0)
286  {
287    cerr << "Error : Register/Signal writing is not allowed before sc_initialize.\n"
288      "Move initializations from constructors/sc_main to module reset sequences.\n";
289    // we are unable to dump register(s) name(s)
290    // because the table binding is not yet completed.
291    exit (24);
292  }
293 
294  string base_name = get_scheduling (scheduling_method);
295
296  if (dynamic_link_of_scheduling_code)
297    compile_and_link (base_name.c_str());
298  else
299    use_static_func ();
300 
301  pending_write_vector_nb = 0;
302 
303  check_all_ports ();
304  usage.start ();
305
306  if (dump_stage)
307    cerr << "sc_initialize () done.\n";
308
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.