| /******************************************************************************* |
| * Copyright (c) 2018 CEA LIST. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr |
| * - Initial API and Implementation |
| *******************************************************************************/ |
| package org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.helper; |
| |
| import org.eclipse.efm.ecore.formalml.common.VisibilityKind; |
| import org.eclipse.efm.ecore.formalml.datatype.DataType; |
| import org.eclipse.efm.ecore.formalml.datatype.EnumerationLiteral; |
| import org.eclipse.efm.ecore.formalml.datatype.EnumerationType; |
| import org.eclipse.efm.ecore.formalml.expression.Expression; |
| import org.eclipse.efm.ecore.formalml.infrastructure.ChannelDirection; |
| import org.eclipse.efm.ecore.formalml.infrastructure.Machine; |
| import org.eclipse.efm.ecore.formalml.infrastructure.Port; |
| import org.eclipse.efm.ecore.formalml.infrastructure.Variable; |
| import org.eclipse.efm.ecore.formalml.statement.BlockStatement; |
| import org.eclipse.efm.ecore.formalml.statement.IfStatement; |
| import org.eclipse.efm.formalml.ecore.factory.XLIA_DATATYPE; |
| import org.eclipse.efm.formalml.ecore.factory.XLIA_EXPRESSION; |
| import org.eclipse.efm.formalml.ecore.factory.XLIA_INFRA; |
| import org.eclipse.efm.formalml.ecore.factory.XLIA_STATEMENT; |
| import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast.MoccChannel; |
| import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast.MoccPort; |
| |
| public class MoccPortHelper { |
| |
| protected final MoccActorHelper moccActorHelper; |
| |
| protected final MoccPort moccPort; |
| |
| |
| public Port xliaPort; |
| public Port xliaChannelPort; |
| |
| public Variable constTOKEN_INITIAL_RATE; |
| public Variable varReceivedTokenCount; |
| |
| public Variable constMODE_INITIAL; |
| public Variable varReceivedMode; |
| |
| public Variable constTOKEN_RATE; |
| |
| public Variable constTOKEN_RATE_CSDF; |
| |
| public MoccPortHelper(final MoccActorHelper moccActorHelper, final MoccPort moccPort) { |
| super(); |
| |
| this.moccActorHelper = moccActorHelper; |
| this.moccPort = moccPort; |
| |
| this.xliaPort = null; |
| this.xliaChannelPort = null; |
| |
| this.constTOKEN_INITIAL_RATE = null; |
| this.varReceivedTokenCount = null; |
| |
| this.constMODE_INITIAL = null; |
| this.varReceivedMode = null; |
| |
| this.constTOKEN_RATE = null; |
| |
| this.constTOKEN_RATE_CSDF = null; |
| } |
| |
| |
| /** |
| * Getter initial rate |
| * @param moccPort |
| * @return |
| */ |
| public Expression initialRateExpression() { |
| return ((constTOKEN_INITIAL_RATE == null)) |
| // || moccPort.hasCycloStaticChannel()) |
| ? XLIA_EXPRESSION.zero() |
| : XLIA_EXPRESSION.createExpression(constTOKEN_INITIAL_RATE); |
| } |
| |
| /** |
| * Getter for current cyclostatic rate of a port |
| * @param moccPort |
| * @return |
| */ |
| public Expression cycloStaticRateExpression() { |
| assert( moccPort.hasCycloStaticRate() |
| && (constTOKEN_RATE_CSDF != null) ); |
| |
| return XLIA_EXPRESSION.createArrayElement( |
| constTOKEN_RATE_CSDF, |
| XLIA_EXPRESSION.createExpression(XLIA_EXPRESSION.OP_MODULO, |
| this.moccActorHelper.varActivationCount, |
| XLIA_EXPRESSION.createExpression( |
| moccPort.getCycloStaticRate().length))); |
| } |
| |
| |
| /** |
| * Getter using cyclo-static Rate |
| * @param moccPort |
| * @return |
| */ |
| public Expression rateExpression() { |
| if( moccPort.hasCycloStaticRate() ) { |
| return cycloStaticRateExpression(); |
| } |
| else { |
| return XLIA_EXPRESSION.createExpression(constTOKEN_RATE); |
| } |
| } |
| |
| |
| /** |
| * addingNonZeroCycloRateCondition |
| * @param moccPort |
| * @param condition |
| * @return |
| */ |
| public Expression isUndefinedModeCondition( |
| final EnumerationLiteral MODE_UNDEFINED) |
| { |
| final Expression condition = |
| XLIA_EXPRESSION.createRelational(XLIA_EXPRESSION.OP_EQ, |
| varReceivedMode, MODE_UNDEFINED); |
| |
| if( moccPort.hasCycloStaticRate() ) { |
| return XLIA_EXPRESSION.createAND(condition, |
| XLIA_EXPRESSION.createRelational(XLIA_EXPRESSION.OP_GT, |
| cycloStaticRateExpression(), XLIA_EXPRESSION.zero()) ); |
| } |
| else { |
| return condition; |
| } |
| } |
| |
| |
| /** |
| * nonZeroCycloRate condition |
| * @param moccPort |
| * @return |
| */ |
| public Expression nonZeroCycloRateCondition() { |
| return XLIA_EXPRESSION.createRelational(XLIA_EXPRESSION.OP_GT, |
| cycloStaticRateExpression(), XLIA_EXPRESSION.zero() ); |
| } |
| |
| /** |
| * Adding if-condition for non-zero cyclo-static rate |
| * @param blockContainer |
| * @param moccPort |
| * @return |
| */ |
| public BlockStatement testIfHasCycloRate(final BlockStatement blockContainer) |
| { |
| if( moccPort.hasCycloStaticRate() ) { |
| final IfStatement ifStatement = XLIA_STATEMENT.addIf( |
| blockContainer, nonZeroCycloRateCondition() ); |
| // theBlock |
| return XLIA_STATEMENT.createBlockStatement(ifStatement); |
| } |
| |
| return blockContainer; |
| |
| } |
| |
| |
| |
| /** |
| * create xLIA Port for Token |
| * @param moccPort |
| * @param direction |
| * @param xliaActor |
| * @param tokenType |
| * @return |
| */ |
| public Port createPortToken(final String name, |
| final MoccPort moccPort, final ChannelDirection direction, |
| final Machine xliaActor, final DataType tokenType) |
| { |
| final String prefix = |
| (direction == ChannelDirection.INPUT) ? "received": "sent"; |
| |
| final Port xliaPort = |
| XLIA_INFRA.createPort(name, tokenType, prefix + "Token"); |
| |
| xliaPort.setVisibility(VisibilityKind.PUBLIC); |
| |
| xliaPort.setDirection(direction); |
| |
| xliaActor.getPort().add( xliaPort ); |
| |
| return xliaPort; |
| } |
| |
| public Port createPortToken( |
| final MoccPort moccPort, final ChannelDirection direction, |
| final Machine xliaActor, final DataType tokenType) |
| { |
| return createPortToken(moccPort.getName(), |
| moccPort, direction, xliaActor, tokenType); |
| } |
| |
| /** |
| * create xLIA Port for Token and Mode |
| * @param moccPort |
| * @param direction |
| * @param xliaActor |
| * @param tokenType |
| * @param modeType |
| * @return |
| */ |
| public Port createPortTokenMode(final String name, final MoccPort moccPort, |
| final ChannelDirection direction, final Machine xliaActor, |
| final DataType tokenType, final DataType modeType) |
| { |
| final String prefix = |
| (direction == ChannelDirection.INPUT) ? "received": "sent"; |
| |
| final Port xliaPort = XLIA_INFRA.createPort(name, |
| tokenType, prefix + "Token", modeType, prefix + "Mode"); |
| |
| xliaPort.setVisibility(VisibilityKind.PUBLIC); |
| |
| xliaPort.setDirection(direction); |
| |
| xliaActor.getPort().add( xliaPort ); |
| |
| return xliaPort; |
| } |
| |
| public Port createPortTokenMode(final MoccPort moccPort, |
| final ChannelDirection direction, final Machine xliaActor, |
| final DataType tokenType, final DataType modeType) |
| { |
| return createPortTokenMode(moccPort.getName(), |
| moccPort, direction, xliaActor, tokenType, modeType); |
| } |
| |
| |
| |
| |
| /** |
| * OUTPUT PORT -> XLIA |
| * @param moccPort |
| * @param xliaActor |
| * @param aLWAYS_USING_MODE |
| */ |
| public void createOutputPort(final Machine xliaActor, |
| final EnumerationType MODE_SET_TYPE, final boolean ALWAYS_USING_MODE) |
| { |
| // CONSTANT: TOKEN PRODUCTION |
| final DataType varType = |
| XLIA_DATATYPE.createRationalOrInteger(moccPort.isRational()); |
| |
| final String targetActor = |
| moccPort.getChannel().getInputActor().getName();//.toUpperCase(); |
| |
| final Expression value = moccPort.isRational() ? |
| XLIA_EXPRESSION.createRational( |
| moccPort.getRate(), moccPort.getRateDenominator()) |
| : XLIA_EXPRESSION.createInteger(moccPort.getRate()); |
| |
| this.constTOKEN_RATE = XLIA_INFRA.createConstant( |
| varType, "PRODUCTION_TO_" + targetActor, value); |
| xliaActor.getVariable().add(this.constTOKEN_RATE); |
| |
| |
| if( moccPort.hasCycloStaticRate() ) { |
| final int[] cycloStaticRate = moccPort.getCycloStaticRate(); |
| this.constTOKEN_RATE_CSDF = XLIA_INFRA.createVariable( |
| XLIA_DATATYPE.createInteger(cycloStaticRate.length), |
| "CSDF_PRODUCTION_TO_" + targetActor, |
| XLIA_EXPRESSION.createCollection(cycloStaticRate)); |
| xliaActor.getVariable().add(constTOKEN_RATE_CSDF); |
| } |
| |
| // OUTPUT PORT |
| //!@! CSDF : createRationalOrInteger(moccPort.isRational() ==> createInteger() |
| final DataType tokenType = XLIA_DATATYPE.createInteger(); |
| |
| if( ALWAYS_USING_MODE || moccPort.isOutputMode() ) |
| { |
| final DataType modeType = |
| XLIA_DATATYPE.createReference(MODE_SET_TYPE); |
| |
| this.xliaPort = createPortTokenMode("out#" +
|
| moccPort.getChannel().getName(), moccPort, |
| ChannelDirection.OUTPUT, xliaActor, tokenType, modeType); |
| } |
| else { |
| this.xliaPort = createPortToken("out#" +
|
| moccPort.getChannel().getName(), |
| moccPort, ChannelDirection.OUTPUT, xliaActor, tokenType); |
| } |
| } |
| |
| |
| /** |
| * INPUT PORT -> XLIA |
| * @param moccPort |
| * @param xliaActor |
| * @param aLWAYS_USING_MODE |
| */ |
| public void createInputPort(final Machine xliaActor, |
| final EnumerationType MODE_SET_TYPE, final boolean ALWAYS_USING_MODE, |
| final boolean generatedChannelPort) |
| { |
| // CONSTANT: REQUIRED TOKENS RATE |
| DataType constType = |
| XLIA_DATATYPE.createRationalOrInteger(moccPort.isRational()); |
| |
| final String sourceActor = |
| moccPort.getChannel().getOutputActor().getName(); |
| |
| Expression value = moccPort.isInputRational() ? |
| XLIA_EXPRESSION.createRational( |
| moccPort.getRate(), moccPort.getRateDenominator()) |
| : XLIA_EXPRESSION.createInteger(moccPort.getRate()); |
| |
| this.constTOKEN_RATE = XLIA_INFRA.createConstant(constType, |
| "REQUIRED_FROM_" + sourceActor/*.toUpperCase()*/, value); |
| xliaActor.getVariable().add(this.constTOKEN_RATE); |
| |
| if( moccPort.hasCycloStaticRate() ) { |
| final int[] cycloStaticRate = moccPort.getCycloStaticRate(); |
| this.constTOKEN_RATE_CSDF = XLIA_INFRA.createVariable( |
| XLIA_DATATYPE.createInteger(cycloStaticRate.length), |
| "CSDF_REQUIRED_FROM_" + sourceActor, |
| XLIA_EXPRESSION.createCollection(cycloStaticRate)); |
| xliaActor.getVariable().add(this.constTOKEN_RATE_CSDF); |
| } |
| |
| // CONSTANT: INITIAL TOKEN COUNT |
| final MoccChannel channel = moccPort.getChannel(); |
| if( channel.hasInitialRate() ) { |
| constType = XLIA_DATATYPE.createRationalOrInteger( |
| channel.hasRationalRate()); |
| |
| value = channel.hasRationalRate() ? |
| XLIA_EXPRESSION.createRational( |
| channel.getInitialRate(), |
| channel.getInitialRateDenominator()) |
| : XLIA_EXPRESSION.createInteger(channel.getInitialRate()); |
| |
| this.constTOKEN_INITIAL_RATE = XLIA_INFRA.createConstant(constType, |
| "INITIAL_TOKEN_FROM_" + sourceActor/*.toUpperCase()*/, value); |
| |
| xliaActor.getVariable().add(this.constTOKEN_INITIAL_RATE); |
| |
| if( channel.hasInitialMode() ) { |
| constType = XLIA_DATATYPE.createReference(MODE_SET_TYPE); |
| |
| this.constMODE_INITIAL = XLIA_INFRA.createConstant(constType, |
| "INITIAL_MODE_FROM_" + sourceActor/*.toUpperCase()*/, |
| XLIA_EXPRESSION.createExpression( |
| XLIA_DATATYPE.getEnumLiteral(MODE_SET_TYPE, |
| channel.getInitialMode().getLiteral()))); |
| |
| xliaActor.getVariable().add(this.constMODE_INITIAL); |
| } |
| } |
| |
| |
| // VARIABLE: TOKEN COUNT |
| //!@! CSDF : createRationalOrInteger(moccPort.isRationalTokenCount() ==> createInteger() |
| final DataType tokenCountType = //XLIA_DATATYPE.createInteger(); |
| XLIA_DATATYPE.createRationalOrInteger(channel.hasRationalRate()); |
| |
| this.varReceivedTokenCount = XLIA_INFRA.createVariable( |
| tokenCountType, "tokenCount_from_" + sourceActor); |
| xliaActor.getVariable().add(this.varReceivedTokenCount); |
| |
| // INPUT PORT |
| //!@! CSDF : createRationalOrInteger(moccPort.isOutputRational() ==> createInteger() |
| final DataType portTokenType = XLIA_DATATYPE.createInteger(); |
| |
| //!@! CSDF : createRationalOrInteger(moccPort.isRational() ==> createInteger() |
| // moccPort.isOutputRational()); |
| final DataType channelTokenType = XLIA_DATATYPE.createInteger(); |
| |
| if( ALWAYS_USING_MODE || moccPort.isInputMode() ) |
| { |
| this.xliaPort = createPortTokenMode(moccPort, |
| ChannelDirection.INPUT, xliaActor, portTokenType, |
| XLIA_DATATYPE.createReference(MODE_SET_TYPE)); |
| |
| this.varReceivedMode = XLIA_INFRA.createVariable( |
| XLIA_DATATYPE.createReference(MODE_SET_TYPE), |
| "receivedMode_from_" + sourceActor);//, |
| // XLIA_EXPRESSION.createExpression( |
| // this.moccActorHelper.constDEFAULT_MODE)); |
| xliaActor.getVariable().add(this.varReceivedMode); |
| |
| if( generatedChannelPort ) { |
| this.xliaChannelPort = createPortTokenMode("in#" +
|
| moccPort.getChannel().getName(), moccPort, |
| // ChannelDirection.INPUT, xliaActor, channelTokenType, |
| ChannelDirection.OUTPUT, xliaActor, channelTokenType, |
| XLIA_DATATYPE.createReference(MODE_SET_TYPE)); |
| } |
| } |
| else { |
| this.xliaPort = createPortToken(moccPort, |
| ChannelDirection.INPUT, xliaActor, portTokenType); |
| |
| if( generatedChannelPort ) { |
| this.xliaChannelPort = createPortToken("in#" +
|
| moccPort.getChannel().getName(), moccPort, |
| // ChannelDirection.INPUT, xliaActor, channelTokenType); |
| ChannelDirection.OUTPUT, xliaActor, channelTokenType); |
| } |
| } |
| } |
| |
| |
| } |