blob: 3ae36183c1113690e1fa1f9750d53a8d06f7e845 [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2019-2020 Robert Bosch GmbH.
*
* 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 org.eclipse.app4mc.amlt2systemc.m2t.transformers.mapping
import com.google.inject.Inject
import com.google.inject.Singleton
import java.util.ArrayList
import org.eclipse.app4mc.amalthea.model.AbstractMemoryElement
import org.eclipse.app4mc.amalthea.model.Channel
import org.eclipse.app4mc.amalthea.model.Label
import org.eclipse.app4mc.amalthea.model.Memory
import org.eclipse.app4mc.amalthea.model.MemoryMapping
import org.eclipse.app4mc.amalthea.model.ModeLabel
import org.eclipse.app4mc.amlt2systemc.m2t.module.BaseTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.TranslationUnit
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.hw.MemoryTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.ChannelTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.LabelTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.ModeLabelTransformer
import org.eclipse.app4mc.transformation.util.OutputBuffer
@Singleton
class MemoryMappingTransformer extends BaseTransformer {
@Inject OutputBuffer outputBuffer
@Inject MemoryTransformer memoryTransformer
@Inject LabelTransformer labelTransformer
@Inject ChannelTransformer channelTransformer
@Inject ModeLabelTransformer modeLabelTransformer
static def String getModulePath() {
return MappingModelTransformer.getModulePath() + "/memoryMapping"
}
def String getModuleName(AbstractMemoryElement element, Memory memory) {
return getModulePath() + "/memoryMapping"//_" + element.name + "_to_" + memory.name
}
def String getCall(AbstractMemoryElement element, Memory memory) '''
init_MemoryMapping_«element.name»_to_«memory.name»'''
private def String getImplementation(String functionName, String memoryElementGetter, String memoryGetter,
Long memoryAddress) '''
void «functionName»(){
MappingModel::addMemoryMapping(«memoryElementGetter», «memoryGetter»);
MappingModel::addMemoryAddress(«memoryElementGetter», «memoryAddress»);
}
'''
def TranslationUnit transform(MemoryMapping memoryMapping) {
if (!memoryElementIsUsed(memoryMapping.abstractElement)){
//only memory elements that are actually referred to somwhere in the
//sw model will be transformed, therefore mappings of unused labels
//must be skipped to avoid issues during compilation(during linking)
return null;
} else {
return transformInternal(memoryMapping);
}
}
private def create new TranslationUnit(
getModuleName(memoryMapping.abstractElement, memoryMapping.memory),
getCall(memoryMapping.abstractElement, memoryMapping.memory)
) transformInternal(MemoryMapping memoryMapping) {
toH(memoryMapping.abstractElement, memoryMapping.memory)
toCpp(memoryMapping.abstractElement, memoryMapping.memory, memoryMapping.memoryPositionAddress)
// includedMemories.add(memoryMapping.memory)
}
def dispatch memoryElementIsUsed(Channel element) {
val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
return channelTransformer.cache.containsKey(_cacheKey);
}
def dispatch memoryElementIsUsed(Label element) {
val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
return labelTransformer.cache.containsKey(_cacheKey);
}
def dispatch memoryElementIsUsed(ModeLabel element) {
val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
return modeLabelTransformer.cache.containsKey(_cacheKey)
}
def dispatch memoryElementIsUsed(AbstractMemoryElement element) {
return false;
}
//Label
def dispatch void toH(Label label, Memory memory) {
val moduleName = getModuleName(label, memory)
if (!outputBuffer.bufferExists("INC", moduleName)) {
outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel/MappingModel.h\"\n");
}
outputBuffer.appendTo("INC", moduleName, "void " + getCall(label, memory) + "();\n");
}
def dispatch void toCpp(Label label, Memory memory, long address) {
val moduleName = getModuleName(label, memory)
outputBuffer.appendTo("SRC", moduleName, "#include \"" + moduleName + ".h\"\n")
val tuLabel = labelTransformer.transform(label)
val tuMemory = memoryTransformer.transform(memory)
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuLabel.module + ".h\"\n");
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuMemory.module + ".h\"\n");
outputBuffer.appendTo("SRC",
moduleName,
getImplementation(getCall(label, memory), tuLabel.call, tuMemory.call + "()", address)
)
}
//Channel
def dispatch void toH(Channel channel, Memory memory) {
val moduleName = getModuleName(channel, memory)
if (!outputBuffer.bufferExists("INC", moduleName)) {
outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel/MappingModel.h\"\n");
}
outputBuffer.appendTo("INC", moduleName, "void " + getCall(channel, memory) + "();\n");
}
def dispatch void toCpp(Channel channel, Memory memory, long address) {
val moduleName = getModuleName(channel, memory)
val tuChannel = channelTransformer.transform(channel)
val tuMemory = memoryTransformer.transform(memory)
outputBuffer.appendTo("SRC", moduleName, "#include \"" + moduleName + ".h\"\n")
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuMemory.module + ".h\"\n");
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuChannel.module + ".h\"\n");
outputBuffer.appendTo("SRC",
moduleName,
getImplementation(getCall(channel, memory), tuChannel.call, tuMemory.call + "()", address)
)
}
//ModeLabel
def dispatch void toH(ModeLabel modeModeLabel, Memory memory) {
val moduleName = getModuleName(modeModeLabel, memory)
if (!outputBuffer.bufferExists("INC", moduleName)) {
outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel/MappingModel.h\"\n");
}
outputBuffer.appendTo("INC", moduleName, "void " + getCall(modeModeLabel, memory) + "();\n");
}
def dispatch void toCpp(ModeLabel modeModeLabel, Memory memory, long address) {
val moduleName = getModuleName(modeModeLabel, memory)
val tuModeLabel = modeLabelTransformer.transform(modeModeLabel)
val tuMemory = memoryTransformer.transform(memory)
outputBuffer.appendTo("SRC", moduleName, "#include \"" + moduleName + ".h\"\n")
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuMemory.module + ".h\"\n");
outputBuffer.appendTo("SRC", moduleName, "#include \"" + tuModeLabel.module + ".h\"\n");
outputBuffer.appendTo("SRC",
moduleName,
getImplementation(getCall(modeModeLabel, memory), tuModeLabel.call, tuMemory.call + "()", address)
)
}
def getCache() { return this._createCache_transformInternal }
}