blob: dbf3e6ad2d122152e908bd9e9e3a2809ef9f341f [file] [log] [blame]
/**
* *******************************************************************************
* Copyright (c) 2019 Robert Bosch GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
* *******************************************************************************
*/
package templates.m2m.stimuli;
import com.google.inject.Inject
import com.inchron.realtime.root.model.Model
import org.eclipse.app4mc.amalthea.model.FrequencyDomain
import org.eclipse.app4mc.amalthea.model.PeriodicStimulus
import org.eclipse.app4mc.amalthea.model.StimuliModel
import org.eclipse.app4mc.amalthea.model.Stimulus
import templates.AbstractAmaltheaInchronTransformer
import templates.m2m.utils.TimeTransformer
import templates.utils.AmltCacheModel
import com.google.inject.Singleton
import templates.m2m.hw.FrequencyDomainTransformer
import org.eclipse.app4mc.amalthea.model.Process
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus
import templates.m2m.utils.CounterUtils
import org.eclipse.app4mc.amalthea.model.EventStimulus
import templates.m2m.sw.ModeValueDisjunctionTransformer
import templates.m2m.sw.CallGraphTransformer
import com.inchron.realtime.root.model.ActivationItem
@Singleton
class StimuliTransformer extends AbstractAmaltheaInchronTransformer {
var AmltCacheModel cacheModel
@Inject TimeTransformer timeUtilsTransformer
@Inject FrequencyDomainTransformer frequencyDomainTransformer
@Inject ModeValueDisjunctionTransformer modeValueDisjunctionTransformer
@Inject CallGraphTransformer callGraphTransformer
def create inchronStimulationFactory.createStimulationScenario createStimulationScenario(StimuliModel amltStimuliModel, Model inchronModel){
it.name = "DefaultScenario"
inchronModel.stimulationScenarios.add(it)
inchronModel.defaultScenario=it
}
def dispatch create inchronModelFactory.createActivationConnection createActivationConnection(Stimulus amltStimulus) {
it.name = amltStimulus.name
//hook into <root>->connections
inchronRoot.connections.add(it)
}
def dispatch create inchronModelFactory.createActivationConnection createActivationConnection(PeriodicStimulus amltStimulus) {
it.name = amltStimulus.name
//hook into stimuli generator
var inchronRandomStimuliGenerator = createRandomStimuliGenerator(amltStimulus)
inchronRandomStimuliGenerator.connections.add(it)
//hook stimuli generator into default scenario
var inchronStimulationScenario = createStimulationScenario(amaltheaRoot.stimuliModel, inchronRoot)
inchronStimulationScenario.generators.add(inchronRandomStimuliGenerator)
}
def create inchronModelFactory.createActivationItem createActivationItem(Stimulus stimulus){
}
def create inchronStimulationFactory.createRandomStimuliGenerator createRandomStimuliGenerator(
PeriodicStimulus amltStimulus) {
it.name = amltStimulus.name
it.startOffset = timeUtilsTransformer.createTime(amltStimulus.offset)
it.period = timeUtilsTransformer.createTime(amltStimulus.recurrence)
var inchronActivationConnection = createActivationConnection(amltStimulus)
it.connections.add(inchronActivationConnection)
var inchronCallGraph = inchronModelFactory.createCallGraph
var inchronCallSequence = inchronModelFactory.createCallSequence
inchronCallSequence.name = "CS"
inchronCallGraph.graphEntries.add(inchronCallSequence)
var inchronActivationItem = inchronModelFactory.createActivationItem
inchronActivationItem.name = "ActivationItem_"+ amltStimulus.name
inchronActivationItem.connection = inchronActivationConnection
inchronCallSequence.calls.add(inchronActivationItem)
it.targets = inchronCallGraph
// TODO: check if the right frequency can be fetched (below solution is good at present. In long run clarify this topic in detail)
var firstFrequencyDomain = getAmaltheaRoot().hwModel.domains.findFirst [ domain | domain instanceof FrequencyDomain]
if (firstFrequencyDomain !== null){
it.clock = frequencyDomainTransformer.createClock(firstFrequencyDomain as FrequencyDomain)
it.variation = inchronModelFactory.createTimeDistribution
it.minInterArrivalTime = inchronModelFactory.createTime
it.startOffsetVariation = inchronModelFactory.createTimeDistribution
}
}
def dispatch create inchronModelFactory.createActivateProcess createActivateProcess(Stimulus amltStimuli, Process amltProcess) {
val inchronActivationConnection = createActivationConnection(amltStimuli)
cacheModel = customObjsStore.getInstance(AmltCacheModel)
var amltProcess_inchronProcessMap = cacheModel.amltProcess_inchronProcessMap
it.target = amltProcess_inchronProcessMap.get(amltProcess)
inchronActivationConnection.activations.add(it)
}
def dispatch create inchronModelFactory.createActivateProcess createActivateProcess(InterProcessStimulus amltStimuli,Process amltProcess) {
val inchronActivationConnection = createActivationConnection(amltStimuli)
cacheModel = customObjsStore.getInstance(AmltCacheModel)
var amltProcess_inchronProcessMap = cacheModel.amltProcess_inchronProcessMap
it.target = amltProcess_inchronProcessMap.get(amltProcess)
if (amltStimuli.counter !== null){
it.period = CounterUtils.getPrescalerAsInteger(amltStimuli.counter)
it.offset = CounterUtils.getOffsetAsInteger(amltStimuli.counter)
}
inchronActivationConnection.activations.add(it)
}
def dispatch create inchronModelFactory.createActivateProcess createActivateProcess(EventStimulus amltStimuli, Process amltProcess ) {
val inchronActivationConnection = createActivationConnection(amltStimuli)
cacheModel = customObjsStore.getInstance(AmltCacheModel)
var amltProcess_inchronProcessMap = cacheModel.amltProcess_inchronProcessMap
it.target = amltProcess_inchronProcessMap.get(amltProcess)
if (amltStimuli.counter !== null){
it.period = CounterUtils.getPrescalerAsInteger(amltStimuli.counter)
it.offset = CounterUtils.getOffsetAsInteger(amltStimuli.counter)
}
inchronActivationConnection.activations.add(it)
}
def create inchronModelFactory.createFunction createDummyFunction(Stimulus amltStimulus, ActivationItem inchronActivationItem){
it.name="Dummy_"+ getStimulusName(amltStimulus)
val inchronCallGraph=inchronModelFactory.createCallGraph
it.callGraph=inchronCallGraph
var amltCondition= getEnableValueList(amltStimulus)
if(amltCondition!==null){
val inchronModeSwitch = inchronModelFactory.createModeSwitch
inchronModeSwitch.name ="EventStimulusCondition"
val inchronModeSwitchEntry=inchronModelFactory.createModeSwitchEntry
// Adding entry with condition
inchronModeSwitch.entries.add(inchronModeSwitchEntry)
var inchronConditon=modeValueDisjunctionTransformer.createModeCondition(amltCondition)
inchronModeSwitchEntry.condition = inchronConditon
//add activation item to call sequence within mode switch's call sequence
val inchronCallSequence_ActivationItem=inchronModelFactory.createCallSequence
inchronCallSequence_ActivationItem.calls.add(inchronActivationItem)
it.callGraph.graphEntries.add(inchronCallSequence_ActivationItem)
inchronModeSwitchEntry.graphEntries.add(inchronCallSequence_ActivationItem)
//add ModeCondition to the Inchron Model: at root --> global condition
if(inchronConditon.eContainer===null){
getInchronRoot().globalModeConditions.add(inchronConditon)
}
//add mode evaluation item before mode switch
callGraphTransformer.createDummyCallSequenceWithModeSwitchEvaluation(inchronModeSwitch, it.callGraph);
//add mode switch to dummy function call graph
it.callGraph.graphEntries.add(inchronModeSwitch)
} else {
val inchronCallSequence_ActivationItem=inchronModelFactory.createCallSequence
it.callGraph.graphEntries.add(inchronCallSequence_ActivationItem)
}
}
private def dispatch getStimulusName(Stimulus stimulus){return "Stimulus"}
private def dispatch getStimulusName(EventStimulus stimulus){return stimulus.name}
private def dispatch getStimulusName(InterProcessStimulus stimulus){return stimulus.name}
private def dispatch getEnableValueList(Stimulus stimulus){return null}
private def dispatch getEnableValueList(EventStimulus stimulus){return stimulus.enablingModeValueList}
private def dispatch getEnableValueList(InterProcessStimulus stimulus){return stimulus.enablingModeValueList}
}