dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hds / HdsModuleVisitor.java
diff --git a/dol/src/dol/visitor/hds/HdsModuleVisitor.java b/dol/src/dol/visitor/hds/HdsModuleVisitor.java
new file mode 100644 (file)
index 0000000..f00bbe3
--- /dev/null
@@ -0,0 +1,347 @@
+/* $Id: HdsModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.hds;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class HdsModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public HdsModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            _mainPS.printPrefixln("#include <systemc>");
+            _mainPS.printPrefixln("#include <list>");
+
+            /* begin of profiling: standard i/o file handling routines */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#include <stdio.h>");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
+            _mainPS.println();
+
+            for (String basename : x.getProcessBasenames()) {
+                _mainPS.printPrefixln("#include \"" + basename
+                        + "_wrapper.h\"");
+            }
+            _mainPS.println();
+            _mainPS.printPrefixln("using namespace std;");
+
+            /* begin of profiling: global variables */
+            _mainPS.println();
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME \"profile.txt\"");
+            _mainPS.printPrefixln("FILE *profiler_output_file;");
+            _mainPS.printPrefixln("unsigned int profiler_event_counter;");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.println();
+            _mainPS.printPrefixln("class sc_application : public sc_module ");
+            _mainPS.printLeftBracket();
+
+            _mainPS.printPrefixln("public:");
+            _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
+
+            //declare processes
+            _mainPS.println();
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getBasename() + "_wrapper "
+                        + p.getName() + "_ins"+ ";");
+                _mainPS.printPrefixln("sc_event " + p.getName()
+                        + "_event;");
+            }
+            _mainPS.println();
+
+            //define the scheduler
+            _mainPS.printPrefixln("sc_event sched_event;");
+            _mainPS.printPrefixln("list<sc_event* > eventList;");
+            _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
+            _mainPS.println();
+
+            //declare channels
+            _mainPS.println();
+            for (Channel p : x.getChannelList()) {
+                if (p.getType().equals("fifo")) { 
+                    _mainPS.printPrefixln("Fifo " + p.getName() + "_ins;");
+                } else if (p.getType().equals("wfifo")) {
+                    _mainPS.printPrefixln("WindowedFifo " + p.getName() + "_ins;");
+                }
+            }
+            _mainPS.println();
+
+            //model constructor
+            _mainPS.printPrefixln("sc_application(sc_module_name name)");
+
+            //parameter of constructor
+            _mainPS.printPrefix(":       sc_module(name)");
+            for (Process p : x.getProcessList()) {
+                _mainPS.println(",");
+                _mainPS.printPrefix(p.getName() + "_ins(\""
+                        + p.getName() +"\")");
+            }
+
+            if (x.getChannelList().size() > 0) {
+                for (Channel c : x.getChannelList()) {
+                    _mainPS.println(",");
+                    _mainPS.printPrefix(c.getName() + "_ins("
+                                        + "\"" + c.getName() + "\", "
+                                        + c.getSize() * c.getTokenSize()
+                                        + ")");
+                }
+            }
+            _mainPS.println("");
+            _mainPS.printLeftBracket();
+
+            //construtor content
+            //build the network
+            for (Channel ch : x.getChannelList()) {
+                ch.accept(this);
+            }
+            _mainPS.println("");
+
+            _mainPS.println("");
+
+            _mainPS.printPrefixln("SC_THREAD(thread_init);");
+            //init thread
+            _mainPS.printPrefixln("SC_THREAD(thread_sched);");
+
+            //declare concurrent non-terminating threads
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln("SC_THREAD(thread_" +
+                                      p.getName() + ");");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define scheduler thread
+            _mainPS.printPrefixln("void thread_init()");
+            _mainPS.printLeftBracket();
+            //init
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+
+            //different scheduling algorithm can be put here
+            _mainPS.printPrefixln("void thread_sched()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("while (1)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
+                    + "eventList.end(); ++iter)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_event* e = (*iter);");
+            _mainPS.printPrefixln("e->notify();");
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("eventList.clear();");
+            _mainPS.printPrefixln("wait(sched_event);");
+            _mainPS.printRightBracket();
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define threads
+            for (Process p : x.getProcessList()) {
+                p.accept(this);
+            }
+
+            /* begin of profiling: initialization function. */
+            /* - opens file */
+            /* - writes a list of all channels with the connected ports to the file. */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("void initialize_profiler()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("if ((profiler_output_file = fopen(PROFILER_OUTPUT_FILENAME,\"w\"))==NULL)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("printf(\"Unable to open profiler output file. No profiling output is written.\\n\");");
+            _mainPS.printPrefixln("return;");
+            _mainPS.printRightBracket();
+            //_mainPS.printPrefixln("printf(\"Profiling data is written to %s.\\n\", PROFILER_OUTPUT_FILENAME);");
+            _mainPS.println();
+
+            for (Channel ch : x.getChannelList()) {
+                String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize();
+                String outputStringAppendix = "";
+                for (Port p : ch.getPortList()) {
+                    Port peerPort = (Port)(p.getPeerPort());
+                    Resource peerResource = p.getPeerResource();
+
+                    if (p.isOutPort()) {
+                        // channel.out == process.in
+                        outputString += " i " + peerResource.getName() + " %pI";
+                        outputStringAppendix += ",(" + peerResource.getName()
+                            + "_ins.INPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), "") + ")";
+                    } else {
+                        outputString += " o " + peerResource.getName() + " %pO";
+                        outputStringAppendix += ",(" + peerResource.getName()
+                            + "_ins.OUTPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), "") + ")";
+                    }
+                }
+                outputString += "\\n\"" + outputStringAppendix + ");";
+                _mainPS.printPrefixln(outputString);
+            }
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("#endif");
+            _mainPS.println();
+            /* end of profiling */
+
+            _mainPS.printRightBracket(); // end of class
+            _mainPS.println(";");
+
+            //create and run the simulator
+            _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_report_handler::set_actions(\""
+                    + "/IEEE_Std_1666/deprecated\", SC_DO_NOTHING);");
+            _mainPS.printPrefixln("sc_report::register_id("
+                    + "5000, "
+                    + "\"parameter problem\" );");
+
+            //create an instance of the application model
+            //remove potential whitespaces before using the process
+            //network name as a systemc identifier
+            _mainPS.printPrefixln("sc_application my_app_mdl(\""
+                    + x.getName().replaceAll(" ", "")  + "\");");
+
+            /* begin of profiling: initialize the profiler */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("my_app_mdl.initialize_profiler();");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("sc_start(-1,SC_NS);");
+            /* begin of profiling: close the output file */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("if (profiler_output_file != NULL) fclose(profiler_output_file);");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("return 0;");
+
+            _mainPS.printRightBracket();
+
+        }
+        catch (Exception e) {
+            System.out.println("HdsModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Print a line for the process in the correct format for DOTTY.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        _mainPS.printPrefixln("void thread_" + x.getName() + "()");
+        _mainPS.printLeftBracket();
+        _mainPS.printPrefixln("while (!" + x.getName()
+                + "_ins.isDetached())");
+        _mainPS.printLeftBracket();
+
+        /* begin of profiling: start event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " started.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln(x.getName() + "_ins.fire();");
+
+        /* begin of profiling: stop event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " stopped.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln("eventList.push_back(&" + x.getName()
+                              + "_event);");
+        _mainPS.printPrefixln("sched_event.notify();");
+        _mainPS.printPrefixln("wait(" + x.getName() + "_event);");
+
+        _mainPS.printRightBracket();
+        _mainPS.printRightBracket();
+    }
+
+    /**
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        for (Port p : x.getPortList()) {
+            Port peerPort = (Port)(p.getPeerPort());
+            Resource peerResource = p.getPeerResource();
+            if (peerPort.getRange() != null) {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.INPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), ""));
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.OUTPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), ""));
+                }
+            }
+            else {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.INPORT_" + peerPort.getName());
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.OUTPORT_" + peerPort.getName());
+                }
+            }
+            _mainPS.println(" = &" + x.getName() + "_ins;");
+        }
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+}