1 package dol.visitor.hdsd;
3 import java.io.FileOutputStream;
4 import java.io.OutputStream;
5 import java.util.Iterator;
6 import java.util.LinkedHashSet;
8 import java.util.Vector;
10 import dol.datamodel.architecture.Configuration;
11 import dol.datamodel.architecture.Processor;
12 import dol.datamodel.mapping.Mapping;
13 import dol.datamodel.pn.Channel;
14 import dol.datamodel.pn.Port;
15 import dol.datamodel.pn.Process;
16 import dol.datamodel.pn.Resource;
17 import dol.main.UserInterface;
18 import dol.util.CodePrintStream;
19 import dol.visitor.ArchiVisitor;
22 * Visitor that generates the main program for one distributed simulator.
24 public class HdsdModuleArchVisitor extends ArchiVisitor {
28 * @param map mapping of this code generation
29 * @param dir path of this file
31 public HdsdModuleArchVisitor(Mapping map, String dir) {
34 _channels = new LinkedHashSet<String>();
35 _remInChannels = new LinkedHashSet<String>();
36 _remOutChannels = new LinkedHashSet<String>();
37 _locChannels = new LinkedHashSet<String>();
42 * @param x Processor that needs to be rendered
44 public void visitComponent(Processor x) {
46 // get channels for this processor
50 String filename = _dir + "/" + "scd_" +
52 OutputStream file = new FileOutputStream(filename);
53 _mainPS = new CodePrintStream(file);
55 _mainPS.printPrefixln("#include <systemc>");
56 _mainPS.printPrefixln("#include <list>");
58 /* begin of profiling: standard i/o file handling routines */
59 _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
60 _mainPS.printPrefixln("#include <stdio.h>");
61 _mainPS.printPrefixln("#endif");
62 /* end of profiling */
64 _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
65 _mainPS.printPrefixln("#include \"simple_fifo.h\"");
66 _mainPS.printPrefixln("#include \"scd_logging.h\"");
67 _mainPS.printPrefixln("#include \"scd_simulator.h\"");
68 _mainPS.printPrefixln("#include \"scd_rem_fifo_in.h\"");
69 _mainPS.printPrefixln("#include \"scd_rem_fifo_out.h\"");
72 // include process files
73 Iterator<Process> pIt = x.getProcessList().iterator();
74 Vector<String> pList = new Vector<String>();
75 while (pIt.hasNext()) {
76 Process p = pIt.next();
77 String basename = p.getBasename();
78 if (!pList.contains(basename)) {
79 _mainPS.printPrefixln("#include \"" + p.getBasename()
87 _mainPS.printPrefixln("using namespace std;");
88 _mainPS.printPrefixln("using sc_core::sc_module;");
89 _mainPS.printPrefixln("using sc_core::sc_event;");
90 _mainPS.printPrefixln("using sc_core::sc_prim_channel;");
93 /* begin of profiling: global variables */
95 _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
96 _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME "
97 + "\"profile_" + x.getName() + ".txt\"");
98 _mainPS.printPrefixln("FILE *profiler_output_file;");
99 _mainPS.printPrefixln("unsigned int profiler_event_counter;");
100 _mainPS.printPrefixln("#endif");
101 /* end of profiling */
104 _mainPS.printPrefixln("class sc_application : public sc_module ");
105 _mainPS.printLeftBracket();
107 _mainPS.printPrefixln("public:");
108 _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
112 pIt = x.getProcessList().iterator();
113 while (pIt.hasNext()) {
114 Process p = pIt.next();
115 _mainPS.printPrefixln(p.getBasename() + "_wrapper "
116 + p.getName() + "_ins"+ ";");
117 _mainPS.printPrefixln("sc_event " + p.getName()
122 //define the scheduler
123 _mainPS.printPrefixln("sc_event sched_event;");
124 _mainPS.printPrefixln("list<sc_event* > eventList;");
125 _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
130 Iterator<String> cIt;
131 cIt = _locChannels.iterator();
132 while (cIt.hasNext())
133 _mainPS.printPrefixln("fifo " + cIt.next() + "_ins;");
134 cIt = _remInChannels.iterator();
135 while (cIt.hasNext())
136 _mainPS.printPrefixln("scd_rem_fifo_in " + cIt.next() + "_ins;");
137 cIt = _remOutChannels.iterator();
138 while (cIt.hasNext())
139 _mainPS.printPrefixln("scd_rem_fifo_out " + cIt.next() + "_ins;");
143 _mainPS.printPrefixln("sc_application(sc_module_name name)");
145 // parameter of constructor (processes)
146 _mainPS.printPrefixln(": sc_module(name),");
147 pIt = x.getProcessList().iterator();
148 while (pIt.hasNext()) {
149 Process p = pIt.next();
150 _mainPS.printPrefixln(p.getName() + "_ins(\""
151 + p.getName() +"\"),");
154 // parameter of constructor (channels)
155 cIt = _channels.iterator();
156 while (cIt.hasNext()) {
157 Channel c = _map.getPN().getChannel( cIt.next() );
158 _mainPS.printPrefix(c.getName() + "_ins(\""
159 + c.getName() +"\", "
160 + c.getSize()*c.getTokenSize()
163 _mainPS.println(",");
167 _mainPS.printLeftBracket();
171 cIt = _channels.iterator();
172 while (cIt.hasNext())
174 Channel c = _map.getPN().getChannel(cIt.next());
175 c.accept( new HdsdModulePNVisitor(x, _mainPS) );
181 _mainPS.printPrefixln("SC_THREAD(thread_init);");
183 _mainPS.printPrefixln("SC_THREAD(thread_sched);");
185 // declare concurrent non-terminating threads
186 pIt = x.getProcessList().iterator();
187 while (pIt.hasNext()) {
188 _mainPS.printPrefixln("SC_THREAD(thread_" +
189 pIt.next().getName() + ");");
191 _mainPS.printRightBracket();
194 //define scheduler thread
195 _mainPS.printPrefixln("void thread_init()");
196 _mainPS.printLeftBracket();
198 pIt = x.getProcessList().iterator();
199 while (pIt.hasNext()) {
200 Process p = pIt.next();
201 _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
203 _mainPS.printRightBracket();
207 //different scheduling algorithm can be put here
208 _mainPS.printPrefixln("void thread_sched()");
209 _mainPS.printLeftBracket();
210 _mainPS.printPrefixln("while (1)");
211 _mainPS.printLeftBracket();
212 _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
213 + "eventList.end(); ++iter)");
214 _mainPS.printLeftBracket();
215 _mainPS.printPrefixln("sc_event* e = (*iter);");
216 _mainPS.printPrefixln("e->notify();");
217 _mainPS.printRightBracket();
218 _mainPS.printPrefixln("eventList.clear();");
219 _mainPS.printPrefixln("wait(sched_event);");
220 _mainPS.printRightBracket();
221 _mainPS.printRightBracket();
225 pIt = x.getProcessList().iterator();
226 while (pIt.hasNext())
227 pIt.next().accept( new HdsdModulePNVisitor(x, _mainPS) );
229 /* begin of profiling: initialization function. */
231 /* - writes a list of all channels with the connected ports to the file. */
232 _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
233 _mainPS.printPrefixln("void initialize_profiler()");
234 _mainPS.printLeftBracket();
235 _mainPS.printPrefixln("if ((profiler_output_file = fopen(PROFILER_OUTPUT_FILENAME,\"w\"))==NULL)");
236 _mainPS.printLeftBracket();
237 _mainPS.printPrefixln("printf(\"Unable to open profiler output file. No profiling output is written.\\n\");");
238 _mainPS.printPrefixln("return;");
239 _mainPS.printRightBracket();
240 //_mainPS.printPrefixln("printf(\"Profiling data is written to %s.\\n\", PROFILER_OUTPUT_FILENAME);");
243 cIt = _channels.iterator();
244 while (cIt.hasNext()) {
245 String cName = cIt.next();
246 Channel ch = _map.getPN().getChannel(cName);
247 Iterator<Port> poIt = ch.getPortList().iterator();
248 String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize();
249 String outputStringAppendix = "";
250 while (poIt.hasNext()) {
251 Port p = poIt.next();
252 Port peerPort = p.getPeerPort();
253 Resource peerResource = p.getPeerResource();
256 // channel.out == process.in
257 String portAddr = null;
258 if ( x.hasProcess(peerResource.getName()) )
259 portAddr = "&(" + peerResource.getName()
260 + "_ins.INPORT_" + peerPort.getBasename()
261 + peerPort.getName().replace(
262 peerPort.getBasename(), "").replaceAll(
263 "_([0-9]+)", "[$1]") + ")";
265 portAddr = "0x00000000";
266 outputString += " i " + peerResource.getName() + " %p";// + p.getPeerPort().getName();
267 outputStringAppendix += "," + portAddr;
269 String portAddr = null;
270 if ( x.hasProcess(peerResource.getName()) )
271 portAddr = "&(" + peerResource.getName()
272 + "_ins.OUTPORT_" + peerPort.getBasename()
273 + peerPort.getName().replace(
274 peerPort.getBasename(), "").replaceAll(
275 "_([0-9]+)", "[$1]") + ")";
277 portAddr = "0x00000000";
278 outputString += " o " + peerResource.getName() + " %p";// + p.getPeerPort().getName();
279 outputStringAppendix += "," + portAddr;
282 outputString += "\\n\"" + outputStringAppendix + ");";
283 _mainPS.printPrefixln(outputString);
285 _mainPS.printRightBracket();
286 _mainPS.printPrefixln("#endif");
288 /* end of profiling */
290 _mainPS.printRightBracket(); // end of class
291 _mainPS.println(";");
293 //create and run the simulator
294 _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
295 _mainPS.printLeftBracket();
297 //create an instance of the application model
298 //remove potential whitespaces before using the process
299 //network name as a systemc identifier
300 _mainPS.printPrefixln("sc_application my_app_mdl(\""
301 + x.getName().replaceAll(" ", "") + "\");");
303 /* begin of profiling: initialize the profiler */
304 _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
305 _mainPS.printPrefixln("my_app_mdl.initialize_profiler();");
306 _mainPS.printPrefixln("#endif");
307 _mainPS.printPrefixln();
308 /* end of profiling */
310 /* begin distributed simulation */
311 if (UserInterface.getInstance().getDebugFlag())
312 _mainPS.printPrefixln("scd_set_loglevel(SCD_DEBUG);");
314 _mainPS.printPrefixln("scd_set_loglevel(SCD_INFO);");
315 // simulator && master/slaves
316 Configuration opt = x.getCfg("master");
317 if (opt != null && opt.getValue().equals("true")) // master
319 // simulator constructor
320 _mainPS.printPrefixln("scd_simulator sim(\""
321 + x.getName() + "\", \""
322 + x.getCfg("address").getValue() + "\", "
323 + x.getCfg("port").getValue() + ", SCD_MASTER);");
325 Iterator<Processor> iter = _map.getProcessorList().iterator();
326 while (iter.hasNext())
328 Processor p = iter.next();
329 opt = p.getCfg("master");
330 if ( !(opt != null && opt.getValue().equals("true")) )
332 _mainPS.printPrefixln("sim.get_cont_man()."
333 + "register_slave(\"" + p.getName()
340 // simulator constructor
341 _mainPS.printPrefixln("scd_simulator sim(\""
342 + x.getName() + "\", \""
343 + x.getCfg("address").getValue() + "\", "
344 + x.getCfg("port").getValue() + ", SCD_SLAVE);");
345 // find and set master
346 Iterator<Processor> iter = _map.getProcessorList().iterator();
347 while (iter.hasNext())
349 Processor p = iter.next();
350 opt = p.getCfg("master");
351 if (opt != null && opt.getValue().equals("true"))
353 _mainPS.printPrefixln("sim.get_cont_man().set_master(\""
354 + p.getCfg("address").getValue() + "\", "
355 + p.getCfg("port").getValue() + ");");
362 // remote out channels
363 cIt = _remOutChannels.iterator();
364 while (cIt.hasNext())
366 String cName = cIt.next();
367 Channel c = _map.getPN().getChannel(cName);
368 Iterator<Port> poIt = c.getPortList().iterator();
370 while (poIt.hasNext())
372 Port po = poIt.next();
375 Process pr = _map.getProcess(
376 po.getPeerResource().getName() );
377 p = pr.getProcessor();
380 _mainPS.printPrefixln("sim.get_chan_man()."
381 + "register_channel(\"" + cName + "\",");
382 _mainPS.printPrefixln(" my_app_mdl." + cName
383 + "_ins, \"" + p.getCfg("address").getValue() + "\", "
384 + p.getCfg("port").getValue() + ");");
386 // remote in channels
387 cIt = _remInChannels.iterator();
388 while (cIt.hasNext())
390 String cName = cIt.next();
391 _mainPS.printPrefixln("sim.get_chan_man().register_channel("
392 + "\"" + cName + "\",");
393 _mainPS.printPrefixln(" my_app_mdl." + cName + "_ins);");
397 _mainPS.printPrefixln("bool ret = sim.init();");
398 _mainPS.printPrefixln("if (ret)");
400 _mainPS.printPrefixln("ret = sim.start();");
402 _mainPS.printPrefixln();
403 /* end distributed simulation */
405 /* begin of profiling: close the output file */
406 _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
407 _mainPS.printPrefixln("if (profiler_output_file != NULL) fclose(profiler_output_file);");
408 _mainPS.printPrefixln("#endif");
409 /* end of profiling */
411 _mainPS.printPrefixln("if (ret)");
413 _mainPS.printPrefixln("return 0;");
415 _mainPS.printPrefixln("else");
417 _mainPS.printPrefixln("return 1;");
420 _mainPS.printRightBracket();
423 catch (Exception e) {
424 System.out.println("HdsdModuleVisitor: exception occured: "
432 * Retrieves all channels that have an endpoint on the specified
433 * processor and fills them into the channel sets.
434 * @param x the processor to get the channels for
436 private void _getChannels(Processor x)
438 Iterator<Channel> iter = _map.getPN().getChannelList().iterator();
440 while (iter.hasNext())
442 Channel c = iter.next();
444 boolean isIn = false;
445 boolean isOut = false;
447 /* check if the in/out endpoint of this channel is on this
450 Iterator<Port> poIt = c.getPortList().iterator();
451 while (poIt.hasNext())
453 Port p = poIt.next();
454 if (x.hasProcess(p.getPeerResource().getName()))
456 if (p.isInPort()) // inPort of channel = outport
458 if (p.isOutPort()) // outPort of channel = inport
463 // add name to channel lists
466 _channels.add(c.getName());
467 _locChannels.add(c.getName());
469 else if (isIn && !isOut)
471 _channels.add(c.getName());
472 _remInChannels.add(c.getName());
474 else if (!isIn && isOut)
476 _channels.add(c.getName());
477 _remOutChannels.add(c.getName());
483 protected CodePrintStream _mainPS = null;
484 protected String _dir = null;
485 protected Mapping _map = null;
487 protected Set<String> _channels = null;
488 protected Set<String> _remInChannels = null;
489 protected Set<String> _remOutChannels = null;
490 protected Set<String> _locChannels = null;