source: sources/src/gen_code.cc

Last change on this file was 65, checked in by bouyer, 5 years ago

Various performance improvements for the parallel systemcass: cache-aligned
data structures, write only when needed, disable some unneeded barriers.

Fix bug in the non-openmp case: a pointer was not initialized

various style updates

File size: 20.9 KB
Line 
1/*------------------------------------------------------------\
2  |                                                             |
3  | Tool    :                  systemcass                       |
4  |                                                             |
5  | File    :                 gen_code.cc                       |
6  |                                                             |
7  | Author  :                 Taktak Sami                       |
8  |                           Buchmann Richard                  |
9  |                                                             |
10  | Date    :                   09_07_2004                      |
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#if defined(__linux__)
38#include <linux/limits.h>
39#elif defined(WIN32)
40#include <windows.h>
41#elif defined(__MACH__)
42#include <sys/syslimits.h>
43#endif
44
45#include <unistd.h>
46#include <cstring>
47#include <cstdio>
48#include <cstdlib>
49#include <iostream>
50#include <fstream>
51#ifdef _OPENMP
52#include <omp.h>
53#endif
54#include <sys/types.h>
55#include <unistd.h>
56
57#include "internal.h"
58#include "gen_code.h"
59#include "sc_module.h"
60#include "sc_ver.h"
61#include "process_dependency.h"
62
63#ifdef HAVE_CONFIG_H
64#include "config.h"
65#endif
66
67#define casc_cflags GENERATED_MODULE_CFLAGS
68
69// Enable CPP call, this is useful for typeinfo-enabled classes
70#define CPP_CALL
71
72using namespace std;
73
74namespace sc_core {
75
76static void PrintCall(std::ostream &, const method_process_t &);
77static void open_temp(std::ofstream &, char *);
78typedef void (*CASC_ENTRY_FUNC) (void *);
79typedef union {
80    unsigned long long int integer;
81    SC_ENTRY_FUNC pmf;
82    CASC_ENTRY_FUNC pf;
83} fct;
84
85
86const char * get_pmf_type() {
87    switch (sizeof(SC_ENTRY_FUNC)) {
88        case 4:
89            // G4 pointer-to-member-function style
90            return "unsigned long int";
91        case 8:
92            // PC pointer-to-member-function style
93            return "unsigned long long int";
94        default:
95            cerr <<
96                "Internal Error : Unsupported pointer-to-member-function"
97                "(size: " << sizeof(SC_ENTRY_FUNC) << ").\n"
98                "Please try --nodynamiclink option.\n";
99            exit(21072009);
100    };
101}
102
103
104static ostream & operator <<(ostream & o, const SC_ENTRY_FUNC & f) {
105    register fct p;
106    p.integer = 0;
107    p.pmf = f;
108    return o << "0x" << hex << p.integer << "ULL";
109}
110
111
112static void PrintCall(std::ostream & o, const method_process_t & m) {
113    SC_ENTRY_FUNC func = m.func;
114    if (print_schedule) {
115        o << "    fprintf(stderr,\"evaluation de " << m.module->name() << "->" << m.name << "()\\n\");\n";
116    }
117    o << " p.integer = " << func << ";\n";
118#ifdef CPP_CALL
119    o << " (((sc_module*)(" << m.module << "))->*(p.pmf)) (); /* " << m.module->name() << "->" << m.name << "() */\n";
120#else
121    o << " p.pf((void *)" << m.module << "); /* " << m.module->name() << "->" << m.name << "() */\n";
122#endif
123}
124
125
126static bool is_exist(const char * temp) {
127    ifstream o;
128    o.open(temp, ios::in);
129    if (o.is_open() == false) {
130        return false;
131    }
132    if (o.peek() == -1) {
133        return false;
134    }
135    return true;
136}
137
138
139static void open_temp(ofstream & o, char * temp) {
140    /*
141       srand (time (NULL));
142       int r = rand () % 1000;
143       */
144    pid_t pid = getpid();
145    int r = -1;
146    do {
147        sprintf(temp, "%s/scheduling-%d-%x.cc", temporary_dir, pid, ++r);
148    } while (is_exist(temp));
149
150    o.open(temp, ios::out);
151    if (o.is_open() == false) {
152        cerr << "Error : Unable to open a file to write scheduling code.\n";
153        exit(30032005);
154    }
155#ifdef CONFIG_DEBUG
156    cerr << "opened temporary filename : " << temp << "\n";
157#endif
158    sprintf(temp, "scheduling-%d-%x", pid, r++);
159}
160
161
162static char * gen_transition(ofstream & o, method_process_list_t & transition_func_list) {
163    // transitions
164    o << "\ninline void transition(void)\n{\n";
165    if (transition_func_list.empty() == false) {
166        o << " /* fonctions de transition */\n" << " register fct p;\n";
167        method_process_list_t::iterator mm;
168        for (mm = transition_func_list.begin(); mm != transition_func_list.end(); ++mm) {
169            PrintCall(o, **mm);
170        }
171    }
172    o << "}\n";
173}
174
175
176static char * gen_moore(ofstream & o, method_process_list_t & moore_func_list) {
177    // Moore generations (sequential functions)
178    o << "\ninline void moore_generation (void)\n{\n";
179    if (moore_func_list.empty() == false) {
180        o << "  /* fonctions de generation de Moore */\n"
181            << " register fct p;\n";
182        method_process_list_t::reverse_iterator mm;
183        for (mm = moore_func_list.rbegin();
184                mm != moore_func_list.rend(); ++mm) {
185            PrintCall(o, **mm);
186        }
187    }
188    o << " \n}\n";
189}
190
191
192static char * gen_mealy(ofstream & o, strong_component_list_t & strongcomponents) {
193    // Mealy generations (combinational functions only)
194    o << "\nextern void mealy_generation (void)\n{\n";
195    if (strongcomponents.empty()) {
196        return NULL;
197    }
198    o << "  register fct p;\n" << "\n\n  /* fonctions de mealy */\n";
199#ifdef NO_STATIC_SCHEDULE
200    o << "\n  do {\n    unstable = 0;\n";
201#endif
202    strong_component_list_t::iterator ss;
203    for (ss = strongcomponents.begin(); ss != strongcomponents.end(); ++ss) {
204        if ((*ss)->size() == 1) {
205            /* un seul element dans le strong component */
206            method_process_t *m = (method_process_t *) (*((*ss)->begin()));
207            PrintCall(o, *m);
208            continue;
209        }
210        else {
211            /* plusieurs elements dans le strong component */
212#ifndef NO_STATIC_SCHEDULE
213            o << "\n  do {\n    unstable = 0;\n";
214#endif
215            component_list_t::reverse_iterator rev_mm;
216            for (rev_mm = (*ss)->rbegin(); rev_mm != (*ss)->rend(); ++rev_mm) {
217                method_process_t * m = (method_process_t *) * rev_mm;
218                PrintCall(o, *m);
219            }
220#ifndef NO_STATIC_SCHEDULE
221            o << "  } while ( unstable );\n\n";
222#endif
223        }
224    }
225#ifdef NO_STATIC_SCHEDULE
226    o << "  } while ( unstable );\n\n";
227#else
228    o << "\tunstable = 0;\n";
229#endif
230}
231
232
233static char * gen_mealy(ofstream & o, ProcessDependencyList & mealy_func_list) {
234    // Mealy generations (combinational functions only)
235    o << "\nextern void mealy_generation (void)\n{\n";
236    o << "  register fct p;\n" << "\n\n  /* fonctions de mealy */\n";
237    ProcessDependencyList::iterator it;
238    for (it = mealy_func_list.begin(); it != mealy_func_list.end(); ++it) {
239        const method_process_t * m = *it;
240        PrintCall(o, *m);
241    }
242}
243
244char *
245gen_scheduling_code_for_dynamic_link (
246               method_process_list_t           &transition_func_list,
247               method_process_list_t           &moore_func_list,
248               strong_component_list_t         *strongcomponents)
249{
250  if (dump_stage)
251    cerr << "Generating C code for scheduling...\n";
252
253    // open temporary file
254    ofstream o;
255    char base_name[PATH_MAX];
256    open_temp(o, base_name);
257
258    if (!o.good()) {
259        perror("scheduling: open file\n");
260        exit(-1);
261    }
262
263  o << "// generated by " << sc_version () << endl
264    << "#include <casc.h>\n\n"
265    << "#include <cstdio>\n\n"
266//  << "#include <iostream>\n\n"
267    << "namespace sc_core {\n"
268    << " typedef void (sc_module::*SC_ENTRY_FUNC)();\n"
269    << " typedef void (*CASC_ENTRY_FUNC)(void *);\n";
270
271    const char * pmf_type = get_pmf_type();
272
273    o << " typedef union { "
274        << pmf_type
275        << " integer; SC_ENTRY_FUNC pmf; CASC_ENTRY_FUNC pf; } fct;\n";
276
277    gen_transition(o, transition_func_list);
278    gen_moore(o, moore_func_list);
279    if (strongcomponents != NULL) {
280        gen_mealy      (o, *strongcomponents);
281    }
282
283    o << " \n}\n";
284    o << "\n} // end of sc_core namespace\n";
285
286    o.flush();
287    o.close();
288
289    // add "cc" extension
290    char file_name[PATH_MAX];
291    strncpy(file_name, base_name, PATH_MAX);
292    file_name[strlen(base_name)] = '\0';
293    strcat(file_name, ".cc");
294    rename(base_name, file_name);
295
296    if (edit_schedule) {
297        run_schedule_editor(file_name);
298    }
299
300    if (dump_stage) {
301        cerr << "Generating C code for scheduling done.\n";
302    }
303
304    return strdup(base_name);
305}
306
307
308char * gen_scheduling_code_for_dynamic_link(method_process_list_t & transition_func_list,
309        method_process_list_t & moore_func_list,
310        ProcessDependencyList & mealy_func_list) {
311    if (dump_stage) {
312        cerr << "Generating C code for scheduling...\n";
313    }
314
315    // open temporary file
316    ofstream o;
317    char base_name[PATH_MAX];
318    open_temp(o, base_name);
319
320    if (!o.good()) {
321        perror("scheduling: open file\n");
322        exit(-1);
323    }
324
325    o << "// generated by " << sc_version() << endl
326        << "#include <casc.h>\n\n" << "#include <cstdio>\n\n"
327        << "namespace sc_core {\n"
328        << " typedef void (sc_module::*SC_ENTRY_FUNC)();\n"
329        << " typedef void (*CASC_ENTRY_FUNC)(void *);\n"
330        <<
331        " typedef union { unsigned long long int integer; SC_ENTRY_FUNC pmf; CASC_ENTRY_FUNC pf; } fct;\n";
332
333    gen_transition(o, transition_func_list);
334    gen_moore(o, moore_func_list);
335    gen_mealy(o, mealy_func_list);
336
337    o << "\n}\n";
338    o << "\n} // end of sc_core namespace\n";
339
340    o.flush();
341    o.close();
342
343    // add "cc" extension
344    char file_name[PATH_MAX];
345    strncpy(file_name, base_name, PATH_MAX);
346    file_name[strlen(base_name)] = '\0';
347    strcat(file_name, ".cc");
348    rename(base_name, file_name);
349
350    if (edit_schedule) {
351        run_schedule_editor(file_name);
352    }
353
354    if (dump_stage) {
355        cerr << "Generating C code for scheduling done.\n";
356    }
357
358    return strdup(base_name);
359}
360
361
362/* base_name est la base du nom du fichier C++
363 * casc_cflags est une string qui correspond à $(INCLUDE) d'un Makefile
364 */
365void compile_code(const char * base_name, const char * casc_cflags2) {
366    if (dump_stage) {
367        cerr << "Compiling C/C++ code for scheduling...\n";
368    }
369    char compil_str[512];
370    const char * compiler = getenv("CXX");
371    const char * systemc_dir = getenv("SYSTEMCASS");
372    const char * default_compiler =
373#ifdef CPP_CALL
374        "g++";
375#else
376    "gcc";
377#endif
378
379    compiler = (compiler == NULL) ? default_compiler : compiler;
380    if (systemc_dir == NULL) {
381        systemc_dir = getenv("SYSTEMC");
382        if (systemc_dir == NULL) {
383            cerr << "Error : set SYSTEMCASS or SYSTEMC environnement variable to the SYSTEMCASS directory.\n";
384            exit(-1);
385        }
386    }
387
388    char target_name[128];
389    char source_name[128];
390    sprintf(target_name, "%s.lo", base_name);
391    sprintf(source_name, "%s.cc", base_name);
392
393    if (keep_generated_code) {
394        char lg_cde[256];
395        sprintf(lg_cde, "mkdir -p %s", generated_files_dir);
396        system(lg_cde);
397        sprintf(lg_cde, "cp %s/%s %s/", temporary_dir, source_name, generated_files_dir);
398        if (dump_stage) {
399            cerr << "$ " << lg_cde << "\n";
400        }
401        system(lg_cde);
402        sprintf(lg_cde, "(cd %s ; indent %s)", generated_files_dir, source_name);
403        if (dump_stage) {
404            cerr << "$ " << lg_cde << "\n";
405        }
406        system(lg_cde);
407    }
408    /* ******* */
409    /* COMPILE */
410    /* ******* */
411    const char * commandline_template =
412#if defined(CONFIG_OS_DARWIN)
413        "(cd %s ;"
414        " %s %s -DSCHEDULING_BY_CASC -I%s/include -fno-common -dynamic -o %s -c %s)"
415#elif defined(CONFIG_OS_LINUX)
416        "(cd %s ; libtool --mode=compile %s %s -DSCHEDULING_BY_CASC -I%s/include -shared -o %s -c %s)"
417#else
418        "(cd %s ;"
419        " %s %s -DSCHEDULING_BY_CASC -I%s/include -dynamiclib -o %s -c %s)"
420#endif
421        ;
422
423    string cflags = casc_cflags;
424    if (use_openmp) {
425        cflags += " -fopenmp";
426    }
427
428    sprintf(compil_str, commandline_template, temporary_dir, compiler, cflags.c_str(), systemc_dir, target_name, source_name);
429
430    if (dump_stage) {
431        cerr << "Executing command : " << compil_str << "\n";
432    }
433
434    if (system(compil_str)) {
435        perror("compil : system");
436        exit(-1);
437    }
438
439    /* **** */
440    /* LINK */
441    /* **** */
442    sprintf(target_name, "%s.la", base_name);
443
444#ifdef CONFIG_OS_LINUX
445    sprintf(source_name, "%s.lo", base_name);
446    sprintf(compil_str, "(cd %s ; pwd ; libtool --mode=link %s %s -module -shared -o %s %s -rpath /tmp)", /* -L. -L%s/lib-%s */
447            temporary_dir, compiler, casc_cflags, /*systemc_dir, target_arch, */
448            target_name, source_name);
449#else
450    sprintf(source_name, "%s.o", base_name);
451    sprintf(compil_str, "(cd %s ; pwd ; libtool -dynamic -o %s %s)", temporary_dir, target_name, source_name);
452#endif
453
454    if (dump_stage) {
455        cerr << "Executing command : " << compil_str << "\n";
456    }
457
458    if (system(compil_str)) {
459        perror("compil : system");
460        exit(-1);
461    }
462
463    system(compil_str);
464    if (dump_stage) {
465        cerr << "Compiling done.\n";
466    }
467}
468
469
470/* ********************************
471 * Function for static scheduling
472 */
473struct function_call {
474    fct * function;
475    void ** instance;
476    int func_number;
477};
478static function_call pf[3];
479
480
481void get_function_call(function_call & pf, method_process_list_t & func_list) {
482    pf.func_number = func_list.size();
483    pf.function = (fct *) malloc(sizeof(fct) * pf.func_number);
484    pf.instance = (void **) malloc(sizeof(void *) * pf.func_number);
485    method_process_list_t::iterator mm;
486    int i;
487    for (mm = func_list.begin(), i = 0; mm != func_list.end(); ++mm, ++i) {
488        const method_process_t * mp = *mm;
489        pf.function[i].pmf = (mp->func);
490        pf.instance[i] = (void *) (mp->module);
491    }
492}
493
494
495void get_function_call(function_call & pf, ProcessDependencyList & func_list) {
496    pf.func_number = func_list.size();
497    pf.function = (fct *) malloc(sizeof(fct) * pf.func_number);
498    pf.instance = (void **) malloc(sizeof(void *) * pf.func_number);
499    ProcessDependencyList::iterator it;
500    int i;
501    for (i = 0, it = func_list.begin(); it != func_list.end(); ++it, ++i) {
502        const method_process_t * mp = *it;
503        pf.function[i].pmf = (mp->func);
504        pf.instance[i] = (void *) (mp->module);
505    }
506}
507
508
509void gen_scheduling_code_for_static_func(method_process_list_t & transition_func_list,
510        method_process_list_t & moore_func_list,
511        ProcessDependencyList & mealy_func_list) {
512    if (dump_stage) {
513        cerr << "Generating scheduling...\n";
514    }
515
516    get_function_call(pf[0], transition_func_list);
517    get_function_call(pf[1], moore_func_list);
518    get_function_call(pf[2], mealy_func_list);
519
520    if (dump_stage) {
521        cerr << "Generating scheduling done.\n";
522    }
523}
524
525
526void call_functions(function_call & fc) {
527    int n = fc.func_number;
528    int i;
529    for (i = 0; i < n; ++i) {
530#if 0
531        //defined(CONFIG_DEBUG)
532        sc_module *m = (sc_module *) (fc.instance[i]);
533        cerr << m->name() << endl;
534#endif
535        fc.function[i].pf(fc.instance[i]);
536    }
537}
538
539void
540call_functions_in_parallel (function_call &fc)
541{
542  int n = fc.func_number;
543  int i;
544  for (i = 0; i < n; ++i)
545  {
546#if 0 //defined(CONFIG_DEBUG)
547    sc_module *m = (sc_module*)(fc.instance[i]);
548    cerr << m->name () << endl;
549    cerr << "thread #" << omp_get_thread_num () << endl;
550#endif
551        fc.function[i].pf(fc.instance[i]);
552    }
553}
554
555
556void static_mealy_generation() {
557    call_functions(pf[2]);
558}
559
560
561void static_simulate_1_cycle(void) {
562    call_functions(pf[0]); // transition
563    update();
564    call_functions_in_parallel(pf[1]); // moore generation
565    call_functions(pf[2]); // mealy generation
566}
567
568
569/* ***************************************
570 * Function for quasi static scheduling
571 */
572
573unsigned int              nb_func[2];
574static method_process_t        **func_list[2];
575static strong_component_list_t quasistatic_list;
576
577unsigned long long busy_wait_f0, busy_wait_f1, busy_wait_up, busy_wait_ml;
578unsigned long long last_wait_f0, last_wait_f1, last_wait_up, last_wait_ml;
579#ifdef _OPENMP
580#pragma omp threadprivate (nb_func, func_list)
581#pragma omp threadprivate (busy_wait_f0, busy_wait_f1, busy_wait_up,busy_wait_ml)
582#pragma omp threadprivate (last_wait_f0, last_wait_f1, last_wait_up,last_wait_ml)
583#endif
584
585static 
586void
587Call         (const method_process_t &m)
588{
589  sc_module        *mod  = m.module;
590  SC_ENTRY_FUNC     func = m.func;
591//  CASC_ENTRY_FUNC   func = reinterpret_cast<CASC_ENTRY_FUNC> (m.func);
592  (mod->*func) ();
593}
594
595
596void quasistatic_mealy_generation() {
597    strong_component_list_t::iterator ss;
598    for (ss = quasistatic_list.begin(); ss != quasistatic_list.end(); ++ss) {
599        if ((*ss)->size() == 1) {
600            /* un seul element dans le strong component */
601            method_process_t * m = (method_process_t *) (*((*ss)->begin()));
602            Call(*m);
603            continue;
604        }
605        else {
606            /* plusieurs elements dans le strong component */
607            do {
608                unstable = 0;
609                component_list_t::reverse_iterator rev_mm;
610                for (rev_mm = (*ss)->rbegin(); rev_mm != (*ss)->rend(); ++rev_mm) {
611                    method_process_t * m = (method_process_t *) * rev_mm;
612                    Call(*m);
613                }
614            } while (unstable);
615        }
616    }
617}
618
619unsigned int expected_globaltime = 0;
620volatile unsigned int globaltime __attribute__ ((aligned (128))) = 0;
621#ifdef _OPENMP
622#pragma omp threadprivate (expected_globaltime)
623#pragma omp shared (globaltime)
624#endif
625
626unsigned int num_omp_threads;
627
628void quasistatic_simulate_1_cycle (void) 
629{
630        int i;
631
632        for (i = 0; i < nb_func[0]; ++i)
633                Call (*(func_list[0][i]));
634#ifdef _OPENMP
635#define USE_BUSY_WAIT 1
636#if 0
637#if USE_BUSY_WAIT
638        expected_globaltime += num_omp_threads;
639        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
640                last_wait_f0++;
641        __asm volatile("mfence");
642        while (globaltime < expected_globaltime) {
643                busy_wait_f0++;
644                __asm volatile("lfence");
645        }
646#else
647    #ifdef _OPENMP
648    #pragma omp barrier
649    #endif
650#endif
651#endif
652#endif // _OPENMP
653
654        update();
655
656#ifdef _OPENMP
657#if USE_BUSY_WAIT
658        expected_globaltime += num_omp_threads;
659        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
660                last_wait_up++;
661        __asm volatile("mfence");
662        while (globaltime < expected_globaltime) {
663                busy_wait_up++;
664                __asm volatile("lfence");
665        }
666
667#else
668    #ifdef _OPENMP
669    #pragma omp barrier
670    #endif
671#endif
672#endif // _OPENMP
673
674        for (i = 0; i < nb_func[1]; ++i)
675                Call (*(func_list[1][i]));
676
677#ifdef _OPENMP
678#if USE_BUSY_WAIT
679        expected_globaltime += num_omp_threads;
680        if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
681                last_wait_f1++;
682        __asm volatile("mfence");
683        while (globaltime < expected_globaltime) {
684                busy_wait_f1++;
685                __asm volatile("lfence");
686        }
687#else
688#pragma omp barrier
689#endif
690#endif // _OPENMP
691
692        if (!quasistatic_list.empty()) {
693#pragma omp master
694                {
695                quasistatic_mealy_generation ();
696                }
697#ifdef _OPENMP
698#if USE_BUSY_WAIT
699                expected_globaltime += num_omp_threads;
700                if (__sync_add_and_fetch(&globaltime, 1) == expected_globaltime)
701                        last_wait_ml++;
702                __asm volatile("mfence");
703                while (globaltime < expected_globaltime) {
704                        busy_wait_ml++;
705                        __asm volatile("lfence");
706                }
707#else
708    #ifdef _OPENMP
709    #pragma omp barrier
710    #endif
711#endif
712#endif // _OPENMP
713        }
714
715}
716
717void
718gen_scheduling_code_for_quasistatic_func (
719            method_process_list_t   &transition_func_list,
720            method_process_list_t   &moore_func_list,
721            strong_component_list_t *mealy_func_list)
722{
723  if (dump_stage)
724    cerr << "Generating quasi static scheduling...\n";
725
726  nb_func[0] = transition_func_list.size();
727  nb_func[1] = moore_func_list     .size();
728
729  func_list[0] = (method_process_t**) malloc (sizeof (method_process_t*) * nb_func[0]);
730  func_list[1] = (method_process_t**) malloc (sizeof (method_process_t*) * nb_func[1]);
731
732  unsigned int i;
733  for (i = 0; i < nb_func[0]; ++i)
734    func_list[0][i] = (transition_func_list[i]);
735
736  for (i = 0; i < nb_func[1]; ++i)
737    func_list[1][i] = (moore_func_list[i]);
738
739  if (mealy_func_list != NULL)
740    quasistatic_list = *mealy_func_list;
741
742  if (dump_stage)
743    cerr << "Generating quasi static scheduling done.\n";
744}
745} // end of sc_core namespace
746
747
748/*
749# Local Variables:
750# tab-width: 4;
751# c-basic-offset: 4;
752# c-file-offsets:((innamespace . 0)(inline-open . 0));
753# indent-tabs-mode: nil;
754# End:
755#
756# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
757*/
Note: See TracBrowser for help on using the repository browser.