blob: 0fefeb4f1b36b789ed08f471daa8f76e95f291c2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 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.xlia;
import org.eclipse.efm.ecore.formalml.expression.Expression;
import org.eclipse.efm.ecore.formalml.expression.RelationalBinaryExpression;
import org.eclipse.efm.ecore.formalml.infrastructure.Behavior;
import org.eclipse.efm.ecore.formalml.infrastructure.Machine;
import org.eclipse.efm.ecore.formalml.infrastructure.ModelOfExecution;
import org.eclipse.efm.ecore.formalml.infrastructure.Routine;
import org.eclipse.efm.ecore.formalml.statemachine.Pseudostate;
import org.eclipse.efm.ecore.formalml.statemachine.Region;
import org.eclipse.efm.ecore.formalml.statemachine.Statemachine;
import org.eclipse.efm.ecore.formalml.statemachine.Transition;
import org.eclipse.efm.ecore.formalml.statemachine.Vertex;
import org.eclipse.efm.ecore.formalml.statement.BlockStatement;
import org.eclipse.efm.ecore.formalml.statement.ConditionalBlockStatement;
import org.eclipse.efm.ecore.formalml.statement.IfStatement;
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_STATEMACHINE;
import org.eclipse.efm.formalml.ecore.factory.XLIA_STATEMENT;
import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast.MoccActor;
import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast.MoccSystem;
import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast.feature.MoccSystemFeature;
import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.helper.MoccActorHelper;
public class MoCC2XLIASchedule {
protected final MoCC2XLIA mainGenerator;
protected final MoccSystem moccSystem;
protected final Machine xliaMainMachine;
public MoCC2XLIASchedule(final MoCC2XLIA mainGenerator,
final MoccSystem moccSystem, final Machine xliaMainMachine) {
super();
this.mainGenerator = mainGenerator;
this.moccSystem = moccSystem;
this.xliaMainMachine = xliaMainMachine;
}
/**
* XLIA SYSTEM SCHEDULING
* @param moccSystemFeature
*/
public void compute(final MoccSystemFeature moccSystemFeature)
{
// computeScheduler(moccSystemFeature);
computeBehavior(moccSystemFeature);
}
/**
* XLIA SYSTEM SCHEDULER
* @param moccSystemFeature
*/
public void computeScheduler(final MoccSystemFeature moccSystemFeature)
{
final ModelOfExecution moExcecution =
XLIA_INFRA.createMOE(this.xliaMainMachine.getMain());
// MOE: RUN
final Routine runRoutine =
XLIA_INFRA.createRoutine(XLIA_STATEMENT.OP_RUN);
moExcecution.setRunRoutine(runRoutine);
final BlockStatement blockRun =
XLIA_STATEMENT.createBlockStatement(runRoutine);
// Authorized global activation
XLIA_STATEMENT.addAssignment(blockRun,
this.mainGenerator.varCanBeActivate,
XLIA_EXPRESSION.trueValue());
XLIA_STATEMENT.addActivitySchedule(blockRun);
// Test if a timed actor disable global activation because of
// timed constraint failure
if( moccSystemFeature.hasTimed ) {
XLIA_STATEMENT.addGuard(blockRun,
XLIA_EXPRESSION.createExpression(
this.mainGenerator.varCanBeActivate));
}
// MOE: SCHEDULE
final Routine scheduleRoutine =
XLIA_INFRA.createRoutine(XLIA_STATEMENT.OP_SCHEDULE);
moExcecution.setScheduleRoutine(scheduleRoutine);
final BlockStatement blockSchedule =
XLIA_STATEMENT.createBlockStatement(scheduleRoutine);
final int activationCount = moccSystemFeature.hyperperiod - 1;
if( moccSystemFeature.hasTimed ) {
final IfStatement ifStatement = XLIA_STATEMENT.addIf(blockSchedule);
computeSchedulingActor(moccSystemFeature, ifStatement, 0);
for( int index = 1 ; index < activationCount; index++) {
computeSchedulingActor(moccSystemFeature,
XLIA_STATEMENT.addElseIf(ifStatement), index);
}
final BlockStatement elseBlock =
XLIA_STATEMENT.createElseBlockStatement(ifStatement);
computeSchedulingActor(moccSystemFeature, elseBlock, activationCount);
}
else if( moccSystemFeature.hyperperiod > 1 ) {
final IfStatement ifStatement = XLIA_STATEMENT.addIf(blockSchedule);
computeStagingActor(moccSystemFeature, ifStatement, 0);
for( int stage = 1 ; stage < activationCount; stage++) {
computeStagingActor(moccSystemFeature,
XLIA_STATEMENT.addElseIf(ifStatement), stage);
}
final BlockStatement elseBlock =
XLIA_STATEMENT.createElseBlockStatement(ifStatement);
computeStagingActor(moccSystemFeature, elseBlock, activationCount);
}
else {
computeSchedulingActor(moccSystemFeature, blockSchedule, 0);
}
// MOE: RUN
XLIA_STATEMENT.addAssignment(blockRun, this.mainGenerator.varTimestamp,
XLIA_EXPRESSION.createExpression(
XLIA_EXPRESSION.OP_PLUS,
this.mainGenerator.varTimestamp,
this.mainGenerator.constTickFrequency));
XLIA_STATEMENT.addAssignment(blockRun,
this.mainGenerator.varTick,
XLIA_EXPRESSION.createExpression(
XLIA_EXPRESSION.OP_PLUS,
this.mainGenerator.varTick,
XLIA_EXPRESSION.createInteger(1)));
// PERIOD & RE-INITIALISATION
final IfStatement ifPeriod = XLIA_STATEMENT.addIf(blockRun,
XLIA_EXPRESSION.createRelational(
XLIA_EXPRESSION.OP_EQ,
this.mainGenerator.varTick,
this.mainGenerator.constHyperPeriod));
final BlockStatement blockPeriod =
XLIA_STATEMENT.createBlockStatement(ifPeriod);
// NEW PERIOD: INTIALISATION
XLIA_STATEMENT.addAssignment(blockPeriod,
this.mainGenerator.varTick, XLIA_EXPRESSION.zero());
computeScheduleReinitialisation(moccSystemFeature, blockPeriod);
}
protected void computeSchedulingActor(
final MoccSystemFeature moccSystemFeature,
final ConditionalBlockStatement ifBlock, final int activationIndex) {
final BlockStatement thenBlock =
XLIA_STATEMENT.createBlockStatement(ifBlock);
ifBlock.setCondition(XLIA_EXPRESSION.createRelational(
XLIA_EXPRESSION.OP_EQ, this.mainGenerator.varTick,
XLIA_EXPRESSION.createInteger(activationIndex)));
computeSchedulingActor(moccSystemFeature, thenBlock, activationIndex);
}
protected void computeSchedulingActor(
final MoccSystemFeature moccSystemFeature,
final BlockStatement thenBlock, final int activationIndex) {
// int statementCount = 0;
for( final MoccActor actor : this.moccSystem.getActor() ) {
if( actor.FEATURE.activation[activationIndex] ) {
final MoccActorHelper actorHELPER = this.mainGenerator.helper(actor);
if( actor.FEATURE.isTimed ) {
XLIA_STATEMENT.addActivityRun(thenBlock, actorHELPER.machine);
}
else {
XLIA_STATEMENT.addActivityRtc(thenBlock, actorHELPER.machine);
}
// Increment statementCount
// ++statementCount;
}
}
// if( (statementCount > 1) /*&& (! moccSystemFeature.hasTimed)*/ ) {
// thenBlock.setOp( XLIA_STATEMENT.OP_SEQUENCE_WEAK );
// }
}
protected void computeStagingActor(
final MoccSystemFeature moccSystemFeature,
final ConditionalBlockStatement ifBlock, final int stageIndex) {
final BlockStatement thenBlock =
XLIA_STATEMENT.createBlockStatement(ifBlock);
ifBlock.setCondition(XLIA_EXPRESSION.createRelational(
XLIA_EXPRESSION.OP_EQ, this.mainGenerator.varTick,
XLIA_EXPRESSION.createInteger(stageIndex)));
computeStagingActor(moccSystemFeature, thenBlock, stageIndex);
}
protected void computeStagingActor(
final MoccSystemFeature moccSystemFeature,
final BlockStatement thenBlock, final int stageIndex) {
// int statementCount = 0;
for( final MoccActor actor : this.moccSystem.getActor() ) {
if( (actor.schedule == stageIndex) && actor.FEATURE.isExecutable ) {
final MoccActorHelper actorHELPER = this.mainGenerator.helper(actor);
XLIA_STATEMENT.addActivityRtc(thenBlock, actorHELPER.machine);
// Increment statementCount
// ++statementCount;
}
}
// if( (statementCount > 1) /*&& (! moccSystemFeature.hasTimed)*/ ) {
// thenBlock.setOp( XLIA_STATEMENT.OP_SEQUENCE_WEAK );
// }
}
protected void computeScheduleReinitialisation(
final MoccSystemFeature moccSystemFeature,
final BlockStatement blockPeriod)
{
BlockStatement blockReinit = blockPeriod;
// XLIA_STATEMENT.addAssignment(blockReinit,
// this.mainGenerator.varTick, XLIA_EXPRESSION.zero());
IfStatement ifReinit = null;
if( ! moccSystemFeature.hasTimed ) {
ifReinit = XLIA_STATEMENT.addIf(blockReinit);
blockReinit = XLIA_STATEMENT.createBlockStatement(ifReinit);
}
Expression untimedConditionalReinitialisation = null;
// NEW PERIOD: CHECKING
for( final MoccActor actor : this.moccSystem.getActor() ) {
final MoccActorHelper actorHELPER = this.mainGenerator.helper(actor);
if( actor.FEATURE.isExecutable ) // && (! actor.FEATURE.isTimed) )
{
final RelationalBinaryExpression actorRepetitionCond =
XLIA_EXPRESSION.createRelational(
XLIA_EXPRESSION.OP_EQ,
actorHELPER.machine,
actorHELPER.varActivationCount,
actorHELPER.constREPETITION);
if( moccSystemFeature.hasTimed ) {
XLIA_STATEMENT.addGuard(blockReinit, actorRepetitionCond);
}
else if( untimedConditionalReinitialisation == null ) {
untimedConditionalReinitialisation = actorRepetitionCond;
}
else {
untimedConditionalReinitialisation =
XLIA_EXPRESSION.createFlatAND(
untimedConditionalReinitialisation,
actorRepetitionCond);
}
//!@! CSDF
XLIA_STATEMENT.addAssignment(blockReinit,
actorHELPER.machine,
actorHELPER.varActivationCount,
XLIA_EXPRESSION.zero());
}
}
// UNTIMED SYSTEM RE-INITIALISATION
if( untimedConditionalReinitialisation != null ) {
ifReinit.setCondition(untimedConditionalReinitialisation);
}
// ENABLED ONLY RECEPTION BEFORE RE-INITIALISATION
final BlockStatement blockReception =
XLIA_STATEMENT.createBlockStatement(
blockReinit, XLIA_STATEMENT.OP_SEQUENCE_WEAK);
XLIA_STATEMENT.addAssignment(blockReception,
this.mainGenerator.varCanBeActivate,
XLIA_EXPRESSION.falseValue());
for( final MoccActor actor : this.moccSystem.getActor() ) {
if( actor.FEATURE.hasInput && actor.FEATURE.isExecutable ) {
XLIA_STATEMENT.addActivityRun(blockReception,
this.mainGenerator.helper(actor).machine);
}
}
XLIA_STATEMENT.addAssignment(blockReception,
this.mainGenerator.varCanBeActivate,
XLIA_EXPRESSION.trueValue());
}
/**
* XLIA SYSTEM SCHEDULER
* @param moccSystemFeature
*/
public void computeBehavior(final MoccSystemFeature moccSystemFeature)
{
final Statemachine xliaScheduler =
XLIA_STATEMACHINE.createStatemachine("scheduler");
this.xliaMainMachine.getBehavior().add(xliaScheduler);
final Region region = XLIA_STATEMACHINE.createRegion(xliaScheduler);
final Pseudostate s_init =
XLIA_STATEMACHINE.createInitialState(region, "s_init");
final Pseudostate s_tick_period =
XLIA_STATEMACHINE.createJunctionState(region, "tick_period");
Vertex s_tick = XLIA_STATEMACHINE.createState(region, "tick_0");
final Transition t_init = XLIA_STATEMACHINE.createTransition(
"t_init", s_init, s_tick);
final Transition t_period = XLIA_STATEMACHINE.createTransition(
"t_period", s_tick_period, s_tick);
Vertex next_tick = (moccSystemFeature.hyperperiod > 1) ?
XLIA_STATEMACHINE.createState(region, "tick_1") : s_tick_period;
Transition t_tick = XLIA_STATEMACHINE.createTransition(
"t_tick_0", s_tick, next_tick);
final int activationCount = moccSystemFeature.hyperperiod - 1;
if( moccSystemFeature.hasTimed ) {
computeRunninActorTickAcivity(moccSystemFeature, t_tick, 0);
if( activationCount > 0 ) {
for( int index = 1 ; index < activationCount; index++) {
s_tick = next_tick;
next_tick = XLIA_STATEMACHINE.createState(
region, "tick_" + (index + 1));
t_tick = XLIA_STATEMACHINE.createTransition(
"t_tick_" + index, s_tick, next_tick);
computeRunninActorTickAcivity(
moccSystemFeature, t_tick, index);
}
t_tick = XLIA_STATEMACHINE.createTransition(
"t_tick_" + activationCount, next_tick, s_tick_period);
computeRunninActorTickAcivity(
moccSystemFeature, t_tick, activationCount);
}
}
else if( moccSystemFeature.hyperperiod > 1 ) {
computeStaginActorTickAcivity(moccSystemFeature, t_tick, 0);
for( int index = 1 ; index < activationCount; index++) {
s_tick = next_tick;
next_tick = XLIA_STATEMACHINE.createState(
region, "tick_" + (index + 1));
t_tick = XLIA_STATEMACHINE.createTransition(
"t_tick_" + index, s_tick, next_tick);
computeStaginActorTickAcivity(moccSystemFeature, t_tick, index);
}
t_tick = XLIA_STATEMACHINE.createTransition(
"t_tick_" + activationCount, next_tick, s_tick_period);
computeStaginActorTickAcivity(
moccSystemFeature, t_tick, activationCount);
}
else if( moccSystemFeature.hyperperiod == 0 ) {
}
computeReinitialisationAcivity(
moccSystemFeature, t_period, activationCount);
computeBehaviorMoe(moccSystemFeature, xliaScheduler);
}
protected void computeRunninActorTickAcivity(
final MoccSystemFeature moccSystemFeature,
final Transition transition, final int activationIndex)
{
final BlockStatement block =
XLIA_STATEMENT.createBlockStatement(transition);
// ifBlock.setCondition(XLIA_EXPRESSION.createRelational(
// XLIA_EXPRESSION.OP_EQ, this.mainGenerator.varTick,
// XLIA_EXPRESSION.createInteger(activationIndex)));
XLIA_STATEMENT.addAssignment(block, this.mainGenerator.varTick,
XLIA_EXPRESSION.createInteger(activationIndex));
computeSchedulingActor(moccSystemFeature, block, activationIndex);
// XLIA_STATEMENT.addAssignment(block, this.mainGenerator.varTick,
// XLIA_EXPRESSION.createInteger(activationIndex + 1));
}
protected void computeStaginActorTickAcivity(
final MoccSystemFeature moccSystemFeature,
final Transition transition, final int stageIndex)
{
final BlockStatement block =
XLIA_STATEMENT.createBlockStatement(transition);
// ifBlock.setCondition(XLIA_EXPRESSION.createRelational(
// XLIA_EXPRESSION.OP_EQ, this.mainGenerator.varTick,
// XLIA_EXPRESSION.createInteger(activationIndex)));
computeStagingActor(moccSystemFeature, block, stageIndex);
XLIA_STATEMENT.addAssignment(block, this.mainGenerator.varTick,
XLIA_EXPRESSION.createInteger(stageIndex + 1));
}
protected void computeReinitialisationAcivity(
final MoccSystemFeature moccSystemFeature,
final Transition transition, final int activationIndex)
{
final BlockStatement blockPeriod =
XLIA_STATEMENT.createBlockStatement(transition);
// XLIA_STATEMENT.addAssignment(blockPeriod,
// this.mainGenerator.varTick, XLIA_EXPRESSION.zero());
// Test if a timed actor disable global activation because of
// timed constraint failure
if( moccSystemFeature.hasTimed ) {
XLIA_STATEMENT.addGuard(blockPeriod,
XLIA_EXPRESSION.createExpression(this.mainGenerator.varCanBeActivate));
}
computeScheduleReinitialisation(moccSystemFeature, blockPeriod);
}
private void computeBehaviorMoe(
final MoccSystemFeature moccSystemFeature, final Machine xliaScheduler) {
final Behavior moeBehavior = XLIA_INFRA.createBehavior();
xliaScheduler.setMain(moeBehavior);
final ModelOfExecution moExcecution = XLIA_INFRA.createMOE(moeBehavior);
// MOE: RUN
final Routine runRoutine =
XLIA_INFRA.createRoutine(XLIA_STATEMENT.OP_RUN);
moExcecution.setRunRoutine(runRoutine);
final BlockStatement blockRun =
XLIA_STATEMENT.createBlockStatement(runRoutine);
// Authorized global activation
XLIA_STATEMENT.addAssignment(blockRun,
this.mainGenerator.varCanBeActivate,
XLIA_EXPRESSION.trueValue());
XLIA_STATEMENT.addActivitySchedule(blockRun);
// Test if a timed actor disable global activation because of
// timed constraint failure
if( moccSystemFeature.hasTimed ) {
XLIA_STATEMENT.addGuard(blockRun,
XLIA_EXPRESSION.createExpression(this.mainGenerator.varCanBeActivate));
}
XLIA_STATEMENT.addAssignment(blockRun, this.mainGenerator.varTimestamp,
XLIA_EXPRESSION.createExpression(
XLIA_EXPRESSION.OP_PLUS,
this.mainGenerator.varTimestamp,
this.mainGenerator.constTickFrequency));
}
}