source: sources/src/global_functions.cc@ 16

Last change on this file since 16 was 4, checked in by nipo, 19 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.