X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2FsystemC%2FProcessVisitor.java;fp=dol%2Fsrc%2Fdol%2Fvisitor%2FsystemC%2FProcessVisitor.java;h=f87545beaf058209b5fa5ae42d144adaa84819e0;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/systemC/ProcessVisitor.java b/dol/src/dol/visitor/systemC/ProcessVisitor.java new file mode 100644 index 0000000..f87545b --- /dev/null +++ b/dol/src/dol/visitor/systemC/ProcessVisitor.java @@ -0,0 +1,351 @@ +/* $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 pList = new Vector(); + + 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 "); + 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 OUTPORT_" + + pr.getName() + ";"); + } + else if (pr.isInPort()) { + ps.printPrefixln("sc_port 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; +}