source: sources/src/global_functions.cc @ 56

Last change on this file since 56 was 52, checked in by meunier, 12 years ago

Code formatting in all source files.

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