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