blob: 7e2afe3418e63199911be56c52d313ee2d745101 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}
}