f00bbe3fe51b62f55e5f1c50e762bf702aac515e
[jump.git] / dol / src / dol / visitor / hds / HdsModuleVisitor.java
1 /* $Id: HdsModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.hds;
3
4 import java.io.FileOutputStream;
5 import java.io.OutputStream;
6
7 import dol.datamodel.pn.Channel;
8 import dol.datamodel.pn.Port;
9 import dol.datamodel.pn.Process;
10 import dol.datamodel.pn.ProcessNetwork;
11 import dol.datamodel.pn.Resource;
12 import dol.util.CodePrintStream;
13 import dol.visitor.PNVisitor;
14
15 /**
16  * This class is a class for a visitor that is used to generate
17  * the main program.
18  */
19 public class HdsModuleVisitor extends PNVisitor {
20
21     /**
22      * Constructor.
23      *
24      * @param dir path of this file
25      */
26     public HdsModuleVisitor(String dir) {
27         _dir = dir;
28     }
29
30     /**
31      *
32      * @param x process network that needs to be rendered
33      */
34     public void visitComponent(ProcessNetwork x) {
35         try {
36             String filename = _dir + _delimiter + "sc_application.cpp";
37             OutputStream file = new FileOutputStream(filename);
38             _mainPS = new CodePrintStream(file);
39
40             _mainPS.printPrefixln("#include <systemc>");
41             _mainPS.printPrefixln("#include <list>");
42
43             /* begin of profiling: standard i/o file handling routines */
44             _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
45             _mainPS.printPrefixln("#include <stdio.h>");
46             _mainPS.printPrefixln("#endif");
47             /* end of profiling */
48
49             _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
50             _mainPS.println();
51
52             for (String basename : x.getProcessBasenames()) {
53                 _mainPS.printPrefixln("#include \"" + basename
54                         + "_wrapper.h\"");
55             }
56             _mainPS.println();
57             _mainPS.printPrefixln("using namespace std;");
58
59             /* begin of profiling: global variables */
60             _mainPS.println();
61             _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
62             _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME \"profile.txt\"");
63             _mainPS.printPrefixln("FILE *profiler_output_file;");
64             _mainPS.printPrefixln("unsigned int profiler_event_counter;");
65             _mainPS.printPrefixln("#endif");
66             /* end of profiling */
67
68             _mainPS.println();
69             _mainPS.printPrefixln("class sc_application : public sc_module ");
70             _mainPS.printLeftBracket();
71
72             _mainPS.printPrefixln("public:");
73             _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
74
75             //declare processes
76             _mainPS.println();
77             for (Process p : x.getProcessList()) {
78                 _mainPS.printPrefixln(p.getBasename() + "_wrapper "
79                         + p.getName() + "_ins"+ ";");
80                 _mainPS.printPrefixln("sc_event " + p.getName()
81                         + "_event;");
82             }
83             _mainPS.println();
84
85             //define the scheduler
86             _mainPS.printPrefixln("sc_event sched_event;");
87             _mainPS.printPrefixln("list<sc_event* > eventList;");
88             _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
89             _mainPS.println();
90
91             //declare channels
92             _mainPS.println();
93             for (Channel p : x.getChannelList()) {
94                 if (p.getType().equals("fifo")) { 
95                     _mainPS.printPrefixln("Fifo " + p.getName() + "_ins;");
96                 } else if (p.getType().equals("wfifo")) {
97                     _mainPS.printPrefixln("WindowedFifo " + p.getName() + "_ins;");
98                 }
99             }
100             _mainPS.println();
101
102             //model constructor
103             _mainPS.printPrefixln("sc_application(sc_module_name name)");
104
105             //parameter of constructor
106             _mainPS.printPrefix(":       sc_module(name)");
107             for (Process p : x.getProcessList()) {
108                 _mainPS.println(",");
109                 _mainPS.printPrefix(p.getName() + "_ins(\""
110                         + p.getName() +"\")");
111             }
112
113             if (x.getChannelList().size() > 0) {
114                 for (Channel c : x.getChannelList()) {
115                     _mainPS.println(",");
116                     _mainPS.printPrefix(c.getName() + "_ins("
117                                         + "\"" + c.getName() + "\", "
118                                         + c.getSize() * c.getTokenSize()
119                                         + ")");
120                 }
121             }
122             _mainPS.println("");
123             _mainPS.printLeftBracket();
124
125             //construtor content
126             //build the network
127             for (Channel ch : x.getChannelList()) {
128                 ch.accept(this);
129             }
130             _mainPS.println("");
131
132             _mainPS.println("");
133
134             _mainPS.printPrefixln("SC_THREAD(thread_init);");
135             //init thread
136             _mainPS.printPrefixln("SC_THREAD(thread_sched);");
137
138             //declare concurrent non-terminating threads
139             for (Process p : x.getProcessList()) {
140                 _mainPS.printPrefixln("SC_THREAD(thread_" +
141                                       p.getName() + ");");
142             }
143             _mainPS.printRightBracket();
144             _mainPS.println();
145
146             //define scheduler thread
147             _mainPS.printPrefixln("void thread_init()");
148             _mainPS.printLeftBracket();
149             //init
150             for (Process p : x.getProcessList()) {
151                 _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
152             }
153             _mainPS.printRightBracket();
154             _mainPS.println();
155
156
157             //different scheduling algorithm can be put here
158             _mainPS.printPrefixln("void thread_sched()");
159             _mainPS.printLeftBracket();
160             _mainPS.printPrefixln("while (1)");
161             _mainPS.printLeftBracket();
162             _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
163                     + "eventList.end(); ++iter)");
164             _mainPS.printLeftBracket();
165             _mainPS.printPrefixln("sc_event* e = (*iter);");
166             _mainPS.printPrefixln("e->notify();");
167             _mainPS.printRightBracket();
168             _mainPS.printPrefixln("eventList.clear();");
169             _mainPS.printPrefixln("wait(sched_event);");
170             _mainPS.printRightBracket();
171             _mainPS.printRightBracket();
172             _mainPS.println();
173
174             //define threads
175             for (Process p : x.getProcessList()) {
176                 p.accept(this);
177             }
178
179             /* begin of profiling: initialization function. */
180             /* - opens file */
181             /* - writes a list of all channels with the connected ports to the file. */
182             _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
183             _mainPS.printPrefixln("void initialize_profiler()");
184             _mainPS.printLeftBracket();
185             _mainPS.printPrefixln("if ((profiler_output_file = fopen(PROFILER_OUTPUT_FILENAME,\"w\"))==NULL)");
186             _mainPS.printLeftBracket();
187             _mainPS.printPrefixln("printf(\"Unable to open profiler output file. No profiling output is written.\\n\");");
188             _mainPS.printPrefixln("return;");
189             _mainPS.printRightBracket();
190             //_mainPS.printPrefixln("printf(\"Profiling data is written to %s.\\n\", PROFILER_OUTPUT_FILENAME);");
191             _mainPS.println();
192
193             for (Channel ch : x.getChannelList()) {
194                 String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize();
195                 String outputStringAppendix = "";
196                 for (Port p : ch.getPortList()) {
197                     Port peerPort = (Port)(p.getPeerPort());
198                     Resource peerResource = p.getPeerResource();
199
200                     if (p.isOutPort()) {
201                         // channel.out == process.in
202                         outputString += " i " + peerResource.getName() + " %pI";
203                         outputStringAppendix += ",(" + peerResource.getName()
204                             + "_ins.INPORT_"
205                             + peerPort.getBasename()
206                             + peerPort.getName().replaceAll(
207                             "_([0-9]+)", "[$1]").replaceFirst(
208                             peerPort.getBasename(), "") + ")";
209                     } else {
210                         outputString += " o " + peerResource.getName() + " %pO";
211                         outputStringAppendix += ",(" + peerResource.getName()
212                             + "_ins.OUTPORT_"
213                             + peerPort.getBasename()
214                             + peerPort.getName().replaceAll(
215                             "_([0-9]+)", "[$1]").replaceFirst(
216                             peerPort.getBasename(), "") + ")";
217                     }
218                 }
219                 outputString += "\\n\"" + outputStringAppendix + ");";
220                 _mainPS.printPrefixln(outputString);
221             }
222             _mainPS.printRightBracket();
223             _mainPS.printPrefixln("#endif");
224             _mainPS.println();
225             /* end of profiling */
226
227             _mainPS.printRightBracket(); // end of class
228             _mainPS.println(";");
229
230             //create and run the simulator
231             _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
232             _mainPS.printLeftBracket();
233             _mainPS.printPrefixln("sc_report_handler::set_actions(\""
234                     + "/IEEE_Std_1666/deprecated\", SC_DO_NOTHING);");
235             _mainPS.printPrefixln("sc_report::register_id("
236                     + "5000, "
237                     + "\"parameter problem\" );");
238
239             //create an instance of the application model
240             //remove potential whitespaces before using the process
241             //network name as a systemc identifier
242             _mainPS.printPrefixln("sc_application my_app_mdl(\""
243                     + x.getName().replaceAll(" ", "")  + "\");");
244
245             /* begin of profiling: initialize the profiler */
246             _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
247             _mainPS.printPrefixln("my_app_mdl.initialize_profiler();");
248             _mainPS.printPrefixln("#endif");
249             /* end of profiling */
250
251             _mainPS.printPrefixln("sc_start(-1,SC_NS);");
252             /* begin of profiling: close the output file */
253             _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
254             _mainPS.printPrefixln("if (profiler_output_file != NULL) fclose(profiler_output_file);");
255             _mainPS.printPrefixln("#endif");
256             /* end of profiling */
257
258             _mainPS.printPrefixln("return 0;");
259
260             _mainPS.printRightBracket();
261
262         }
263         catch (Exception e) {
264             System.out.println("HdsModuleVisitor: exception occured: "
265                     + e.getMessage());
266             e.printStackTrace();
267         }
268     }
269
270     /**
271      * Print a line for the process in the correct format for DOTTY.
272      *
273      * @param x process that needs to be rendered
274      */
275     public void visitComponent(Process x) {
276         _mainPS.printPrefixln("void thread_" + x.getName() + "()");
277         _mainPS.printLeftBracket();
278         _mainPS.printPrefixln("while (!" + x.getName()
279                 + "_ins.isDetached())");
280         _mainPS.printLeftBracket();
281
282         /* begin of profiling: start event */
283         _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
284         _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " started.\\n\", profiler_event_counter++);");
285         _mainPS.printPrefixln("#endif");
286         /* end of profiling */
287
288         _mainPS.printPrefixln(x.getName() + "_ins.fire();");
289
290         /* begin of profiling: stop event */
291         _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
292         _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " stopped.\\n\", profiler_event_counter++);");
293         _mainPS.printPrefixln("#endif");
294         /* end of profiling */
295
296         _mainPS.printPrefixln("eventList.push_back(&" + x.getName()
297                               + "_event);");
298         _mainPS.printPrefixln("sched_event.notify();");
299         _mainPS.printPrefixln("wait(" + x.getName() + "_event);");
300
301         _mainPS.printRightBracket();
302         _mainPS.printRightBracket();
303     }
304
305     /**
306      *
307      * @param x channel that needs to be rendered
308      */
309     public void visitComponent(Channel x) {
310         for (Port p : x.getPortList()) {
311             Port peerPort = (Port)(p.getPeerPort());
312             Resource peerResource = p.getPeerResource();
313             if (peerPort.getRange() != null) {
314                 if (p.isOutPort()) {
315                     _mainPS.printPrefix(peerResource.getName()
316                             + "_ins.INPORT_"
317                             + peerPort.getBasename()
318                             + peerPort.getName().replaceAll(
319                             "_([0-9]+)", "[$1]").replaceFirst(
320                             peerPort.getBasename(), ""));
321                 }
322                 else if (p.isInPort()) {
323                     _mainPS.printPrefix(peerResource.getName()
324                             + "_ins.OUTPORT_"
325                             + peerPort.getBasename()
326                             + peerPort.getName().replaceAll(
327                             "_([0-9]+)", "[$1]").replaceFirst(
328                             peerPort.getBasename(), ""));
329                 }
330             }
331             else {
332                 if (p.isOutPort()) {
333                     _mainPS.printPrefix(peerResource.getName()
334                             + "_ins.INPORT_" + peerPort.getName());
335                 }
336                 else if (p.isInPort()) {
337                     _mainPS.printPrefix(peerResource.getName()
338                             + "_ins.OUTPORT_" + peerPort.getName());
339                 }
340             }
341             _mainPS.println(" = &" + x.getName() + "_ins;");
342         }
343     }
344
345     protected CodePrintStream _mainPS = null;
346     protected String _dir = null;
347 }