dol: initial epiphany code generator (untested)
[jump.git] / dol / src / dol / visitor / epiphany / EpiphanyVisitor.java
1 package dol.visitor.Epiphany;
2
3 import java.util.Vector;
4
5 /* file management */
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.io.IOException;
9 import java.util.jar.JarFile;
10 import dol.util.JarCopier;
11 import dol.util.Copier;
12 import dol.util.Sed;
13
14 /* DOL elements */
15 import dol.visitor.PNVisitor;
16 import dol.datamodel.pn.Resource;
17 import dol.datamodel.pn.ProcessNetwork;
18 import dol.datamodel.pn.Process;
19 import dol.datamodel.pn.Channel;
20 import dol.datamodel.pn.Connection;
21 import dol.datamodel.pn.Port;
22
23 public class EpiphanyVisitor extends PNVisitor {
24         private String _epiphanyHostName = "EpiphanyHost";
25         private String _packageName;
26         private Vector<EpiphanyBuffer> _buffers = new Vector<EpiphanyBuffer>();
27         private Integer _numShmBufs = 0;
28
29         /* Constructor */
30         public EpiphanyVisitor(String packageName) {
31                 _packageName = packageName + _delimiter + "src";
32         }
33
34         /* ProcessNetwork Visitor */
35         public void visitComponent(ProcessNetwork pn) {
36                 try {
37                         /* create list of buffers */
38                         createBuffers(pn);
39
40                         /* copy static files */
41                         copyStaticFiles();
42
43                         /* create process wrappers
44                            TODO: fix _epiphanyHostName ?? */
45                         for (Process p : pn.getProcessList()) {
46                                 if(!_epiphanyHostName.equals(p.getBasename()))
47                                         createProcessWrapper(p);
48                         }
49
50                         /* create and copy shared header */
51                         createSharedHeader();
52
53                         /* create and copy host main application */
54                         createHostApplication(pn);
55
56                         /* create and copy Makefile */
57                         createMakefile(pn);
58
59                 } catch (Exception e) {
60                         System.out.println("Exception: " + e.getMessage());
61                         e.printStackTrace();
62                 }
63         }
64
65         /* Search for all structures of type
66            "Process-Port-Connection-Port-Channel-Port-Connection-Port-Process"
67            and save src/dst Process, src/dst Port and Channel */
68         private void createBuffers(ProcessNetwork pn)
69         {
70                 for(Connection c1 : pn.getConnectionList()) {
71                         for(Connection c2 : pn.getConnectionList()) {
72                                 if(c1 == c2) continue;
73
74                                 if(c1.getTarget() == c2.getOrigin() &&
75                                    "fifo".equals(c1.getTarget().getType()) &&
76                                    "fifo".equals(c2.getOrigin().getType())) {
77
78                                         Process src  = (Process)c1.getOrigin();
79                                         Port    srcP = c1.getOriginPort();
80                                         Process dst  = (Process)c2.getTarget();
81                                         Port    dstP = c2.getTargetPort();
82                                         Channel ch   = (Channel)c1.getTarget();
83
84                                         createBuffer(ch, src, srcP, dst, dstP);
85                                 }
86                         }
87                 }
88         }
89
90         /* create a buffer assignment structure */
91         private void createBuffer(Channel ch,
92                 Process src, Port srcP,
93                 Process dst, Port dstP)
94         {
95 //              TODO: all buffers are SHM buffers for now
96 //              if(src.getBasename().equals(_epiphanyHostName) ||
97 //                 dst.getBasename().equals(_epiphanyHostName)) {
98                         /* this is an SHM buffer */
99                         System.out.println("\tBuffer: " +
100                                 src.getBasename() + ":" + srcP.getBasename() +
101                                 " ==> " +
102                                 dst.getBasename() + ":" + dstP.getBasename() +
103                                 " (size " + ch.getSize() + ")" +
104                                 " as SHM:" + _numShmBufs);
105
106                         EpiphanyBuffer buf = new EpiphanyBuffer();
107                         buf.type = "shm";
108                         buf.srcProcess = src; buf.srcPort = srcP;
109                         buf.dstProcess = dst; buf.dstPort = dstP;
110                         buf.shmIndex = _numShmBufs; buf.size = ch.getSize();
111                         _buffers.add(buf);
112                         _numShmBufs++;
113
114 //              } else {
115                         /* this is an C2C buffer */
116 //                      System.out.println("C2CBUF: " +
117 //                              src.getBasename() + ":" + srcP.getBasename() +
118 //                              " ==> " +
119 //                              dst.getBasename() + ":" + dstP.getBasename() +
120 //                              " (size " + ch.getSize() + ")");
121 //              }
122         }
123
124         /* return buffer structure for a given process:port combination */
125         private EpiphanyBuffer getBuffer(Process process, Port port)
126                 throws Exception
127         {
128                 for(EpiphanyBuffer buf : _buffers) {
129                         if(port == buf.srcPort ||
130                            port == buf.dstPort) {
131                                 return(buf);
132                         }
133                 }
134
135                 throw new Exception("No buffer for '" + port + "' found!");
136         }
137
138         /* Copy a file from the JAR-file to some destination.
139            Copier() supports JAR-sources for directories only,
140            although it has a copyFile method. */
141         private void copyFile(File src, File dst) throws IOException {
142                 if(src.toString().contains("dol.jar!"))
143         {
144                         String jarName = src.toString();
145                         jarName = jarName.substring(jarName.indexOf("file:") + 5, jarName.lastIndexOf("!"));
146                         String srcName = src.toString();
147                                srcName = srcName.substring(src.toString().lastIndexOf("!") + 2);
148                                srcName = srcName.replaceAll("\\\\", "/");
149                         JarFile jar = new JarFile(jarName);
150                         JarCopier copier = new JarCopier();
151                         copier.copyFile(jar, srcName, dst.toString());
152                 } else {
153                         throw new IOException("Source file must be in JAR file.");
154                 }
155         }
156
157         /* create directories, copy processes and library */
158         private void copyStaticFiles() throws IOException,FileNotFoundException
159         {
160                 System.out.print("\tcopyStaticFiles(): ");
161
162                 /* create folders */
163                 System.out.print("directories, ");
164                 File dir;
165                 dir = new File(_packageName);
166                 dir.mkdirs();
167                 dir = new File(_packageName + _delimiter + "esrc");
168                 dir.mkdirs();
169                 dir = new File(_packageName + _delimiter + "hsrc");
170                 dir.mkdirs();
171                 dir = new File(_packageName + _delimiter + "lib");
172                 dir.mkdirs();
173                 dir = new File(_packageName + _delimiter + "bin");
174                 dir.mkdirs();
175
176                 /* copy processes */
177                 System.out.print("processes, ");
178                 File src  = new File("src");
179                 File dest = new File(_packageName + _delimiter + "esrc");
180                 new Copier().copy(src, dest);
181
182                 /* copy library */
183                 System.out.print("lib, ");
184                 String libPath = _ui.getMySystemCLib();
185                        libPath = libPath.replaceAll("systemC", "epiphany");
186                 src  = new File(libPath);
187                 dest = new File(_packageName + _delimiter + "lib");
188                 new Copier().copy(src, dest);
189
190                 System.out.println("finished!");
191         }
192
193         /* create a process_Wrapper.c file */
194         private void createProcessWrapper(Process p) throws Exception
195         {
196                 System.out.println("\tcreateProcessWrapper(): " +
197                         p.getBasename());
198
199                 /* copy template file */
200                 String filename = _packageName + _delimiter + "esrc" +
201                                   _delimiter + p.getBasename() + "_Wrapper.c";
202                 String template = _ui.getMySystemCLib() + _delimiter +
203                                   "process_Wrapper.c";
204                        template = template.replaceAll("systemC", "epiphany");
205                        template = template.replaceAll("lib", "template");
206
207                 File fFilename = new File(filename);
208                 File fTemplate = new File(template);
209                 copyFile(fTemplate, fFilename);
210
211                 /* handle this process' ports */
212                 Integer portNum       = 0;
213                 String  portMapping   = "";
214                 String  portFunctions = "";
215                 for (Port port : p.getPortList()) {
216                         EpiphanyBuffer buf = getBuffer(p, port);
217
218                         /* port mapping */
219                         portMapping += "\t{ \"" + port.getBasename() + "\", size_" + portNum + ", level_" + portNum + ", ";
220                         portMapping += port.isInPort() ? "read_" + portNum + ", " : "NULL, ";
221                         portMapping += port.isOutPort() ? "write_" + portNum + ", " : "NULL, ";
222                         portMapping += "},\n";
223
224                         /* port access functions  - TODO: c2c buffers */
225                         if("shm".equals(buf.type)) {
226                                 Integer bufNum = buf.shmIndex;
227
228                                 portFunctions += "int size_" + portNum + "(void) { return(size_shm(&shm.buf" + bufNum + ")); }\n";
229                                 portFunctions += "int level_" + portNum + "(void) { return(level_shm(&shm.buf" + bufNum + ")); }\n";
230                                 if(port.isInPort()) {
231                                         portFunctions += "int read_" + portNum + "(void *buf, int len) { return(read_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
232                                 }
233
234                                 if(port.isOutPort()) {
235                                         portFunctions += "int write_" + portNum + "(void *buf, int len) { return(write_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
236                                 }
237                         } else {
238                                 throw new Exception("unknown port type");
239                         }
240
241                         portNum++;
242                 }
243
244                 /* replace information */
245                 Sed sed = new Sed();
246                 sed.sed(filename, "@@PROCESSNAME@@",   p.getBasename());
247                 sed.sed(filename, "@@NUM_PORTS@@",     portNum.toString());
248                 sed.sed(filename, "@@PORTMAPPING@@",   portMapping);
249                 sed.sed(filename, "@@PORTFUNCTIONS@@", portFunctions);
250         }
251
252         /* create the shared.h header file */
253         private void createSharedHeader() throws Exception
254         {
255                 System.out.print("\tcreateSharedHeader(): ");
256
257                 /* copy template file */
258                 String filename = _packageName + _delimiter + "shared.h";
259                 String template = _ui.getMySystemCLib() + _delimiter +
260                                   "shared.h";
261                        template = template.replaceAll("systemC", "epiphany");
262                        template = template.replaceAll("lib", "template");
263                 File fFilename = new File(filename);
264                 File fTemplate = new File(template);
265                 copyFile(fTemplate, fFilename);
266
267                 /* generate replacement string */
268                 String shmBufs = "";
269                 for(EpiphanyBuffer buf : _buffers) {
270                         if("shm".equals(buf.type)) {
271                                 shmBufs +=
272                                 "\ntypedef struct {\n" +
273                                 "\tuint32_t rp;\n" +
274                                 "\tuint32_t wp;\n" +
275                                 "\tuint32_t size;\n" +
276                                 "\tchar     buf[" + buf.size + "];\n" +
277                                 "} PACKED buf" + buf.shmIndex + "_t;\n";
278                         }
279                 }
280
281                 /* do the replace */
282                 Sed sed = new Sed();
283                 sed.sed(filename, "@@SHM_BUF_STRUCTS@@", shmBufs);
284                 System.out.println("done!");
285         }
286
287         /* create the host application */
288         private void createHostApplication(ProcessNetwork pn) throws Exception
289         {
290                 System.out.print("\tcreateHostApplication(): ");
291
292                 /* copy template file */
293                 String filename = _packageName + _delimiter + "hsrc/main.c";
294                 String template = _ui.getMySystemCLib() + _delimiter +
295                                   "main.c";
296                        template = template.replaceAll("systemC", "epiphany");
297                        template = template.replaceAll("lib", "template");
298                 File fFilename = new File(filename);
299                 File fTemplate = new File(template);
300                 copyFile(fTemplate, fFilename);
301
302                 /* generate srec filenames */
303                 String srecFiles = "";
304                 Integer srecNum = 0;
305                 for(Process p : pn.getProcessList()) {
306                         if(!_epiphanyHostName.equals(p.getBasename())) {
307                                 srecFiles += "\t\"bin/" + p.getBasename() + ".srec\",\n";
308                                 srecNum++;
309                         }
310                 }
311
312                 /* generate shm buffer initialization code sequence */
313                 String shmBufInit = "";
314                 for(EpiphanyBuffer buf : _buffers) {
315                         if("shm".equals(buf.type)) {
316                                 String tmp = "\tshm.buf" + buf.shmIndex;
317
318                                 shmBufInit +=
319                                         tmp + ".size = " + buf.size + ";\n" +
320                                         tmp + ".rp   = 0;\n" +
321                                         tmp + ".wp   = 0;\n";
322                         }
323                 }
324
325                 /* do the replace */
326                 Sed sed = new Sed();
327                 sed.sed(filename, "@@SREC_FILES@@",   srecFiles);
328                 sed.sed(filename, "@@SREC_NUM@@",     srecNum.toString());
329                 sed.sed(filename, "@@SHM_BUF_INIT@@", shmBufInit);
330                 System.out.println("done!");
331         }
332
333         /* create Makefile */
334         private void createMakefile(ProcessNetwork pn) throws Exception
335         {
336                 System.out.print("\tcreateMakefile(): ");
337
338                 /* copy template file */
339                 String filename = _packageName + _delimiter + "Makefile";
340                 String template = _ui.getMySystemCLib() + _delimiter +
341                                   "Makefile";
342                        template = template.replaceAll("systemC", "epiphany");
343                        template = template.replaceAll("lib", "template");
344                 File fFilename = new File(filename);
345                 File fTemplate = new File(template);
346                 copyFile(fTemplate, fFilename);
347
348                 /* generate srec filenames */
349                 String srecFiles = "";
350                 for(Process p : pn.getProcessList()) {
351                         if(!_epiphanyHostName.equals(p.getBasename())) {
352                                 srecFiles += "\\$(DEST)/" +
353                                         p.getBasename() + ".srec ";
354                         }
355                 }
356
357                 /* do the replace */
358                 Sed sed = new Sed();
359                 sed.sed(filename, "@@SREC_FILES@@",   srecFiles);
360                 System.out.println("done!");
361         }
362 }