| /** |
| ******************************************************************************** |
| * 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 } |
| |
| } |