source: sources/src/schedulers.cc @ 52

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

Code formatting in all source files.

File size: 10.0 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                 schedulers.cc                     |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Nicolas Pouillon                  |
9|                                                             |
10| Date    :                   23_03_2007                      |
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 <cassert>
39#include <iostream>
40#include <algorithm> //std::sort
41
42#include "sc_module.h" // method_process_t
43#include "gen_code.h"  // gen_scheduling_code_for_dynamic_link & gen_scheduling_code_for_static_func
44#include "internal.h"  // dump_all_graph
45#include "graph_cass.h" // makegraph
46#include "process_dependency.h" // MakeProcessDependencyList
47#include "signal_dependency.h" // MakeSignalDependencyGraph
48#include "mouchard_scheduling.h" // MakeMouchardScheduling
49#include "graph_signals.h" // makegraph
50
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54
55using namespace std;
56
57namespace sc_core {
58
59/* ***************************** */
60/* Dumping functions (for debug) */
61/* ***************************** */
62
63template <typename T>
64ostream & operator << (ostream & o, const vector<T*> & v) {
65    typename vector<T *>::const_iterator i;
66    for (i = v.begin(); i != v.end(); ++i) {
67        o << **i << " ";
68    }
69    return o;
70}
71
72/* ************ */
73/*  functions   */
74/****************/
75
76// sort_functions splits and sorts instances_list into three functions lists :
77method_process_list_t transition_func_list;
78method_process_list_t moore_func_list;
79method_process_list_t combinational_func_list;
80
81
82static bool sort_by_module_ptr (const method_process_t * a1, const method_process_t * a2) {
83    assert(a1 != NULL);
84    assert(a2 != NULL);
85    return (a1->module < a2->module);
86}
87
88
89static bool sort_by_fct_ptr (const method_process_t * a1, const method_process_t * a2) {
90    assert(a1 != NULL);
91    assert(a2 != NULL);
92    union {
93        SC_ENTRY_FUNC func;
94        unsigned long addr_l;
95        unsigned long long addr_ll;
96    } addr1, addr2;
97
98    addr1.func = a1->func;
99    addr2.func = a2->func;
100   
101    if (a1->func == a2->func) {
102        return sort_by_module_ptr(a1,a2);
103    }
104
105    if (sizeof(SC_ENTRY_FUNC) == 4 ) {
106        return (addr1.addr_l < addr2.addr_l);
107    }
108    else {
109        return (addr1.addr_ll < addr2.addr_ll);
110    }
111}
112
113
114
115void sort_functions() {
116    method_process_list_t::const_iterator m;
117    for (m = method_process_list.begin(); m != method_process_list.end(); ++m) {
118        if ((*m)->is_combinational()) {
119            combinational_func_list.push_back(*m);
120        }
121        else if ((*m)->is_transition ()) {
122            transition_func_list.push_back(*m);
123        }
124        else if ((*m)->is_genmoore ()) {
125            moore_func_list.push_back(*m);
126        }
127    }
128    // Sort transition functions by method pointer (1) and by module pointer (2)
129    std::sort (transition_func_list.begin(), transition_func_list.end(), sort_by_fct_ptr);
130    // Sort generation functions by method pointer (1) and by module pointer (2)
131    std::sort (moore_func_list.begin(), moore_func_list.end(), sort_by_fct_ptr);
132}
133
134/* ****************** */
135/* process dependency */
136/* ****************** */
137
138static SignalDependencyGraph * MakeAcyclicSignalDependencyGraph() {
139    if (dump_all_graph) {
140        const PortDependencyGraph & port_graph = get_port_dependency_graph ();
141        PortDependencyGraph2dot ("port_graph", port_graph);
142    }
143
144    SignalDependencyGraph * sig_graph = MakeSignalDependencyGraph();
145
146    if (dump_all_graph) {
147        SignalDependencyGraph2dot ("signal_graph",*sig_graph);
148    }
149
150    if (!Check(*sig_graph)) {
151        cerr << "The signal dependency graph is not valid.\n";
152        exit (29092004);
153    }
154
155    if (!Check(method_process_list, *sig_graph)) {
156        cerr << "Sensitivity list is not valid.\n";
157        exit (30092004);
158    }
159
160    // There is a cycle in the signal dependency graph ?
161    Graph * sig_knuth = makegraph(*sig_graph);
162    strong_component_list_t * s = strong_component(sig_knuth);
163
164    if (dump_all_graph) {
165        SignalDependencyOrder2txt("signal_order",*s);
166    }
167
168    if (has_cycle(*s)) {
169        cerr << "Error : There is a cycle in the signal dependency graph.\n";
170        exit (24092004);
171    }
172    return sig_graph;
173}
174
175
176static ProcessDependencyList * MouchardScheduling() {
177    SignalDependencyGraph * sig_graph = MakeAcyclicSignalDependencyGraph();
178    assert(sig_graph != NULL);
179    // Create the process evaluation list
180    ProcessDependencyList * process_list = MakeMouchardScheduling(*sig_graph);
181    assert(process_list != NULL);
182
183    if (dump_all_graph) {
184        ProcessDependencyList2dot  ("process_order", *process_list);
185    }
186
187    return process_list;
188}
189
190
191static ProcessDependencyList * BuchmannScheduling() {
192    SignalDependencyGraph * sig_graph = MakeAcyclicSignalDependencyGraph();
193    // Create the process evaluation list
194    ProcessDependencyList * process_list = MakeProcessDependencyList(*sig_graph);
195
196    if (dump_all_graph) {
197        ProcessDependencyList2dot("process_order", *process_list);
198    }
199
200    return process_list;
201}
202
203
204string get_scheduling(int scheduling_method) {
205    /* marque les fonctions comme fonction de mealy ou non */
206    if (dump_funclist_info) {
207        cerr << "method process list : " << method_process_list << "\n";
208    }
209
210    sort_functions();
211    if (dump_funclist_info) {
212        cerr << "Transition functions : " << transition_func_list << "\n";
213        cerr << "Moore generation functions : " << moore_func_list << "\n";
214        cerr << "Mealy generation functions : " << combinational_func_list << "\n";
215    }
216
217    /* Schedule */ 
218    string base_name;
219    switch (scheduling_method) {
220        case BUCHMANN_SCHEDULING :
221        {
222            // Generate the scheduled code, compile and link.
223            // Buchmann's thesis explains this scheduling method.
224            // Uses port dependancies like Dr. Mouchard.
225            ProcessDependencyList * process_list = BuchmannScheduling();
226            if (dynamic_link_of_scheduling_code) {
227                base_name = gen_scheduling_code_for_dynamic_link(transition_func_list, moore_func_list, *process_list);
228            }
229            else {
230                gen_scheduling_code_for_static_func(transition_func_list, moore_func_list, *process_list);
231            }
232            break;
233        }
234
235        case MOUCHARD_SCHEDULING :
236        {
237            // Generate the scheduled code, compile and link.
238            // Mouchard's thesis explains this scheduling method.
239            // Uses port dependancies like Dr. Mouchard.
240            // CAUTION : unlike FastSysC, this scheduling is totally static
241            // and does not use an event-driven scheduler.
242            ProcessDependencyList * process_list = MouchardScheduling();
243            if (dynamic_link_of_scheduling_code) {
244                base_name = gen_scheduling_code_for_dynamic_link(transition_func_list, moore_func_list, *process_list);
245            }
246            else {
247                gen_scheduling_code_for_static_func (transition_func_list, moore_func_list, *process_list);
248            }
249            break;
250        }
251
252        case CASS_SCHEDULING :
253        {
254            // Generate the scheduled code, compile and link
255            // Hommais's thesis explains this scheduling method (like CASS strategy)
256            // Doesn't use port dependancies
257            Graph * g = makegraph (&combinational_func_list);
258            if (dump_all_graph && g) {
259                graph2dot("module_graph", *g);
260            }
261            strong_component_list_t * strong_list = strong_component(g);
262            if (dynamic_link_of_scheduling_code) {
263                base_name = gen_scheduling_code_for_dynamic_link(transition_func_list, moore_func_list, *strong_list);
264            }
265            else {
266                gen_scheduling_code_for_quasistatic_func (transition_func_list, moore_func_list, *strong_list);
267            }
268            break;
269        }
270        default :
271            cerr << "Error : Unable to schedule SystemC process."
272                    "Please select a scheduling method.\n";
273            exit (35);
274    }
275    return base_name;
276}
277
278
279bool run_schedule_editor (const char * schedule) {
280    char buf[128];
281    const char * editor = getenv("EDITOR");
282    if (editor == NULL) {
283        editor = "vim";
284    }
285    sprintf (buf, "(cd '%s' ; %s '%s')", temporary_dir, editor, schedule);
286    if (dump_stage) {
287        cerr << "Executing : " << buf << endl;
288    }
289    return (system(buf) == 0);
290}
291
292
293} // end of sc_core namespace
294
295/*
296# Local Variables:
297# tab-width: 4;
298# c-basic-offset: 4;
299# c-file-offsets:((innamespace . 0)(inline-open . 0));
300# indent-tabs-mode: nil;
301# End:
302#
303# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
304*/
305
Note: See TracBrowser for help on using the repository browser.