X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fcell%2FCellModuleVisitor.java;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fcell%2FCellModuleVisitor.java;h=10c700ba69e658270b8bee32398390594a7a0d88;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/cell/CellModuleVisitor.java b/dol/src/dol/visitor/cell/CellModuleVisitor.java new file mode 100644 index 0000000..10c700b --- /dev/null +++ b/dol/src/dol/visitor/cell/CellModuleVisitor.java @@ -0,0 +1,386 @@ +package dol.visitor.cell; + +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Vector; + +import dol.datamodel.pn.Channel; +import dol.datamodel.pn.Port; +import dol.datamodel.pn.Process; +import dol.datamodel.pn.ProcessNetwork; +import dol.visitor.PNVisitor; +import dol.main.UserInterface; +import dol.util.CodePrintStream; + +/** + * This class is a class for a visitor that is used to generate the main + * program. + * + * @author lschor, 2008-10-30 + * + * Remarks: Based on a original file from khuang for rtems + * + * Revision: 2008-10-30: Updated the file for the CBE 2008-11-08: Add + * double buffering 2008-11-16: Add new fifo implementation and defines + * for measurement 2008-11-21: Sink/Source do not run on the SPE, but on + * the PPE (as Linux thread) 2009-03-17: Added Protothread Support + * 2009-04-07: Several modifications, so that one only writes if there + * is enough memory, do not allocate all queues on PPU + */ +public class CellModuleVisitor extends PNVisitor { + + /** + * Constructor. + * + * @param dir + * path of this file + */ + public CellModuleVisitor(String dir, HashMap portMap, + CellMapping mapping) { + _dir = dir; + _portMap = portMap; + _mapping = mapping; + } + + /** + * Visit process network. + * + * @param x + * process network that needs to be rendered + */ + public void visitComponent(ProcessNetwork x) { + try { + // Create in a first step the different SPU OS Layers + ArrayList> spuList = _mapping.getSPUList(); + Vector ppu = _mapping.getPPU(); + + // Create the main file for the PPU + _ui = UserInterface.getInstance(); + String filename = _dir + _delimiter + "ppu_main.cpp"; + OutputStream file = new FileOutputStream(filename); + _mainPS = new CodePrintStream(file); + + // create header section + _mainPS.println("// ========================"); + _mainPS.println("// ppu_main.cpp file"); + _mainPS.println("// ========================"); + _mainPS.println(""); + + // Includes + _mainPS.println("#include \"ppu_main.h\""); + _mainPS.println(""); + + // Function to create and run one SPE thread + _mainPS.println("// create and run one SPE thread"); + _mainPS.println("void *spu_pthread(void *arg) {"); + _mainPS.println(" spu_data_t *datp = (spu_data_t *)arg;"); + _mainPS.println(" uint32_t entry = SPE_DEFAULT_ENTRY;"); + _mainPS.println(" printf(\")PPE: spe thread start run\\n\" );"); + _mainPS.println(" if(spe_context_run(datp->spe_ctx,&entry,0,datp->argp,NULL,NULL)<0){"); + _mainPS.println(" perror (\"Failed running context\"); exit (1);"); + _mainPS.println(" }"); + _mainPS.println(" printf(\")PPE: spe thread finish run\\n\");"); + _mainPS.println(" pthread_exit(NULL);"); + _mainPS.println("}"); + _mainPS.println(""); + + // Declaration of the Header function for the PPE-Wrappers + /* + * for (Process p : ppu) { _mainPS.println("void *"+ p.getBasename() + * + "_wrapper( void *ptr );"); } + */ + _mainPS.println("void *ppu( void *ptr );"); + _mainPS.println(); + + // Create the port_id and the port_queue_id arrays to send over the + // DMA + for (Process process : _mapping.getAllSpuProcess()) { + String processName = process.getName(); + _mainPS.println("volatile char " + processName + + "_name[256] __attribute__ ((aligned(16)));"); + } + _mainPS.println(); + + // Go through all SPEs + for (Vector spu : spuList) { + _mainPS.println("volatile uint64_t spu_" + + spuList.indexOf(spu) + "[" + spu.size() + + "] __attribute__ ((aligned(16)));"); + } + _mainPS.println(); + _mainPS.println("// The input queue of a process is always on the SPU of the receiver, negative means that the queue is on the PPE"); + _mainPS.println("volatile int32_t queueOnSPU [NUM_FIFO] __attribute__ ((aligned(16)));"); + _mainPS.println(); + _mainPS.println(" // The queue comes from this SPU"); + _mainPS.println("volatile int32_t queueFromSPU [NUM_FIFO] __attribute__ ((aligned(16)));"); + _mainPS.println(); + _mainPS.println(" volatile uint64_t ea_ls_base[NUM_SPES] __attribute__ ((aligned(16)));"); + _mainPS.println("volatile uint64_t context_addr[NUM_SPES] __attribute__ ((aligned(16)));"); + _mainPS.println("volatile spe_spu_control_area_t* mfc_ctl[NUM_SPES] __attribute__ ((aligned(16)));"); + _mainPS.println("volatile uint64_t fifoTails[NUM_FIFO] __attribute__ ((aligned(16)));"); + _mainPS.println(); + + // Create the main function + _mainPS.println("int main()"); + _mainPS.println("{"); + + // List with all SPU to be open + _mainPS.println(" char spe_names[NUM_SPES][60] = {"); + for (Vector spu : spuList) { + _mainPS.println(" \"spu/spu_os_" + spuList.indexOf(spu) + + "\","); + } + _mainPS.println(" };"); + + _mainPS.println(); + + for (Channel c : x.getChannelList()) { + // Search for the origin spe + int origin = -1; + + for (Vector spu : spuList) { + + if (spu.contains(c.getOrigin())) { + origin = spuList.indexOf(spu); + break; + } + } + + // Origin on the PPU + if (origin == -1) { + origin = (-1) * (ppu.indexOf(c.getOrigin()) + 1); + } + + _mainPS.println(" queueFromSPU[" + + x.getChannelList().indexOf(c) + "] = " + origin + + ";"); + } + + _mainPS.println(); + + for (Channel c : x.getChannelList()) { + // Search for the origin spe + int origin = -1; + + for (Vector spu : spuList) { + if (spu.contains(c.getTarget())) { + origin = spuList.indexOf(spu); + break; + } + } + + // Origin on the PPU + if (origin == -1) { + origin = (-1) * (ppu.indexOf(c.getTarget()) + 1); + } + + _mainPS.println(" queueOnSPU[" + + x.getChannelList().indexOf(c) + "] = " + origin + + ";"); + } + + _mainPS.println(); + + // connect ports to channels + HashMap channel_map = new HashMap(); + + int j = 0; + for (Channel c : x.getChannelList()) { + channel_map.put(c, j++); + } + + // Add to each process the ports and the queues + _mainPS + .println(" //Add to each process the ports and the queues"); + j = 0; + + // SPU Process + for (Process process : _mapping.getAllSpuProcess()) { + String processName = process.getName(); + _mainPS.println(" ctx_proc[" + j + "]" + + ".is_detached = 0;"); + _mainPS.println(" strcpy((char *)" + processName + + "_name, " + "\"" + processName + "\");"); + _mainPS.println(" ctx_proc[" + j + "]" + + ".processName = (uint64_t) " + processName + + "_name;"); + _mainPS.println(" ctx_proc[" + j + "]" + + ".processNameLen = ((strlen((char *)" + + processName + "_name) + 15) & ~15);"); + _mainPS.println(); + j++; + } + + _mainPS.println(" // Mapping tasks -> What to map to which SPE?"); + _mainPS.println(" // Example: Square 0-2 to SPE 0 AND Square 3-5 to SPE 1"); + j = 0; + for (Process process : _mapping.getAllSpuProcess()) { + for (Vector spu : spuList) { + if (spu.contains(process)) { + _mainPS.println(" spu_" + spuList.indexOf(spu) + + "[" + spu.indexOf(process) + + "] = (uint64_t) &(ctx_proc[" + j + + "]);"); + j++; + break; + } + } + } + + for (Vector spu : spuList) { + _mainPS.println(" ctx_spu[" + spuList.indexOf(spu) + + "].procContents = (uint64_t) spu_" + + spuList.indexOf(spu) + ";"); + _mainPS.println(" ctx_spu[" + spuList.indexOf(spu) + + "].procContentsLen = " + spu.size() + ";"); + } + + _mainPS.println(); + + // Init the SPE control structure + _mainPS.println(" //Initiate SPEs control structure"); + _mainPS.println(" int num = 0; "); + _mainPS.println(" for( num=0; num variable store the executable name"); + _mainPS.println(" // - Load SPEs objects into SPE context local store"); + _mainPS.println(" for( num=0; numprocContentsAll = (uint64_t *) context_addr;"); + _mainPS.println(" ppu_Process_Wrapper->queueFromSPU = (int32_t *)queueFromSPU;"); + _mainPS.println(" ppu_Process_Wrapper->queueOnSPU = (int32_t *)queueOnSPU;"); + _mainPS.println(" ppu_Process_Wrapper->ea_ls_base = (uint64_t *)ea_ls_base;"); + _mainPS.println(" ppu_Process_Wrapper->fifoTails = (uint64_t *) fifoTails;"); + _mainPS.println(" "); + + _mainPS.println(" // create SPE pthreads"); + _mainPS.println(" for( num=0; num 16) + return number + 16 - (number % 16); + else if (number > 8) + return 16; + else if (number > 4) + return 8; + else if (number > 2) + return 4; + else if (number > 1) + return 2; + else + return 1; + } + + protected CodePrintStream _mainPS = null; + protected String _dir = null; + protected HashMap _portMap; + protected CellMapping _mapping; + +}