@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; }
private boolean isSinlgeReturnBlock(Block block) { if (block.isBlockBasic()) { BlockBasic basic = (BlockBasic) block; if (basic.getInstructions().size() == 1) { Instruction instruction = basic.getInstructions().get(0); if (instruction.isInstReturn()) { 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); }
@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; }