public Void caseProcedure(Procedure proc) { for (Param param : new ArrayList<Param>(proc.getParameters())) { if (param.getVariable().getType().isString()) { IrUtil.delete(param); } } for (Var var : new ArrayList<Var>(proc.getLocals())) { if (var.getType().isString()) { IrUtil.delete(var); } } return super.caseProcedure(proc); }
@Override public Block caseActor(Actor actor) { BlockBasic block = IrFactory.eINSTANCE.createBlockBasic(); List<Port> ports = new ArrayList<Port>(); // Get inputs and output port of the actor ports.addAll(actor.getInputs()); ports.addAll(actor.getOutputs()); for (Port port : ports) { // -- Create status Variable and add it as local to the scheduler Var status = IrFactory.eINSTANCE.createVar( IrFactory.eINSTANCE.createTypeBool(), port.getName() + "Status", true, 0); scheduler.addLocal(status); Def def = IrFactory.eINSTANCE.createDef(status); // -- Create InstPortStatus InstPortStatus portStatus = XronosIrFactory.eINSTANCE.createInstPortStatus(); portStatus.setPort(port); portStatus.setTarget(def); // -- Add InstPortStatus to block block.add(portStatus); } return block; }
@Override public Boolean caseProcedure(Procedure procedure) { this.procedure = procedure; // Test if The procedure contains a BlockWhile before size - 1 int blockSize = procedure.getBlocks().size(); if (blockSize > 1) { Block block = procedure.getBlocks().get(blockSize - 2); if (block.isBlockWhile()) { // If it is check if an additional loop should be added doSwitch(block); } else { return true; } } return false; }
protected void createBroadcast(String id, Port port, List<? extends Edge> outList) { // Add broadcast vertex Actor bcast = dfFactory.createActor(); bcast.setName(id + "_" + port.getName()); Instance instance = dfFactory.createInstance(id + "_" + port.getName() + "_bcast", bcast); network.add(instance); Type portVarType = irFactory.createTypeList(1, port.getType()); Pattern inputPattern = dfFactory.createPattern(); Pattern outputPattern = dfFactory.createPattern(); Port input = dfFactory.createPort(EcoreUtil.copy(port.getType()), "input"); bcast.getInputs().add(input); // Creates a connection between the vertex and the broadcast Connection conn = (Connection) outList.get(0); Connection incoming = dfFactory.createConnection( conn.getSource(), conn.getSourcePort(), instance, input, EcoreUtil.copyAll(conn.getAttributes())); incoming.getAttributes().addAll(EcoreUtil.copyAll(conn.getAttributes())); network.getConnections().add(incoming); inputPattern.setNumTokens(input, 1); inputPattern.setVariable(input, irFactory.createVar(portVarType, "input", true, 0)); // Change the source of the other connections int i = 0; for (Edge edge : outList) { Port output = dfFactory.createPort(EcoreUtil.copy(port.getType()), "output_" + i); bcast.getOutputs().add(output); Connection connection = (Connection) edge; connection.setSourcePort(output); connection.setSource(instance); outputPattern.setNumTokens(output, 1); outputPattern.setVariable(output, irFactory.createVar(portVarType, "output_" + i, true, 0)); i++; } // Create body of the broadcast Procedure body = irFactory.createProcedure("copy", 0, irFactory.createTypeVoid()); Var tmpVar = body.newTempLocalVariable(IrUtil.copy(port.getType()), "tmp"); BlockBasic block = IrUtil.getLast(body.getBlocks()); block.add(irFactory.createInstLoad(tmpVar, inputPattern.getVariable(input), 0)); for (Port output : bcast.getOutputs()) { block.add(irFactory.createInstStore(outputPattern.getVariable(output), 0, tmpVar)); } // Create the scheduler Procedure scheduler = irFactory.createProcedure("isSchedulable_copy", 0, irFactory.createTypeBool()); BlockBasic block2 = IrUtil.getLast(scheduler.getBlocks()); block2.add(irFactory.createInstReturn(irFactory.createExprBool(true))); Action copy = dfFactory.createAction( "copy", inputPattern, outputPattern, dfFactory.createPattern(), scheduler, body); bcast.getActions().add(copy); bcast.getActionsOutsideFsm().add(copy); }
@SuppressWarnings("unchecked") @Override public Loop caseBlockWhile(BlockWhile blockWhile) { // Initialize members Map<Var, Port> inputs = new HashMap<Var, Port>(); Map<Var, Bus> outputs = new HashMap<Var, Bus>(); Map<Bus, Var> feedbackBusVar = new HashMap<Bus, Var>(); Map<Bus, Var> completeBusVar = new HashMap<Bus, Var>(); // -- Decision // Construct decision from the block while condition Block decisionBlock = null; Component valueComponent = new ExprToComponent().doSwitch(blockWhile.getCondition()); Map<Var, Port> dBlockDataPorts = null; if (!(valueComponent instanceof Block)) { dBlockDataPorts = new HashMap<Var, Port>(); Map<Var, Port> valueDataPorts = (Map<Var, Port>) blockWhile.getCondition().getAttribute("inputs").getObjectValue(); decisionBlock = new Block(Arrays.asList(valueComponent)); // Propagate DataPorts ComponentUtil.propagateDataPorts(decisionBlock, dBlockDataPorts, valueDataPorts); // Propagate DataBuses for (Bus dataBus : valueComponent.getExit(Exit.DONE).getDataBuses()) { Bus blockDataBus = decisionBlock.getExit(Exit.DONE).makeDataBus(); Port blockDataBuspeer = blockDataBus.getPeer(); ComponentUtil.connectDataDependency(dataBus, blockDataBuspeer, 0); } } else { decisionBlock = (Block) valueComponent; dBlockDataPorts = (Map<Var, Port>) blockWhile.getCondition().getAttribute("inputs").getObjectValue(); } Component decisionComponent = ComponentUtil.decisionFindConditionComponent(decisionBlock); // Create decision Decision decision = new Decision(decisionBlock, decisionComponent); Debug.depGraphTo(decision, "deicions", "/tmp/decision1.dot", 1); // Propagate decisionBlockInputs to the decision one Map<Var, Port> dDataPorts = new HashMap<Var, Port>(); ComponentUtil.propagateDataPorts(decision, dDataPorts, dBlockDataPorts); // -- Loop Body // Construct Loop Body Block from the block while blocks Map<Var, Port> blockDataPorts = new HashMap<Var, Port>(); Map<Var, Bus> blockDataBuses = new HashMap<Var, Bus>(); Module body = (Module) new BlocksToBlock(blockDataPorts, blockDataBuses, false) .doSwitch(blockWhile.getBlocks()); // Loop body (While Body) inputs and outputs Map<Var, Port> lbDataPorts = new HashMap<Var, Port>(); LoopBody loopBody = new WhileBody(decision, body); Debug.depGraphTo(loopBody, "loopBody", "/tmp/loopBody.dot", 1); // Propagate decision and body inputs to the loopBody // -- Propagate Decision data ports ComponentUtil.propagateDataPorts(loopBody, lbDataPorts, dDataPorts); // -- Propagate Body Blocks data ports ComponentUtil.propagateDataPorts(loopBody, lbDataPorts, blockDataPorts); // -- Complete Exit for (Var var : blockDataBuses.keySet()) { Type type = var.getType(); Bus bus = blockDataBuses.get(var); // -- Make an complete exit data bus Bus cBus = loopBody .getLoopCompleteExit() .makeDataBus(var.getName() + "_fb", type.getSizeInBits(), type.isInt()); // -- Connect Port cBusPeer = cBus.getPeer(); ComponentUtil.connectDataDependency(bus, cBusPeer); // -- Save it to the feedbackBusVar completeBusVar.put(cBus, var); } // -- FeedBack Exit for (Var var : blockDataBuses.keySet()) { Type type = var.getType(); // -- If the input does not exist create one because this is a // feedback if (!lbDataPorts.containsKey(var)) { Port lbPort = loopBody.makeDataPort(var.getName() + "_fb", type.getSizeInBits(), type.isInt()); lbDataPorts.put(var, lbPort); } Bus bus = blockDataBuses.get(var); // -- Make an feedback exit data bus Bus fbBus = loopBody .getFeedbackExit() .makeDataBus(var.getName() + "_fb", type.getSizeInBits(), type.isInt()); // -- Connect Port fbBusPeer = fbBus.getPeer(); ComponentUtil.connectDataDependency(bus, fbBusPeer); // -- Save it to the feedbackBusVar feedbackBusVar.put(fbBus, var); } // -- From input to Complete Exit dependency for (Bus bus : completeBusVar.keySet()) { Var var = completeBusVar.get(bus); Port port = lbDataPorts.get(var); // -- Connect it Port busPeer = bus.getPeer(); Bus portpeer = port.getPeer(); ComponentUtil.connectDataDependency(portpeer, busPeer); } // Create Loop Loop loop = new Loop(loopBody); // -- Loop inputs comes from decision and body Set<Var> inVars = new HashSet<Var>(); inVars.addAll(dDataPorts.keySet()); inVars.addAll(lbDataPorts.keySet()); for (Var var : inVars) { Type type = var.getType(); Port dataPort = loop.makeDataPort(var.getName(), type.getSizeInBits(), type.isInt()); inputs.put(var, dataPort); } // -- Init Dependencies Entry initEntry = loop.getBodyInitEntry(); for (Var var : inputs.keySet()) { if (feedbackBusVar.containsValue(var)) { Port lPort = inputs.get(var); Port lbPort = lbDataPorts.get(var); Bus lPortPeer = lPort.getPeer(); Dependency dep = (lbPort == lbPort.getOwner().getGoPort()) ? new ControlDependency(lPortPeer) : new DataDependency(lPortPeer); initEntry.addDependency(lbPort, dep); } } // -- Feedback Dependencies Entry fbEntry = loop.getBodyFeedbackEntry(); for (Bus bus : feedbackBusVar.keySet()) { Var var = feedbackBusVar.get(bus); Exit lfbExit = loop.getBody().getFeedbackExit(); Port lbPort = lbDataPorts.get(var); // -- Create a feedback register Reg fbReg = loop.createDataRegister(); fbReg.setIDLogical("fbReg_" + var.getName()); // fbReg.getDataPort().setIDLogical(var.getName()); // fbReg.getResultBus().setIDLogical(var.getName()); // -- Dependencies Entry entry = fbReg.makeEntry(lfbExit); entry.addDependency(fbReg.getDataPort(), new DataDependency(bus)); fbEntry.addDependency(lbPort, new DataDependency(fbReg.getResultBus())); } // -- Latch Dependencies Collection<Dependency> goInitDeps = initEntry.getDependencies(loop.getBody().getGoPort()); Bus initDoneBus = goInitDeps.iterator().next().getLogicalBus(); for (Var var : inVars) { if (!feedbackBusVar.containsValue(var)) { Port lPort = inputs.get(var); Bus lPortPeer = lPort.getPeer(); // -- Create a latch Latch latch = loop.createDataLatch(); latch.setIDLogical("latched_" + var.getName()); // -- Dependencies Entry latchEntry = latch.makeEntry(initDoneBus.getOwner()); latch.getDataPort().setIDLogical(var.getName()); // -- Control dependency latchEntry.addDependency(latch.getEnablePort(), new ControlDependency(initDoneBus)); // -- Data dependency in latch latchEntry.addDependency(latch.getDataPort(), new DataDependency(lPortPeer)); // -- Data dependency out latch Bus latchResultBus = latch.getResultBus(); latchResultBus.setIDLogical(var.getName() + "_result"); Port lbPort = lbDataPorts.get(var); fbEntry.addDependency(lbPort, new DataDependency(latchResultBus)); } } // -- Done Dependencies Entry outbufEntry = loop.getExit(Exit.DONE).getPeer().getEntries().get(0); for (Bus bus : loopBody.getLoopCompleteExit().getDataBuses()) { Var var = completeBusVar.get(bus); Type type = var.getType(); Bus dataBus = loop.getExit(Exit.DONE).makeDataBus(var.getName(), type.getSizeInBits(), type.isInt()); Port dataBusPeer = dataBus.getPeer(); Dependency dep = new DataDependency(bus); outbufEntry.addDependency(dataBusPeer, dep); outputs.put(var, dataBus); } // -- Set control dependency Port lbDonePort = loopBody.getLoopCompleteExit().getDoneBus().getPeer(); Bus lDoneBus = loop.getExit(Exit.DONE).getDoneBus(); Dependency dep = new ControlDependency(lDoneBus); outbufEntry.addDependency(lbDonePort, dep); // -- IDSourceInfo Procedure procedure = EcoreHelper.getContainerOfType(blockWhile, Procedure.class); IDSourceInfo sinfo = new IDSourceInfo(procedure.getName(), blockWhile.getLineNumber()); loop.setIDSourceInfo(sinfo); Debug.depGraphTo(loop, "loopBody", "/tmp/loop_new.dot", 1); // -- Set attributes blockWhile.setAttribute("inputs", inputs); blockWhile.setAttribute("outputs", outputs); return loop; }