source: sources/src/global_functions.cc@ 59

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