예제 #1
0
  @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;
  }
예제 #2
0
  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;
  }
예제 #3
0
  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);
  }
예제 #4
0
  @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;
  }