@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 public Void caseAction(Action action) { // FIXME: Do not detect a pathological case for the moment, // extra clock cycles for (Port port : action.getOutputPattern().getPorts()) { int size = action.getOutputPattern().getNumTokensMap().get(port); if (size > 1) { Var newVar = newPortToVarMap.get(port); Var var = action.getOutputPattern().getPortToVarMap().get(port); EList<Use> uses = var.getUses(); while (!uses.isEmpty()) { uses.get(0).setVariable(newVar); } EList<Def> defs = var.getDefs(); while (!defs.isEmpty()) { defs.get(0).setVariable(newVar); } // Create the Block while for the repeat BlockWhile whileBlock = IrFactory.eINSTANCE.createBlockWhile(); whileBlock.setJoinBlock(IrFactory.eINSTANCE.createBlockBasic()); // Create the condition Type type = IrFactory.eINSTANCE.createTypeInt(32); Var index = IrFactory.eINSTANCE.createVar(type, "rp_Index_" + port.getName(), true, 0); action.getBody().getLocals().add(index); ExprVar condE0 = IrFactory.eINSTANCE.createExprVar(index); ExprInt condE1 = IrFactory.eINSTANCE.createExprInt(size); ExprBinary whileCond = IrFactory.eINSTANCE.createExprBinary( condE0, OpBinary.LT, condE1, IrFactory.eINSTANCE.createTypeBool()); whileBlock.setCondition(whileCond); // Create an if block with a pin Status as condition Var pinStatus = IrFactory.eINSTANCE.createVar( IrFactory.eINSTANCE.createTypeBool(), "portStatus_" + port.getName(), true, 0); action.getBody().getLocals().add(pinStatus); // Add portStatus to the first block of the while BlockBasic firstWhileBlock = IrFactory.eINSTANCE.createBlockBasic(); InstPortStatus portStatus = XronosIrUtil.createInstPortStatus(pinStatus, port); firstWhileBlock.add(portStatus); whileBlock.getBlocks().add(firstWhileBlock); BlockIf blockIf = IrFactory.eINSTANCE.createBlockIf(); blockIf.setJoinBlock(IrFactory.eINSTANCE.createBlockBasic()); ExprVar ifCond = IrFactory.eINSTANCE.createExprVar(pinStatus); blockIf.setCondition(ifCond); // ----------------------------------------------------------- // Then Block // Create While blockBasic BlockBasic thenBlock = IrFactory.eINSTANCE.createBlockBasic(); // Create a Load instruction Type tmpLoadType = IrUtil.copy(port.getType()); Var tmpLoad = IrFactory.eINSTANCE.createVar(tmpLoadType, "tmp_rp_" + port.getName(), true, 0); action.getBody().getLocals().add(tmpLoad); ExprVar loadIndex = IrFactory.eINSTANCE.createExprVar(index); InstLoad load = IrFactory.eINSTANCE.createInstLoad( tmpLoad, newVar, Arrays.asList((Expression) loadIndex)); thenBlock.add(load); // Create the Port Write instruction InstPortWrite portWrite = XronosIrUtil.createInstPortWrite(port, tmpLoad, false); thenBlock.add(portWrite); // Create the instruction assign with index++ ExprVar assignE0 = IrFactory.eINSTANCE.createExprVar(index); ExprInt assignE1 = IrFactory.eINSTANCE.createExprInt(1); ExprBinary assignValue = IrFactory.eINSTANCE.createExprBinary( assignE0, OpBinary.PLUS, assignE1, IrFactory.eINSTANCE.createTypeInt()); InstAssign assignIndex = IrFactory.eINSTANCE.createInstAssign(index, assignValue); thenBlock.add(assignIndex); // ----------------------------------------------------------- // Add to thenBlocks the thenBlock blockIf.getThenBlocks().add(thenBlock); // Add the ifBlock to the Block While whileBlock.getBlocks().add(blockIf); // Create a Block Basic with rp_Index_ to 0 BlockBasic initRpIndex = IrFactory.eINSTANCE.createBlockBasic(); InstAssign rpAssignZero = IrFactory.eINSTANCE.createInstAssign(index, 0); initRpIndex.add(rpAssignZero); // Add the BlockWhile to the body of the procedure int indexBlock = action.getBody().getBlocks().size(); Block lastBlock = action.getBody().getBlocks().get(indexBlock - 1); if (isSinlgeReturnBlock(lastBlock)) { action.getBody().getBlocks().add(indexBlock - 1, initRpIndex); action.getBody().getBlocks().add(indexBlock, whileBlock); } else { if (lastBlock.isBlockBasic()) { BlockBasic basic = (BlockBasic) lastBlock; int instrSize = basic.getInstructions().size(); if (basic.getInstructions().get(instrSize - 1).isInstReturn()) { Instruction returnInst = basic.getInstructions().get(instrSize - 1); BlockBasic newLastBlock = IrFactory.eINSTANCE.createBlockBasic(); newLastBlock.add(returnInst); action.getBody().getBlocks().add(initRpIndex); action.getBody().getBlocks().add(whileBlock); action.getBody().getBlocks().add(newLastBlock); } } } } } return null; }