Changeset 52 for sources/src/schedulers.cc
- Timestamp:
- Jan 22, 2013, 4:23:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sources/src/schedulers.cc
r38 r52 35 35 */ 36 36 37 #include <cstdio> 38 #include <cassert> 39 #include <iostream> 40 #include <algorithm> //std::sort 41 37 42 #include "sc_module.h" // method_process_t 38 43 #include "gen_code.h" // gen_scheduling_code_for_dynamic_link & gen_scheduling_code_for_static_func … … 43 48 #include "mouchard_scheduling.h" // MakeMouchardScheduling 44 49 #include "graph_signals.h" // makegraph 45 //#include "module_hierarchy2dot.h"46 47 #include <cstdio>48 #include <cassert>49 #include <iostream>50 #include <algorithm> //std::sort51 50 52 51 #ifdef HAVE_CONFIG_H … … 63 62 64 63 template <typename T> 65 ostream& operator << (ostream &o, const vector<T*> &v) 66 { 67 typename vector<T*>::const_iterator i; 68 for (i = v.begin(); i != v.end(); ++i) { 69 o << **i << " "; 70 } 71 return o; 64 ostream & 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; 72 70 } 73 71 … … 76 74 /****************/ 77 75 78 //79 76 // sort_functions splits and sorts instances_list into three functions lists : 80 77 method_process_list_t transition_func_list; … … 82 79 method_process_list_t combinational_func_list; 83 80 84 #if 0 85 static 86 bool 87 isCostly (const char *n) 88 { 89 const char *costly[] = {/*"vgmn", */"mips", "cache", NULL}; 90 int i = 0; 91 do { 92 if (strstr (n, costly[i]) != NULL) 93 return true; 94 } while (costly[++i] != NULL); 95 return false; 96 } 97 98 static 99 bool 100 only_sort_by_module_ptr (const method_process_t *a1, 101 const method_process_t *a2) 102 { 103 assert(a1 != NULL); 104 assert(a2 != NULL); 105 sc_module *m1 = a1->module; 106 sc_module *m2 = a2->module; 107 const char* n1 = m1->basename (); 108 const char* n2 = m2->basename (); 109 bool h1 = isCostly (n1); 110 bool h2 = isCostly (n2); 111 if ((h1 ^ h2) == true) 112 return h1 > h2; 113 if (a1->module == a2->module) 114 { 115 union { 116 SC_ENTRY_FUNC func; 117 unsigned long addr_l; 118 unsigned long long addr_ll; 119 } addr1, addr2; 120 addr1.func = a1->func; 121 addr2.func = a2->func; 122 assert(addr1.addr_ll != addr2.addr_ll); 123 if ( sizeof(SC_ENTRY_FUNC) == 4 ) { 124 return (addr1.addr_l < addr2.addr_l); 125 } else { 126 return (addr1.addr_ll < addr2.addr_ll); 127 } 128 } 129 return (a1->module < a2->module); 130 } 131 #endif 132 #if 1 133 static 134 bool 135 sort_by_module_ptr (const method_process_t *a1, 136 const method_process_t *a2) 137 { 138 assert(a1 != NULL); 139 assert(a2 != NULL); 140 return (a1->module < a2->module); 141 } 142 143 static 144 bool 145 sort_by_fct_ptr (const method_process_t *a1, 146 const method_process_t *a2) 147 { 81 82 static 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 89 static bool sort_by_fct_ptr (const method_process_t * a1, const method_process_t * a2) { 148 90 assert(a1 != NULL); 149 91 assert(a2 != NULL); … … 153 95 unsigned long long addr_ll; 154 96 } addr1, addr2; 97 155 98 addr1.func = a1->func; 156 99 addr2.func = a2->func; 157 if (a1->func == a2->func) 158 return sort_by_module_ptr (a1,a2); 159 if ( sizeof(SC_ENTRY_FUNC) == 4 ) { 100 101 if (a1->func == a2->func) { 102 return sort_by_module_ptr(a1,a2); 103 } 104 105 if (sizeof(SC_ENTRY_FUNC) == 4 ) { 160 106 return (addr1.addr_l < addr2.addr_l); 161 } else { 107 } 108 else { 162 109 return (addr1.addr_ll < addr2.addr_ll); 163 110 } 164 111 } 165 #endif 166 void 167 sort_functions () 168 { 169 #if 0 170 cerr << method_process_list << endl; 171 #endif 172 method_process_list_t::const_iterator m; 173 for (m = method_process_list.begin(); m != method_process_list.end(); ++m) { 174 if ((*m)->is_combinational()) combinational_func_list.push_back(*m); 175 else if ((*m)->is_transition ()) transition_func_list.push_back(*m); 176 else if ((*m)->is_genmoore ()) moore_func_list.push_back(*m); 177 } 178 #if 1 179 // Sort transition functions by method pointer (1) and by module pointer (2) 180 std::sort (transition_func_list.begin(), transition_func_list.end(), sort_by_fct_ptr); 181 // Sort generation functions by method pointer (1) and by module pointer (2) 182 std::sort (moore_func_list.begin(), moore_func_list.end(), sort_by_fct_ptr); 183 #endif 184 #if 0 185 std::sort (transition_func_list.begin(), transition_func_list.end(), only_sort_by_module_ptr); 186 std::sort (moore_func_list.begin(), moore_func_list.end(), only_sort_by_module_ptr); 187 #endif 112 113 114 115 void 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); 188 132 } 189 133 … … 192 136 /* ****************** */ 193 137 194 static 195 SignalDependencyGraph* 196 MakeAcyclicSignalDependencyGraph () 197 { 198 if (dump_all_graph) { 199 const PortDependencyGraph &port_graph = get_port_dependency_graph (); 200 PortDependencyGraph2dot ("port_graph", port_graph); 201 } 202 203 SignalDependencyGraph* sig_graph = MakeSignalDependencyGraph (); 204 205 if (dump_all_graph) 206 SignalDependencyGraph2dot ("signal_graph",*sig_graph); 207 208 if (!Check (*sig_graph)) 209 { 210 cerr << "The signal dependency graph is not valid.\n"; 211 exit (29092004); 212 } 213 214 #if 1 215 if (!Check (method_process_list,*sig_graph)) 216 { 217 cerr << "Sensitivity list is not valid.\n"; 218 exit (30092004); 219 } 220 #endif 221 222 // There is a cycle in the signal dependency graph ? 223 Graph *sig_knuth = makegraph (*sig_graph); 224 strong_component_list_t *s = strong_component(sig_knuth); 225 226 if (dump_all_graph) 227 SignalDependencyOrder2txt ("signal_order",*s); 228 229 if (has_cycle (*s)) 230 { 231 cerr << "Error : There is a cycle in the signal dependency graph.\n"; 232 #if 0 233 print_cycle (cerr, get_cycle (*s)); 234 #endif 235 exit (24092004); 236 } 237 return sig_graph; 238 } 239 240 static 241 ProcessDependencyList* 242 MouchardScheduling () 243 { 244 SignalDependencyGraph *sig_graph = MakeAcyclicSignalDependencyGraph (); 245 assert(sig_graph != NULL); 246 // Create the process evaluation list 247 ProcessDependencyList* process_list = MakeMouchardScheduling (*sig_graph); 248 assert(process_list != NULL); 249 250 if (dump_all_graph) 251 ProcessDependencyList2dot ("process_order",*process_list); 252 253 return process_list; 254 } 255 256 static 257 ProcessDependencyList* 258 BuchmannScheduling () 259 { 260 SignalDependencyGraph *sig_graph = MakeAcyclicSignalDependencyGraph (); 261 // Create the process evaluation list 262 ProcessDependencyList* process_list = MakeProcessDependencyList (*sig_graph); 263 264 if (dump_all_graph) 265 ProcessDependencyList2dot ("process_order",*process_list); 266 267 return process_list; 268 } 269 270 string 271 get_scheduling (int scheduling_method) 272 { 273 /* marque les fonctions comme fonction de mealy ou non */ 274 if (dump_funclist_info) 275 cerr << "method process list : " << method_process_list << "\n"; 276 sort_functions (); 277 if (dump_funclist_info) 278 { 279 cerr << "Transition functions : " << transition_func_list << "\n"; 280 cerr << "Moore generation functions : " << moore_func_list << "\n"; 281 cerr << "Mealy generation functions : " << combinational_func_list << "\n"; 282 } 283 284 /* Schedule */ 285 string base_name; 286 switch (scheduling_method) { 287 case BUCHMANN_SCHEDULING : { 288 // Generate the scheduled code, compile and link. 289 // Buchmann's thesis explains this scheduling method. 290 // Uses port dependancies like Dr. Mouchard. 291 ProcessDependencyList* process_list = BuchmannScheduling (); 292 if (dynamic_link_of_scheduling_code) 293 base_name = gen_scheduling_code_for_dynamic_link (transition_func_list, moore_func_list,*process_list); 294 else 295 gen_scheduling_code_for_static_func (transition_func_list, moore_func_list, *process_list); 296 break; 297 } 298 case MOUCHARD_SCHEDULING : { 299 // Generate the scheduled code, compile and link. 300 // Mouchard's thesis explains this scheduling method. 301 // Uses port dependancies like Dr. Mouchard. 302 // CAUTION : unlike FastSysC, this scheduling is totally static 303 // and does not use an event-driven scheduler. 304 ProcessDependencyList* process_list = MouchardScheduling (); 305 if (dynamic_link_of_scheduling_code) 306 base_name = gen_scheduling_code_for_dynamic_link(transition_func_list, moore_func_list,*process_list); 307 else 308 gen_scheduling_code_for_static_func (transition_func_list, moore_func_list, *process_list); 309 break; 310 } 311 case CASS_SCHEDULING : { 312 // Generate the scheduled code, compile and link 313 // Hommais's thesis explains this scheduling method (like CASS strategy) 314 // Doesn't use port dependancies 315 Graph *g = makegraph (&combinational_func_list); 316 if (dump_all_graph && g) 317 graph2dot("module_graph", *g); 318 strong_component_list_t *strong_list = strong_component (g); 319 if (dynamic_link_of_scheduling_code) 320 base_name = gen_scheduling_code_for_dynamic_link(transition_func_list, moore_func_list,*strong_list); 321 else 322 gen_scheduling_code_for_quasistatic_func (transition_func_list, moore_func_list, *strong_list); 323 break; 324 } 325 default : 326 cerr << "Error : Unable to schedule SystemC process." 327 "Please select a scheduling method.\n"; 328 exit (35); 329 } 330 return base_name; 331 } 332 333 bool 334 run_schedule_editor (const char *schedule) 335 { 336 char buf[128]; 337 const char *editor = getenv ("EDITOR"); 338 if (editor == NULL) 339 editor = "vim"; 340 sprintf (buf, "(cd '%s' ; %s '%s')", temporary_dir, editor, schedule); 341 if (dump_stage) 342 cerr << "Executing : " << buf << endl; 343 return (system(buf) == 0); 344 } 345 346 ///////////////////////// 138 static 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 176 static 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 191 static 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 204 string 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 279 bool 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 347 292 348 293 } // end of sc_core namespace 349 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 TracChangeset
for help on using the changeset viewer.