X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2FHdsdModuleArchVisitor.java;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2FHdsdModuleArchVisitor.java;h=4b896463aec07a24c535651b027c2fd160ea1682;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java b/dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java new file mode 100644 index 0000000..4b89646 --- /dev/null +++ b/dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java @@ -0,0 +1,491 @@ +package dol.visitor.hdsd; + +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.Vector; + +import dol.datamodel.architecture.Configuration; +import dol.datamodel.architecture.Processor; +import dol.datamodel.mapping.Mapping; +import dol.datamodel.pn.Channel; +import dol.datamodel.pn.Port; +import dol.datamodel.pn.Process; +import dol.datamodel.pn.Resource; +import dol.main.UserInterface; +import dol.util.CodePrintStream; +import dol.visitor.ArchiVisitor; + +/** + * Visitor that generates the main program for one distributed simulator. + */ +public class HdsdModuleArchVisitor extends ArchiVisitor { + + /** + * Constructor. + * @param map mapping of this code generation + * @param dir path of this file + */ + public HdsdModuleArchVisitor(Mapping map, String dir) { + _map = map; + _dir = dir; + _channels = new LinkedHashSet(); + _remInChannels = new LinkedHashSet(); + _remOutChannels = new LinkedHashSet(); + _locChannels = new LinkedHashSet(); + } + + /** + * + * @param x Processor that needs to be rendered + */ + public void visitComponent(Processor x) { + + // get channels for this processor + _getChannels(x); + + try { + String filename = _dir + "/" + "scd_" + + x.getName() + ".cpp"; + OutputStream file = new FileOutputStream(filename); + _mainPS = new CodePrintStream(file); + + _mainPS.printPrefixln("#include "); + _mainPS.printPrefixln("#include "); + + /* begin of profiling: standard i/o file handling routines */ + _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER"); + _mainPS.printPrefixln("#include "); + _mainPS.printPrefixln("#endif"); + /* end of profiling */ + + _mainPS.printPrefixln("#include \"dol_sched_if.h\""); + _mainPS.printPrefixln("#include \"simple_fifo.h\""); + _mainPS.printPrefixln("#include \"scd_logging.h\""); + _mainPS.printPrefixln("#include \"scd_simulator.h\""); + _mainPS.printPrefixln("#include \"scd_rem_fifo_in.h\""); + _mainPS.printPrefixln("#include \"scd_rem_fifo_out.h\""); + _mainPS.println(); + + // include process files + Iterator pIt = x.getProcessList().iterator(); + Vector pList = new Vector(); + while (pIt.hasNext()) { + Process p = pIt.next(); + String basename = p.getBasename(); + if (!pList.contains(basename)) { + _mainPS.printPrefixln("#include \"" + p.getBasename() + + "_wrapper.h\""); + pList.add(basename); + } + } + _mainPS.println(); + + // namespaces + _mainPS.printPrefixln("using namespace std;"); + _mainPS.printPrefixln("using sc_core::sc_module;"); + _mainPS.printPrefixln("using sc_core::sc_event;"); + _mainPS.printPrefixln("using sc_core::sc_prim_channel;"); + + + /* begin of profiling: global variables */ + _mainPS.println(); + _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER"); + _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME " + + "\"profile_" + x.getName() + ".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(); + pIt = x.getProcessList().iterator(); + while (pIt.hasNext()) { + Process p = pIt.next(); + _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 eventList;"); + _mainPS.printPrefixln("list::iterator iter;"); + _mainPS.println(); + + //declare channels + _mainPS.println(); + Iterator cIt; + cIt = _locChannels.iterator(); + while (cIt.hasNext()) + _mainPS.printPrefixln("fifo " + cIt.next() + "_ins;"); + cIt = _remInChannels.iterator(); + while (cIt.hasNext()) + _mainPS.printPrefixln("scd_rem_fifo_in " + cIt.next() + "_ins;"); + cIt = _remOutChannels.iterator(); + while (cIt.hasNext()) + _mainPS.printPrefixln("scd_rem_fifo_out " + cIt.next() + "_ins;"); + _mainPS.println(); + + // model constructor + _mainPS.printPrefixln("sc_application(sc_module_name name)"); + + // parameter of constructor (processes) + _mainPS.printPrefixln(": sc_module(name),"); + pIt = x.getProcessList().iterator(); + while (pIt.hasNext()) { + Process p = pIt.next(); + _mainPS.printPrefixln(p.getName() + "_ins(\"" + + p.getName() +"\"),"); + } + + // parameter of constructor (channels) + cIt = _channels.iterator(); + while (cIt.hasNext()) { + Channel c = _map.getPN().getChannel( cIt.next() ); + _mainPS.printPrefix(c.getName() + "_ins(\"" + + c.getName() +"\", " + + c.getSize()*c.getTokenSize() + + ")"); + if (cIt.hasNext()) + _mainPS.println(","); + else + _mainPS.println(); + } + _mainPS.printLeftBracket(); + + //construtor content + //build the network + cIt = _channels.iterator(); + while (cIt.hasNext()) + { + Channel c = _map.getPN().getChannel(cIt.next()); + c.accept( new HdsdModulePNVisitor(x, _mainPS) ); + } + _mainPS.println(); + + _mainPS.println(); + + _mainPS.printPrefixln("SC_THREAD(thread_init);"); + // init thread + _mainPS.printPrefixln("SC_THREAD(thread_sched);"); + + // declare concurrent non-terminating threads + pIt = x.getProcessList().iterator(); + while (pIt.hasNext()) { + _mainPS.printPrefixln("SC_THREAD(thread_" + + pIt.next().getName() + ");"); + } + _mainPS.printRightBracket(); + _mainPS.println(); + + //define scheduler thread + _mainPS.printPrefixln("void thread_init()"); + _mainPS.printLeftBracket(); + //init + pIt = x.getProcessList().iterator(); + while (pIt.hasNext()) { + Process p = pIt.next(); + _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 + pIt = x.getProcessList().iterator(); + while (pIt.hasNext()) + pIt.next().accept( new HdsdModulePNVisitor(x, _mainPS) ); + + /* 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(); + + cIt = _channels.iterator(); + while (cIt.hasNext()) { + String cName = cIt.next(); + Channel ch = _map.getPN().getChannel(cName); + Iterator poIt = ch.getPortList().iterator(); + String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize(); + String outputStringAppendix = ""; + while (poIt.hasNext()) { + Port p = poIt.next(); + Port peerPort = p.getPeerPort(); + Resource peerResource = p.getPeerResource(); + + if (p.isOutPort()) { + // channel.out == process.in + String portAddr = null; + if ( x.hasProcess(peerResource.getName()) ) + portAddr = "&(" + peerResource.getName() + + "_ins.INPORT_" + peerPort.getBasename() + + peerPort.getName().replace( + peerPort.getBasename(), "").replaceAll( + "_([0-9]+)", "[$1]") + ")"; + else + portAddr = "0x00000000"; + outputString += " i " + peerResource.getName() + " %p";// + p.getPeerPort().getName(); + outputStringAppendix += "," + portAddr; + } else { + String portAddr = null; + if ( x.hasProcess(peerResource.getName()) ) + portAddr = "&(" + peerResource.getName() + + "_ins.OUTPORT_" + peerPort.getBasename() + + peerPort.getName().replace( + peerPort.getBasename(), "").replaceAll( + "_([0-9]+)", "[$1]") + ")"; + else + portAddr = "0x00000000"; + outputString += " o " + peerResource.getName() + " %p";// + p.getPeerPort().getName(); + outputStringAppendix += "," + portAddr; + } + } + 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(); + + //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"); + _mainPS.printPrefixln(); + /* end of profiling */ + + /* begin distributed simulation */ + if (UserInterface.getInstance().getDebugFlag()) + _mainPS.printPrefixln("scd_set_loglevel(SCD_DEBUG);"); + else + _mainPS.printPrefixln("scd_set_loglevel(SCD_INFO);"); + // simulator && master/slaves + Configuration opt = x.getCfg("master"); + if (opt != null && opt.getValue().equals("true")) // master + { + // simulator constructor + _mainPS.printPrefixln("scd_simulator sim(\"" + + x.getName() + "\", \"" + + x.getCfg("address").getValue() + "\", " + + x.getCfg("port").getValue() + ", SCD_MASTER);"); + // register slaves + Iterator iter = _map.getProcessorList().iterator(); + while (iter.hasNext()) + { + Processor p = iter.next(); + opt = p.getCfg("master"); + if ( !(opt != null && opt.getValue().equals("true")) ) + { + _mainPS.printPrefixln("sim.get_cont_man()." + + "register_slave(\"" + p.getName() + + "\");"); + } + } + } // end master + else // slave + { + // simulator constructor + _mainPS.printPrefixln("scd_simulator sim(\"" + + x.getName() + "\", \"" + + x.getCfg("address").getValue() + "\", " + + x.getCfg("port").getValue() + ", SCD_SLAVE);"); + // find and set master + Iterator iter = _map.getProcessorList().iterator(); + while (iter.hasNext()) + { + Processor p = iter.next(); + opt = p.getCfg("master"); + if (opt != null && opt.getValue().equals("true")) + { + _mainPS.printPrefixln("sim.get_cont_man().set_master(\"" + + p.getCfg("address").getValue() + "\", " + + p.getCfg("port").getValue() + ");"); + break; + } + } + } // end slave + + // register channels + // remote out channels + cIt = _remOutChannels.iterator(); + while (cIt.hasNext()) + { + String cName = cIt.next(); + Channel c = _map.getPN().getChannel(cName); + Iterator poIt = c.getPortList().iterator(); + Processor p = null; + while (poIt.hasNext()) + { + Port po = poIt.next(); + if (po.isOutPort()) + { + Process pr = _map.getProcess( + po.getPeerResource().getName() ); + p = pr.getProcessor(); + } + } + _mainPS.printPrefixln("sim.get_chan_man()." + + "register_channel(\"" + cName + "\","); + _mainPS.printPrefixln(" my_app_mdl." + cName + + "_ins, \"" + p.getCfg("address").getValue() + "\", " + + p.getCfg("port").getValue() + ");"); + } + // remote in channels + cIt = _remInChannels.iterator(); + while (cIt.hasNext()) + { + String cName = cIt.next(); + _mainPS.printPrefixln("sim.get_chan_man().register_channel(" + + "\"" + cName + "\","); + _mainPS.printPrefixln(" my_app_mdl." + cName + "_ins);"); + } + + // init & start + _mainPS.printPrefixln("bool ret = sim.init();"); + _mainPS.printPrefixln("if (ret)"); + _mainPS.prefixInc(); + _mainPS.printPrefixln("ret = sim.start();"); + _mainPS.prefixDec(); + _mainPS.printPrefixln(); + /* end distributed simulation */ + + /* 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("if (ret)"); + _mainPS.prefixInc(); + _mainPS.printPrefixln("return 0;"); + _mainPS.prefixDec(); + _mainPS.printPrefixln("else"); + _mainPS.prefixInc(); + _mainPS.printPrefixln("return 1;"); + _mainPS.prefixDec(); + + _mainPS.printRightBracket(); + + } + catch (Exception e) { + System.out.println("HdsdModuleVisitor: exception occured: " + + e.getMessage()); + e.printStackTrace(); + } + } + + + /** + * Retrieves all channels that have an endpoint on the specified + * processor and fills them into the channel sets. + * @param x the processor to get the channels for + */ + private void _getChannels(Processor x) + { + Iterator iter = _map.getPN().getChannelList().iterator(); + + while (iter.hasNext()) + { + Channel c = iter.next(); + + boolean isIn = false; + boolean isOut = false; + + /* check if the in/out endpoint of this channel is on this + * processor + */ + Iterator poIt = c.getPortList().iterator(); + while (poIt.hasNext()) + { + Port p = poIt.next(); + if (x.hasProcess(p.getPeerResource().getName())) + { + if (p.isInPort()) // inPort of channel = outport + isOut = true; + if (p.isOutPort()) // outPort of channel = inport + isIn = true; + } + } + + // add name to channel lists + if (isIn && isOut) + { + _channels.add(c.getName()); + _locChannels.add(c.getName()); + } + else if (isIn && !isOut) + { + _channels.add(c.getName()); + _remInChannels.add(c.getName()); + } + else if (!isIn && isOut) + { + _channels.add(c.getName()); + _remOutChannels.add(c.getName()); + } + } + } // _getChannels() + + + protected CodePrintStream _mainPS = null; + protected String _dir = null; + protected Mapping _map = null; + + protected Set _channels = null; + protected Set _remInChannels = null; + protected Set _remOutChannels = null; + protected Set _locChannels = null; +}