dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / HdsdProcessVisitor.java
diff --git a/dol/src/dol/visitor/hdsd/HdsdProcessVisitor.java b/dol/src/dol/visitor/hdsd/HdsdProcessVisitor.java
new file mode 100644 (file)
index 0000000..2ba1044
--- /dev/null
@@ -0,0 +1,364 @@
+package dol.visitor.hdsd;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * Visitor that is used to generate
+ * a wrapper class for a process: process_wrapper.[h/cpp].
+ */
+public class HdsdProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public HdsdProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param p process that needs to be rendered
+     */
+    public void visitComponent(Process p) {
+        try {
+            _createCppFile(p);
+            _createHeaderFile(p);
+            _adaptSources(p);
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _adaptSources(Process p) throws IOException {
+        Sed sed = new Sed();
+        for (Port port : p.getPortList()) {
+            String processHeaderFile;
+
+            for (SourceCode sr : p.getSrcList()) {
+                processHeaderFile = _dir + _delimiter + ".."
+                        + _delimiter + "processes" + _delimiter
+                        + sr.getLocality().
+                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                if (port.isOutPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "&((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->OUTPORT_"
+                            + port.getBasename() + ")");
+
+                }
+                else if (port.isInPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "&((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->INPORT_"
+                            + port.getBasename() + ")");
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _createCppFile(Process p) throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.cpp";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#include \"" + p.getBasename()
+                + "_wrapper.h\"");
+        ps.printPrefixln();
+
+        //define the write/read
+        if (p.hasOutPorts()) {
+            ps.printPrefixln("static inline int DOL_write(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
+                    + "<sc_port<write_if> *>(port);");
+            ps.printPrefixln("char *str = static_cast<char*>(buf);");
+
+            /* begin of profiling: write event */
+            ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+            ps.printPrefixln("(static_cast<" + p.getBasename()
+                  + "_wrapper *>(process->wptr))" + "->addToProfile(\"w\", port, len);");
+            ps.printPrefixln("#endif");
+            /* end of profiling */
+
+            ps.printPrefixln("while (len-- > 0) ");
+            ps.printPrefixln("    (*write_port)->write(*str++);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+            ps.printPrefixln("static inline int DOL_wtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
+                    + "<sc_port<write_if> *>(port);");
+            ps.printPrefixln("return (*write_port)->wtest(len);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+        }
+        if (p.hasInPorts()) {
+            ps.printPrefixln("static inline int DOL_read(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
+                    + "<sc_port<read_if> *>(port);");
+            ps.printPrefixln("char *str = static_cast<char*>(buf);");
+
+            /* begin of profiling: read event */
+            ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+            ps.printPrefixln("(static_cast<" + p.getBasename()
+                  + "_wrapper *>(process->wptr))" + "->addToProfile(\"r\", port, len);");
+            ps.printPrefixln("#endif");
+            /* end of profiling */
+
+            ps.printPrefixln("while (len-- > 0) ");
+            ps.printPrefixln("    (*read_port)->read(*str++);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+            ps.printPrefixln("static inline int DOL_rtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
+                    + "<sc_port<read_if> *>(port);");
+            ps.printPrefixln("return (*read_port)->rtest(len);");
+            ps.printRightBracket();
+        }
+        ps.printPrefixln();
+        ps.printPrefixln("static inline int DOL_detach(DOLProcess *p)");
+        ps.printLeftBracket();
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))" + "->setDetached();");
+        ps.printRightBracket();
+        ps.printPrefixln();
+
+        ps.printPrefixln("#define GETINDEX(dimension) \\");
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))->_processIndex[dimension]");
+        ps.printPrefixln();
+        //include c file
+        for (SourceCode sr : p.getSrcList()) {
+            ps.printPrefixln("#include \"" + sr.getLocality() + "\"");
+        }
+        ps.printPrefixln();
+
+        /* begin of profiling: function that adds an entry to the profile */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("void " + p.getBasename() + "_wrapper::addToProfile(const char *evnt, void *port, int length)");
+        ps.printLeftBracket();
+        ps.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u %s %s %p %d\\n\", profiler_event_counter++, _uniqueName, evnt, port, length);");
+        ps.printRightBracket();
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::setDetached() { _detached = 1; }");
+        ps.printPrefixln("int " + p.getBasename()
+                + "_wrapper::isDetached() { return _detached; }");
+        ps.printPrefixln();
+
+        //constructor
+        ps.printPrefixln(p.getBasename() + "_wrapper::" + p.getBasename()
+                + "_wrapper(sc_module_name name=sc_gen_unique_name(\""
+                + p.getBasename() + "\" ))  : sc_module(name),  _process("
+                + p.getBasename() +  ")" + ", _detached(0)");
+        ps.printLeftBracket();
+        ps.printPrefixln("struct _local_states *_state = "
+                + "new struct _local_states;");
+        ps.printPrefixln("memcpy(_state, " + p.getBasename()
+                + ".local, sizeof(struct _local_states));");
+        ps.printPrefixln("_process.local = _state;");
+        //ps.printPrefixln("sprintf(_process.local->id, name);");
+        ps.printPrefixln("_process.wptr = this;");
+        ps.printPrefixln();
+        ps.printPrefixln("char buffer[255];");
+        ps.printPrefixln("sprintf(buffer, name);");
+
+        /* begin of profiling: save unique name for writing it to
+           the profile later */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("sprintf(_uniqueName, name);");
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln("for (int i = 0; i < 4; i++)");
+        ps.printPrefixln("    _processIndex[i] = "
+                + "getIndex(buffer, \"_\", i);");
+
+        ps.printPrefixln();
+        ps.printRightBracket();
+
+        ps.printPrefixln();
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::initialize()");
+        ps.printLeftBracket();
+        ps.printPrefixln("_process.init(&_process);");
+        ps.printRightBracket();
+        ps.printPrefixln();
+        ps.printPrefixln("int " + p.getBasename() + "_wrapper::fire()");
+        ps.printLeftBracket();
+        ps.printPrefixln();
+        ps.printPrefixln("return _process.fire(&_process);");
+        ps.printRightBracket();
+    }
+
+    protected void _createHeaderFile(Process p)
+        throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#ifndef " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln("#define " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"systemc.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"dol_sched_if.h\"");
+        ps.printPrefixln("#include \"simple_fifo.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include <dol.h>");
+        ps.printPrefixln();
+
+        /* begin of profiling: externally defined global variables */
+        ps.println();
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("extern FILE *profiler_output_file;");
+        ps.printPrefixln("extern unsigned int profiler_event_counter;");
+        ps.printPrefixln("#endif");
+        ps.printPrefixln();
+        /* end of profiling */
+
+        ps.printPrefixln("class " + p.getBasename() +
+                         "_wrapper : virtual public dol_sched_if, " +
+                         "public sc_module");
+        ps.printLeftBracket();
+        ps.printPrefixln("public:");
+
+
+        Vector<String> portList = new Vector<String>();
+        for (Port port : p.getPortList()) {
+            String basename = port.getBasename();
+
+            if (!portList.contains(basename)) {
+                portList.add(basename);
+
+                if (!port.getRange().equals("")) {
+                    if (port.isOutPort()) {
+                        ps.printPrefixln("sc_port<write_if> OUTPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];");
+                    }
+                    else if (port.isInPort()) {
+                        ps.printPrefixln("sc_port<read_if> INPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];");
+                    }
+                }
+                else {
+                    if (port.isOutPort()) {
+                        ps.printPrefixln("sc_port<write_if> OUTPORT_"
+                                + port.getName() + ";");
+                    }
+                    else if (port.isInPort()) {
+                        ps.printPrefixln("sc_port<read_if> INPORT_"
+                                + port.getName() + ";");
+                    }
+                }
+            }
+        }
+        ps.printPrefixln("int _processIndex[4];");
+
+        /* begin of profiling: name variable declaration */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("char _uniqueName[255];");
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln();
+        ps.printPrefixln("" + p.getBasename()
+                + "_wrapper(sc_module_name name);");
+        ps.printPrefixln();
+        ps.printPrefixln("~" + p.getBasename() + "_wrapper() {}");
+        ps.printPrefixln();
+
+        /* begin of profiling: addtoprofile member function */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("void addToProfile(const char *, void *, int);");
+        ps.printPrefixln("#endif");
+        ps.printPrefixln();
+        /* end of profiling */
+
+        ps.printPrefixln("// DOL scheduler interface");
+        ps.printPrefixln("void initialize();");
+        ps.printPrefixln("int fire();");
+        ps.printPrefixln("void setDetached();");
+        ps.printPrefixln("int isDetached();");
+        ps.printPrefixln();
+        ps.printPrefixln();
+        ps.printPrefixln("protected:");
+        ps.printPrefixln();
+        ps.printPrefixln("private:");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper( const "
+                + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper& operator = "
+                + "( const " + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("DOLProcess _process;");
+        ps.printPrefixln("int _detached;");
+        ps.printRightBracket();
+        ps.printPrefixln(";");
+        ps.printPrefixln("#endif");
+    }
+
+    protected String _dir = null;
+}