+/* $Id: ProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.systemC;
+
+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;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a SystemC wrapper for a process: process_wrapper.[h/cpp].
+ */
+public class ProcessVisitor extends PNVisitor {
+
+ /**
+ * Constructor.
+ *
+ * @param dir target directory
+ */
+ public ProcessVisitor(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 _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();
+
+ if (p.hasOutPorts()) {
+ //DOL_write()
+ ps.printPrefixln("static inline int DOL_write(void *port, "
+ + "void *buf, int len, DOLProcess *process)");
+ ps.printLeftBracket();
+ ps.printPrefixln("char *str = (char *)buf;");
+ ps.printPrefixln("while (len-- > 0) ");
+ ps.printLeftBracket();
+
+ int j = 0;
+ for (Port ip : p.getPortList()) {
+ if (ip.isOutPort()) {
+ String s = (j++ == 0) ? "if " : " else if ";
+ ps.printPrefixln(s + "(strstr(\" OUTPORT_"
+ + ip.getName() + "\", (const char*)port)) ");
+ ps.printLeftBracket();
+ ps.printPrefixln("(static_cast<" + p.getBasename()
+ + "_wrapper *>(process->wptr))->OUTPORT_"
+ + ip.getName() + "->write(*(str++));");
+ ps.printRightBracket();
+ }
+ }
+ ps.printRightBracket();
+ ps.printRightBracket();
+
+ //DOL_wtest()
+ ps.printPrefixln("static inline int DOL_wtest(void *port, "
+ + "int len, DOLProcess *process)");
+ ps.printLeftBracket();
+ j = 0;
+ for (Port ip : p.getPortList()) {
+ if (ip.isOutPort()) {
+ String s = (j++ == 0) ? "if " : "else if ";
+ ps.printPrefixln(s + "(strstr(\" OUTPORT_"
+ + ip.getName() + "\", (const char*)port)) ");
+ ps.printLeftBracket();
+ ps.printPrefixln("return (static_cast<" + p.getBasename()
+ + "_wrapper *>(process->wptr))->OUTPORT_"
+ + ip.getName() + "->wtest(len);");
+ ps.printRightBracket();
+ }
+ }
+ ps.printRightBracket();
+ }
+
+ ps.printPrefixln();
+ if (p.hasInPorts()) {
+ //DOL_read()
+ ps.printPrefixln("static inline int DOL_read(void *port, "
+ + "void *buf, int len, DOLProcess *process)");
+ ps.printLeftBracket();
+ ps.printPrefixln("char *str = (char *)buf;");
+ ps.printPrefixln("while (len-- > 0)");
+ ps.printLeftBracket();
+
+ int j = 0;
+ for (Port ip : p.getPortList()) {
+ if (ip.isInPort()) {
+ String s = (j++ == 0) ? "if " : "else if ";
+ ps.printPrefixln(s + "(strstr(\" INPORT_"
+ + ip.getName() + "\", (const char*)port))");
+ ps.printLeftBracket();
+ ps.printPrefixln("(static_cast<" + p.getBasename()
+ + "_wrapper *>(process->wptr))->INPORT_"
+ + ip.getName() + "->read(*(str++));");
+ ps.printRightBracket();
+ }
+ }
+ ps.printRightBracket();
+ ps.printRightBracket();
+
+ //DOL_rtest()
+ ps.printPrefixln("static inline int DOL_rtest(void *port, "
+ + "int len, DOLProcess *process)");
+ ps.printLeftBracket();
+ j = 0;
+ for (Port ip : p.getPortList()) {
+ if (ip.isInPort()) {
+ String s = (j++ == 0) ? "if " : " else if ";
+ ps.printPrefixln(s + "(strstr(\" INPORT_"
+ + ip.getName() + "\", (const char*)port))");
+ ps.printLeftBracket();
+ ps.printPrefixln("return (static_cast<" + p.getBasename()
+ + "_wrapper *>(process->wptr))->INPORT_"
+ + ip.getName() + "->rtest(len);");
+ ps.printRightBracket();
+ }
+ }
+ 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();
+
+
+ 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("_state = (LocalState)new "
+ + p.getBasename().substring(0, 1).toUpperCase()
+ + p.getBasename().substring(1) + "_State;");
+ //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.init = " + p.getBasename() + "_init;");
+ ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
+ ps.printPrefixln("_process.wptr = this;");
+ ps.printPrefixln();
+ ps.printPrefixln("char buffer[255];");
+ ps.printPrefixln("sprintf(buffer, name);");
+ 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("return _process.fire(&_process);");
+ ps.printRightBracket();
+ ps.printPrefixln();
+ ps.printPrefixln(p.getBasename() + "_wrapper::~" + p.getBasename()
+ + "_wrapper()");
+ ps.printLeftBracket();
+ ps.printPrefixln("if (_state)");
+ ps.printLeftBracket();
+ ps.printPrefixln("delete ("
+ + p.getBasename().substring(0, 1).toUpperCase()
+ + p.getBasename().substring(1) + "_State*)_state;");
+ ps.printRightBracket();
+ 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 \"dol_fifo_if.h\"");
+ ps.printPrefixln("#include \"simple_fifo.h\"");
+ ps.printPrefixln();
+ ps.printPrefixln("#include <dol.h>");
+ ps.printPrefixln();
+ ps.printPrefixln("class " + p.getBasename() +
+ "_wrapper : virtual public dol_sched_if, " +
+ "public sc_module");
+ ps.printLeftBracket();
+ ps.printPrefixln("public:");
+
+ for (Port pr : p.getPortList()) {
+ if (pr.isOutPort()) {
+ ps.printPrefixln("sc_port<write_if> OUTPORT_" +
+ pr.getName() + ";");
+ }
+ else if (pr.isInPort()) {
+ ps.printPrefixln("sc_port<read_if> INPORT_" +
+ pr.getName() + ";");
+ }
+ }
+ ps.printPrefixln("int _processIndex[4];");
+
+ ps.printPrefixln();
+ ps.printPrefixln("" + p.getBasename()
+ + "_wrapper(sc_module_name name);");
+ ps.printPrefixln();
+ ps.printPrefixln("virtual ~" + p.getBasename() + "_wrapper();");
+ ps.printPrefixln();
+ 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("LocalState _state;");
+
+ 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");
+ }
+
+ /**
+ * Make modifications to source files of a process.
+ * Port names need to be strings for the SystemC code generation.
+ * Therefore, in the header files integer port names are put into
+ * quotation marks.
+ *
+ * @param p process whose sources should be adapted
+ * @throws IOException
+ */
+ 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");
+
+ sed.sed(processHeaderFile,
+ "(#define[ ]*PORT_\\w*[ ]*)\"?"
+ + port.getBasename() + "\"?[ ]*$",
+ "$1 " + "\"" + port.getBasename() + "\"");
+ }
+ }
+ }
+
+
+ protected String _dir = null;
+}