dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / HdsdProcessVisitor.java
1 package dol.visitor.hdsd;
2
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.util.Vector;
7
8 import dol.datamodel.pn.Port;
9 import dol.datamodel.pn.Process;
10 import dol.datamodel.pn.ProcessNetwork;
11 import dol.datamodel.pn.SourceCode;
12 import dol.util.CodePrintStream;
13 import dol.util.Sed;
14 import dol.visitor.PNVisitor;
15
16 /**
17  * Visitor that is used to generate
18  * a wrapper class for a process: process_wrapper.[h/cpp].
19  */
20 public class HdsdProcessVisitor extends PNVisitor {
21
22     /**
23      * Constructor.
24      *
25      * @param dir target directory
26      */
27     public HdsdProcessVisitor(String dir) {
28         _dir = dir;
29     }
30
31     /**
32      *
33      * @param x process network that needs to be rendered
34      */
35     public void visitComponent(ProcessNetwork x) {
36         try {
37             Vector<String> pList = new Vector<String>();
38
39             for (Process p : x.getProcessList()) {
40                 String basename = p.getBasename();
41                 if (!pList.contains(basename)) {
42                     pList.add(basename);
43                     p.accept(this);
44                 }
45             }
46         }
47         catch (Exception e) {
48             System.out.println("Process Visitor: exception "
49                     + "occured: " + e.getMessage());
50             e.printStackTrace();
51         }
52     }
53
54     /**
55      *
56      * @param p process that needs to be rendered
57      */
58     public void visitComponent(Process p) {
59         try {
60             _createCppFile(p);
61             _createHeaderFile(p);
62             _adaptSources(p);
63         }
64         catch (Exception e) {
65             System.out.println("Process Visitor: exception "
66                     + "occured: " + e.getMessage());
67             e.printStackTrace();
68         }
69     }
70
71     /**
72      *
73      */
74     protected void _adaptSources(Process p) throws IOException {
75         Sed sed = new Sed();
76         for (Port port : p.getPortList()) {
77             String processHeaderFile;
78
79             for (SourceCode sr : p.getSrcList()) {
80                 processHeaderFile = _dir + _delimiter + ".."
81                         + _delimiter + "processes" + _delimiter
82                         + sr.getLocality().
83                         replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
84
85                 if (port.isOutPort()) {
86                     sed.sed(processHeaderFile,
87                             "(#define[ ]*PORT_\\w*[ ]*)\"?"
88                             + port.getBasename() + "\"?",
89                             "$1 " + "&((static_cast<" + p.getBasename()
90                             + "_wrapper *>(p->wptr))->OUTPORT_"
91                             + port.getBasename() + ")");
92
93                 }
94                 else if (port.isInPort()) {
95                     sed.sed(processHeaderFile,
96                             "(#define[ ]*PORT_\\w*[ ]*)\"?"
97                             + port.getBasename() + "\"?",
98                             "$1 " + "&((static_cast<" + p.getBasename()
99                             + "_wrapper *>(p->wptr))->INPORT_"
100                             + port.getBasename() + ")");
101                 }
102             }
103         }
104     }
105
106     /**
107      *
108      */
109     protected void _createCppFile(Process p) throws IOException {
110         String filename = _dir + _delimiter + p.getBasename()
111                 + "_wrapper.cpp";
112         OutputStream file = new FileOutputStream(filename);
113         CodePrintStream ps = new CodePrintStream(file);
114
115         ps.printPrefixln("#include \"" + p.getBasename()
116                 + "_wrapper.h\"");
117         ps.printPrefixln();
118
119         //define the write/read
120         if (p.hasOutPorts()) {
121             ps.printPrefixln("static inline int DOL_write(void *port, "
122                     + "void *buf, int len, DOLProcess *process)");
123             ps.printLeftBracket();
124             ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
125                     + "<sc_port<write_if> *>(port);");
126             ps.printPrefixln("char *str = static_cast<char*>(buf);");
127
128             /* begin of profiling: write event */
129             ps.printPrefixln("#ifdef INCLUDE_PROFILER");
130             ps.printPrefixln("(static_cast<" + p.getBasename()
131                   + "_wrapper *>(process->wptr))" + "->addToProfile(\"w\", port, len);");
132             ps.printPrefixln("#endif");
133             /* end of profiling */
134
135             ps.printPrefixln("while (len-- > 0) ");
136             ps.printPrefixln("    (*write_port)->write(*str++);");
137             ps.printRightBracket();
138             ps.printPrefixln();
139             ps.printPrefixln("static inline int DOL_wtest(void *port, "
140                     + "int len, DOLProcess *process)");
141             ps.printLeftBracket();
142             ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
143                     + "<sc_port<write_if> *>(port);");
144             ps.printPrefixln("return (*write_port)->wtest(len);");
145             ps.printRightBracket();
146             ps.printPrefixln();
147         }
148         if (p.hasInPorts()) {
149             ps.printPrefixln("static inline int DOL_read(void *port, "
150                     + "void *buf, int len, DOLProcess *process)");
151             ps.printLeftBracket();
152             ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
153                     + "<sc_port<read_if> *>(port);");
154             ps.printPrefixln("char *str = static_cast<char*>(buf);");
155
156             /* begin of profiling: read event */
157             ps.printPrefixln("#ifdef INCLUDE_PROFILER");
158             ps.printPrefixln("(static_cast<" + p.getBasename()
159                   + "_wrapper *>(process->wptr))" + "->addToProfile(\"r\", port, len);");
160             ps.printPrefixln("#endif");
161             /* end of profiling */
162
163             ps.printPrefixln("while (len-- > 0) ");
164             ps.printPrefixln("    (*read_port)->read(*str++);");
165             ps.printRightBracket();
166             ps.printPrefixln();
167             ps.printPrefixln("static inline int DOL_rtest(void *port, "
168                     + "int len, DOLProcess *process)");
169             ps.printLeftBracket();
170             ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
171                     + "<sc_port<read_if> *>(port);");
172             ps.printPrefixln("return (*read_port)->rtest(len);");
173             ps.printRightBracket();
174         }
175         ps.printPrefixln();
176         ps.printPrefixln("static inline int DOL_detach(DOLProcess *p)");
177         ps.printLeftBracket();
178         ps.printPrefixln("(static_cast<" + p.getBasename()
179                 + "_wrapper *>(p->wptr))" + "->setDetached();");
180         ps.printRightBracket();
181         ps.printPrefixln();
182
183         ps.printPrefixln("#define GETINDEX(dimension) \\");
184         ps.printPrefixln("(static_cast<" + p.getBasename()
185                 + "_wrapper *>(p->wptr))->_processIndex[dimension]");
186         ps.printPrefixln();
187         //include c file
188         for (SourceCode sr : p.getSrcList()) {
189             ps.printPrefixln("#include \"" + sr.getLocality() + "\"");
190         }
191         ps.printPrefixln();
192
193         /* begin of profiling: function that adds an entry to the profile */
194         ps.printPrefixln("#ifdef INCLUDE_PROFILER");
195         ps.printPrefixln("void " + p.getBasename() + "_wrapper::addToProfile(const char *evnt, void *port, int length)");
196         ps.printLeftBracket();
197         ps.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u %s %s %p %d\\n\", profiler_event_counter++, _uniqueName, evnt, port, length);");
198         ps.printRightBracket();
199         ps.printPrefixln("#endif");
200         /* end of profiling */
201
202         ps.printPrefixln("void " + p.getBasename()
203                 + "_wrapper::setDetached() { _detached = 1; }");
204         ps.printPrefixln("int " + p.getBasename()
205                 + "_wrapper::isDetached() { return _detached; }");
206         ps.printPrefixln();
207
208         //constructor
209         ps.printPrefixln(p.getBasename() + "_wrapper::" + p.getBasename()
210                 + "_wrapper(sc_module_name name=sc_gen_unique_name(\""
211                 + p.getBasename() + "\" ))  : sc_module(name),  _process("
212                 + p.getBasename() +  ")" + ", _detached(0)");
213         ps.printLeftBracket();
214         ps.printPrefixln("struct _local_states *_state = "
215                 + "new struct _local_states;");
216         ps.printPrefixln("memcpy(_state, " + p.getBasename()
217                 + ".local, sizeof(struct _local_states));");
218         ps.printPrefixln("_process.local = _state;");
219         //ps.printPrefixln("sprintf(_process.local->id, name);");
220         ps.printPrefixln("_process.wptr = this;");
221         ps.printPrefixln();
222         ps.printPrefixln("char buffer[255];");
223         ps.printPrefixln("sprintf(buffer, name);");
224
225         /* begin of profiling: save unique name for writing it to
226            the profile later */
227         ps.printPrefixln("#ifdef INCLUDE_PROFILER");
228         ps.printPrefixln("sprintf(_uniqueName, name);");
229         ps.printPrefixln("#endif");
230         /* end of profiling */
231
232         ps.printPrefixln("for (int i = 0; i < 4; i++)");
233         ps.printPrefixln("    _processIndex[i] = "
234                 + "getIndex(buffer, \"_\", i);");
235
236         ps.printPrefixln();
237         ps.printRightBracket();
238
239         ps.printPrefixln();
240         ps.printPrefixln("void " + p.getBasename()
241                 + "_wrapper::initialize()");
242         ps.printLeftBracket();
243         ps.printPrefixln("_process.init(&_process);");
244         ps.printRightBracket();
245         ps.printPrefixln();
246         ps.printPrefixln("int " + p.getBasename() + "_wrapper::fire()");
247         ps.printLeftBracket();
248         ps.printPrefixln();
249         ps.printPrefixln("return _process.fire(&_process);");
250         ps.printRightBracket();
251     }
252
253     protected void _createHeaderFile(Process p)
254         throws IOException {
255         String filename = _dir + _delimiter + p.getBasename()
256                 + "_wrapper.h";
257         OutputStream file = new FileOutputStream(filename);
258         CodePrintStream ps = new CodePrintStream(file);
259
260         ps.printPrefixln("#ifndef " + p.getBasename() + "_WRAPPER_H");
261         ps.printPrefixln("#define " + p.getBasename() + "_WRAPPER_H");
262         ps.printPrefixln();
263         ps.printPrefixln("#include \"systemc.h\"");
264         ps.printPrefixln();
265         ps.printPrefixln("#include \"dol_sched_if.h\"");
266         ps.printPrefixln("#include \"simple_fifo.h\"");
267         ps.printPrefixln();
268         ps.printPrefixln("#include <dol.h>");
269         ps.printPrefixln();
270
271         /* begin of profiling: externally defined global variables */
272         ps.println();
273         ps.printPrefixln("#ifdef INCLUDE_PROFILER");
274         ps.printPrefixln("extern FILE *profiler_output_file;");
275         ps.printPrefixln("extern unsigned int profiler_event_counter;");
276         ps.printPrefixln("#endif");
277         ps.printPrefixln();
278         /* end of profiling */
279
280         ps.printPrefixln("class " + p.getBasename() +
281                          "_wrapper : virtual public dol_sched_if, " +
282                          "public sc_module");
283         ps.printLeftBracket();
284         ps.printPrefixln("public:");
285
286
287         Vector<String> portList = new Vector<String>();
288         for (Port port : p.getPortList()) {
289             String basename = port.getBasename();
290
291             if (!portList.contains(basename)) {
292                 portList.add(basename);
293
294                 if (!port.getRange().equals("")) {
295                     if (port.isOutPort()) {
296                         ps.printPrefixln("sc_port<write_if> OUTPORT_"
297                                 + port.getBasename() + "["
298                                 + port.getRange().replaceAll(
299                                 ";", "\\]\\[") + "];");
300                     }
301                     else if (port.isInPort()) {
302                         ps.printPrefixln("sc_port<read_if> INPORT_"
303                                 + port.getBasename() + "["
304                                 + port.getRange().replaceAll(
305                                 ";", "\\]\\[") + "];");
306                     }
307                 }
308                 else {
309                     if (port.isOutPort()) {
310                         ps.printPrefixln("sc_port<write_if> OUTPORT_"
311                                 + port.getName() + ";");
312                     }
313                     else if (port.isInPort()) {
314                         ps.printPrefixln("sc_port<read_if> INPORT_"
315                                 + port.getName() + ";");
316                     }
317                 }
318             }
319         }
320         ps.printPrefixln("int _processIndex[4];");
321
322         /* begin of profiling: name variable declaration */
323         ps.printPrefixln("#ifdef INCLUDE_PROFILER");
324         ps.printPrefixln("char _uniqueName[255];");
325         ps.printPrefixln("#endif");
326         /* end of profiling */
327
328         ps.printPrefixln();
329         ps.printPrefixln("" + p.getBasename()
330                 + "_wrapper(sc_module_name name);");
331         ps.printPrefixln();
332         ps.printPrefixln("~" + p.getBasename() + "_wrapper() {}");
333         ps.printPrefixln();
334
335         /* begin of profiling: addtoprofile member function */
336         ps.printPrefixln("#ifdef INCLUDE_PROFILER");
337         ps.printPrefixln("void addToProfile(const char *, void *, int);");
338         ps.printPrefixln("#endif");
339         ps.printPrefixln();
340         /* end of profiling */
341
342         ps.printPrefixln("// DOL scheduler interface");
343         ps.printPrefixln("void initialize();");
344         ps.printPrefixln("int fire();");
345         ps.printPrefixln("void setDetached();");
346         ps.printPrefixln("int isDetached();");
347         ps.printPrefixln();
348         ps.printPrefixln();
349         ps.printPrefixln("protected:");
350         ps.printPrefixln();
351         ps.printPrefixln("private:");
352         ps.printPrefixln("" + p.getBasename() + "_wrapper( const "
353                 + p.getBasename() + "_wrapper& );");
354         ps.printPrefixln("" + p.getBasename() + "_wrapper& operator = "
355                 + "( const " + p.getBasename() + "_wrapper& );");
356         ps.printPrefixln("DOLProcess _process;");
357         ps.printPrefixln("int _detached;");
358         ps.printRightBracket();
359         ps.printPrefixln(";");
360         ps.printPrefixln("#endif");
361     }
362
363     protected String _dir = null;
364 }