@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; }
@Override protected void traverse(Block block) { block.getInBuf().accept(this); traverse(block.getSequence()); traverse(block.getOutBufs()); }