dol: initial epiphany code generator (untested)
[jump.git] / dol / src / dol / visitor / epiphany / EpiphanyVisitor.java
index d2a39e8978b85ba7382b6e38071ba402caf98ad2..2c0c642a5a0b173c44276cafaf668f9d815942e8 100644 (file)
 package dol.visitor.Epiphany;
 
+import java.util.Vector;
+
+/* file management */
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.jar.JarFile;
+import dol.util.JarCopier;
+import dol.util.Copier;
+import dol.util.Sed;
+
+/* DOL elements */
 import dol.visitor.PNVisitor;
+import dol.datamodel.pn.Resource;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Connection;
+import dol.datamodel.pn.Port;
 
 public class EpiphanyVisitor extends PNVisitor {
+       private String _epiphanyHostName = "EpiphanyHost";
+       private String _packageName;
+       private Vector<EpiphanyBuffer> _buffers = new Vector<EpiphanyBuffer>();
+       private Integer _numShmBufs = 0;
+
        /* Constructor */
        public EpiphanyVisitor(String packageName) {
-               System.out.println("EPIPHANY VISITOR CONSTRUCTOR");
+               _packageName = packageName + _delimiter + "src";
+       }
+
+       /* ProcessNetwork Visitor */
+       public void visitComponent(ProcessNetwork pn) {
+               try {
+                       /* create list of buffers */
+                       createBuffers(pn);
+
+                       /* copy static files */
+                       copyStaticFiles();
+
+                       /* create process wrappers
+                          TODO: fix _epiphanyHostName ?? */
+                       for (Process p : pn.getProcessList()) {
+                               if(!_epiphanyHostName.equals(p.getBasename()))
+                                       createProcessWrapper(p);
+                       }
+
+                       /* create and copy shared header */
+                       createSharedHeader();
+
+                       /* create and copy host main application */
+                       createHostApplication(pn);
+
+                       /* create and copy Makefile */
+                       createMakefile(pn);
+
+               } catch (Exception e) {
+                       System.out.println("Exception: " + e.getMessage());
+                       e.printStackTrace();
+               }
+       }
+
+       /* Search for all structures of type
+          "Process-Port-Connection-Port-Channel-Port-Connection-Port-Process"
+          and save src/dst Process, src/dst Port and Channel */
+       private void createBuffers(ProcessNetwork pn)
+       {
+               for(Connection c1 : pn.getConnectionList()) {
+                       for(Connection c2 : pn.getConnectionList()) {
+                               if(c1 == c2) continue;
+
+                               if(c1.getTarget() == c2.getOrigin() &&
+                                  "fifo".equals(c1.getTarget().getType()) &&
+                                  "fifo".equals(c2.getOrigin().getType())) {
+
+                                       Process src  = (Process)c1.getOrigin();
+                                       Port    srcP = c1.getOriginPort();
+                                       Process dst  = (Process)c2.getTarget();
+                                       Port    dstP = c2.getTargetPort();
+                                       Channel ch   = (Channel)c1.getTarget();
+
+                                       createBuffer(ch, src, srcP, dst, dstP);
+                               }
+                       }
+               }
+       }
+
+       /* create a buffer assignment structure */
+       private void createBuffer(Channel ch,
+               Process src, Port srcP,
+               Process dst, Port dstP)
+       {
+//             TODO: all buffers are SHM buffers for now
+//             if(src.getBasename().equals(_epiphanyHostName) ||
+//                dst.getBasename().equals(_epiphanyHostName)) {
+                       /* this is an SHM buffer */
+                       System.out.println("\tBuffer: " +
+                               src.getBasename() + ":" + srcP.getBasename() +
+                               " ==> " +
+                               dst.getBasename() + ":" + dstP.getBasename() +
+                               " (size " + ch.getSize() + ")" +
+                               " as SHM:" + _numShmBufs);
+
+                       EpiphanyBuffer buf = new EpiphanyBuffer();
+                       buf.type = "shm";
+                       buf.srcProcess = src; buf.srcPort = srcP;
+                       buf.dstProcess = dst; buf.dstPort = dstP;
+                       buf.shmIndex = _numShmBufs; buf.size = ch.getSize();
+                       _buffers.add(buf);
+                       _numShmBufs++;
+
+//             } else {
+                       /* this is an C2C buffer */
+//                     System.out.println("C2CBUF: " +
+//                             src.getBasename() + ":" + srcP.getBasename() +
+//                             " ==> " +
+//                             dst.getBasename() + ":" + dstP.getBasename() +
+//                             " (size " + ch.getSize() + ")");
+//             }
+       }
+
+       /* return buffer structure for a given process:port combination */
+       private EpiphanyBuffer getBuffer(Process process, Port port)
+               throws Exception
+       {
+               for(EpiphanyBuffer buf : _buffers) {
+                       if(port == buf.srcPort ||
+                          port == buf.dstPort) {
+                               return(buf);
+                       }
+               }
+
+               throw new Exception("No buffer for '" + port + "' found!");
+       }
+
+       /* Copy a file from the JAR-file to some destination.
+          Copier() supports JAR-sources for directories only,
+          although it has a copyFile method. */
+       private void copyFile(File src, File dst) throws IOException {
+               if(src.toString().contains("dol.jar!"))
+       {
+                       String jarName = src.toString();
+                       jarName = jarName.substring(jarName.indexOf("file:") + 5, jarName.lastIndexOf("!"));
+                       String srcName = src.toString();
+                              srcName = srcName.substring(src.toString().lastIndexOf("!") + 2);
+                              srcName = srcName.replaceAll("\\\\", "/");
+                       JarFile jar = new JarFile(jarName);
+                       JarCopier copier = new JarCopier();
+                       copier.copyFile(jar, srcName, dst.toString());
+               } else {
+                       throw new IOException("Source file must be in JAR file.");
+               }
+       }
+
+       /* create directories, copy processes and library */
+       private void copyStaticFiles() throws IOException,FileNotFoundException
+       {
+               System.out.print("\tcopyStaticFiles(): ");
+
+               /* create folders */
+               System.out.print("directories, ");
+               File dir;
+               dir = new File(_packageName);
+               dir.mkdirs();
+               dir = new File(_packageName + _delimiter + "esrc");
+               dir.mkdirs();
+               dir = new File(_packageName + _delimiter + "hsrc");
+               dir.mkdirs();
+               dir = new File(_packageName + _delimiter + "lib");
+               dir.mkdirs();
+               dir = new File(_packageName + _delimiter + "bin");
+               dir.mkdirs();
+
+               /* copy processes */
+               System.out.print("processes, ");
+               File src  = new File("src");
+               File dest = new File(_packageName + _delimiter + "esrc");
+               new Copier().copy(src, dest);
+
+               /* copy library */
+               System.out.print("lib, ");
+               String libPath = _ui.getMySystemCLib();
+                      libPath = libPath.replaceAll("systemC", "epiphany");
+               src  = new File(libPath);
+               dest = new File(_packageName + _delimiter + "lib");
+               new Copier().copy(src, dest);
+
+               System.out.println("finished!");
+       }
+
+       /* create a process_Wrapper.c file */
+       private void createProcessWrapper(Process p) throws Exception
+       {
+               System.out.println("\tcreateProcessWrapper(): " +
+                       p.getBasename());
+
+               /* copy template file */
+               String filename = _packageName + _delimiter + "esrc" +
+                                 _delimiter + p.getBasename() + "_Wrapper.c";
+               String template = _ui.getMySystemCLib() + _delimiter +
+                                 "process_Wrapper.c";
+                      template = template.replaceAll("systemC", "epiphany");
+                      template = template.replaceAll("lib", "template");
+
+               File fFilename = new File(filename);
+               File fTemplate = new File(template);
+               copyFile(fTemplate, fFilename);
+
+               /* handle this process' ports */
+               Integer portNum       = 0;
+               String  portMapping   = "";
+               String  portFunctions = "";
+               for (Port port : p.getPortList()) {
+                       EpiphanyBuffer buf = getBuffer(p, port);
+
+                       /* port mapping */
+                       portMapping += "\t{ \"" + port.getBasename() + "\", size_" + portNum + ", level_" + portNum + ", ";
+                       portMapping += port.isInPort() ? "read_" + portNum + ", " : "NULL, ";
+                       portMapping += port.isOutPort() ? "write_" + portNum + ", " : "NULL, ";
+                       portMapping += "},\n";
+
+                       /* port access functions  - TODO: c2c buffers */
+                       if("shm".equals(buf.type)) {
+                               Integer bufNum = buf.shmIndex;
+
+                               portFunctions += "int size_" + portNum + "(void) { return(size_shm(&shm.buf" + bufNum + ")); }\n";
+                               portFunctions += "int level_" + portNum + "(void) { return(level_shm(&shm.buf" + bufNum + ")); }\n";
+                               if(port.isInPort()) {
+                                       portFunctions += "int read_" + portNum + "(void *buf, int len) { return(read_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
+                               }
+
+                               if(port.isOutPort()) {
+                                       portFunctions += "int write_" + portNum + "(void *buf, int len) { return(write_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
+                               }
+                       } else {
+                               throw new Exception("unknown port type");
+                       }
+
+                       portNum++;
+               }
+
+               /* replace information */
+               Sed sed = new Sed();
+               sed.sed(filename, "@@PROCESSNAME@@",   p.getBasename());
+               sed.sed(filename, "@@NUM_PORTS@@",     portNum.toString());
+               sed.sed(filename, "@@PORTMAPPING@@",   portMapping);
+               sed.sed(filename, "@@PORTFUNCTIONS@@", portFunctions);
+       }
+
+       /* create the shared.h header file */
+       private void createSharedHeader() throws Exception
+       {
+               System.out.print("\tcreateSharedHeader(): ");
+
+               /* copy template file */
+               String filename = _packageName + _delimiter + "shared.h";
+               String template = _ui.getMySystemCLib() + _delimiter +
+                                 "shared.h";
+                      template = template.replaceAll("systemC", "epiphany");
+                      template = template.replaceAll("lib", "template");
+               File fFilename = new File(filename);
+               File fTemplate = new File(template);
+               copyFile(fTemplate, fFilename);
+
+               /* generate replacement string */
+               String shmBufs = "";
+               for(EpiphanyBuffer buf : _buffers) {
+                       if("shm".equals(buf.type)) {
+                               shmBufs +=
+                               "\ntypedef struct {\n" +
+                               "\tuint32_t rp;\n" +
+                               "\tuint32_t wp;\n" +
+                               "\tuint32_t size;\n" +
+                               "\tchar     buf[" + buf.size + "];\n" +
+                               "} PACKED buf" + buf.shmIndex + "_t;\n";
+                       }
+               }
+
+               /* do the replace */
+               Sed sed = new Sed();
+               sed.sed(filename, "@@SHM_BUF_STRUCTS@@", shmBufs);
+               System.out.println("done!");
+       }
+
+       /* create the host application */
+       private void createHostApplication(ProcessNetwork pn) throws Exception
+       {
+               System.out.print("\tcreateHostApplication(): ");
+
+               /* copy template file */
+               String filename = _packageName + _delimiter + "hsrc/main.c";
+               String template = _ui.getMySystemCLib() + _delimiter +
+                                 "main.c";
+                      template = template.replaceAll("systemC", "epiphany");
+                      template = template.replaceAll("lib", "template");
+               File fFilename = new File(filename);
+               File fTemplate = new File(template);
+               copyFile(fTemplate, fFilename);
+
+               /* generate srec filenames */
+               String srecFiles = "";
+               Integer srecNum = 0;
+               for(Process p : pn.getProcessList()) {
+                       if(!_epiphanyHostName.equals(p.getBasename())) {
+                               srecFiles += "\t\"bin/" + p.getBasename() + ".srec\",\n";
+                               srecNum++;
+                       }
+               }
+
+               /* generate shm buffer initialization code sequence */
+               String shmBufInit = "";
+               for(EpiphanyBuffer buf : _buffers) {
+                       if("shm".equals(buf.type)) {
+                               String tmp = "\tshm.buf" + buf.shmIndex;
+
+                               shmBufInit +=
+                                       tmp + ".size = " + buf.size + ";\n" +
+                                       tmp + ".rp   = 0;\n" +
+                                       tmp + ".wp   = 0;\n";
+                       }
+               }
+
+               /* do the replace */
+               Sed sed = new Sed();
+               sed.sed(filename, "@@SREC_FILES@@",   srecFiles);
+               sed.sed(filename, "@@SREC_NUM@@",     srecNum.toString());
+               sed.sed(filename, "@@SHM_BUF_INIT@@", shmBufInit);
+               System.out.println("done!");
+       }
+
+       /* create Makefile */
+       private void createMakefile(ProcessNetwork pn) throws Exception
+       {
+               System.out.print("\tcreateMakefile(): ");
+
+               /* copy template file */
+               String filename = _packageName + _delimiter + "Makefile";
+               String template = _ui.getMySystemCLib() + _delimiter +
+                                 "Makefile";
+                      template = template.replaceAll("systemC", "epiphany");
+                      template = template.replaceAll("lib", "template");
+               File fFilename = new File(filename);
+               File fTemplate = new File(template);
+               copyFile(fTemplate, fFilename);
+
+               /* generate srec filenames */
+               String srecFiles = "";
+               for(Process p : pn.getProcessList()) {
+                       if(!_epiphanyHostName.equals(p.getBasename())) {
+                               srecFiles += "\\$(DEST)/" +
+                                       p.getBasename() + ".srec ";
+                       }
+               }
+
+               /* do the replace */
+               Sed sed = new Sed();
+               sed.sed(filename, "@@SREC_FILES@@",   srecFiles);
+               System.out.println("done!");
        }
 }