| /** |
| * ******************************************************************************* |
| * Copyright (c) 2019-2021 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 |
| |
| import com.google.inject.Inject |
| import org.eclipse.app4mc.amalthea.model.Amalthea |
| import org.eclipse.app4mc.amalthea.model.check.ModelStructureCheck |
| import org.eclipse.app4mc.amalthea.model.util.ModelUtil |
| import org.eclipse.app4mc.amlt2systemc.m2t.module.BaseTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.module.PropertyKeys |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.event.EventModelTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.hw.HwModelTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.hw.MemoryTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.hw.ProcessingUnitTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.mapping.MappingModelTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.os.OsModelTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.stimuli.StimuliModelTransformer |
| import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.SWModelTransformer |
| import org.eclipse.app4mc.transformation.util.OutputBuffer |
| import org.slf4j.Logger |
| import org.slf4j.LoggerFactory |
| |
| class AmaltheaTransformer extends BaseTransformer { |
| |
| @Inject OutputBuffer outputBuffer |
| @Inject SWModelTransformer swModelTransformer |
| @Inject OsModelTransformer osModelTransformer |
| @Inject MappingModelTransformer mappingModelTransformer |
| @Inject HwModelTransformer hwModelTransformer |
| @Inject EventModelTransformer eventModelTransformer |
| @Inject StimuliModelTransformer stimuliModelTransformer |
| |
| @Inject ProcessingUnitTransformer processingUnitTransformer |
| @Inject MemoryTransformer memoryTransformer |
| |
| static final Logger LOG = LoggerFactory.getLogger(AmaltheaTransformer); |
| |
| static def getModulePath() { |
| return "amaltheaTop" |
| } |
| |
| def getModuleName() { |
| return getModulePath() + "/amalthea" |
| } |
| |
| def void transform(Amalthea amalthea) { |
| |
| if (amalthea === null) { |
| LOG.error("Input Amalthea model invalid (received null).") |
| return |
| } |
| |
| if (!ModelStructureCheck.checkModel(amalthea, null, false)){ |
| LOG.error("Input Amalthea model failed model structure check.") |
| return |
| } |
| |
| adjustModel(amalthea) |
| |
| outputBuffer.appendTo("INC", getModuleName(), toH(amalthea)) |
| outputBuffer.appendTo("SRC", getModuleName(), toCpp(amalthea)) |
| outputBuffer.appendTo("OTHER", getModulePath() + "/CMakeLists.txt", getCMake()); |
| } |
| |
| private def void adjustModel(Amalthea amalthea) { |
| // ensure that the following sub models are available |
| ModelUtil.getOrCreateSwModel(amalthea); |
| ModelUtil.getOrCreateOsModel(amalthea); |
| ModelUtil.getOrCreateHwModel(amalthea); |
| ModelUtil.getOrCreateMappingModel(amalthea); |
| ModelUtil.getOrCreateEventModel(amalthea); |
| ModelUtil.getOrCreateStimuliModel(amalthea); |
| } |
| |
| private def String toH(Amalthea amalthea) ''' |
| //top level header |
| ''' |
| |
| private def String toCpp(Amalthea amalthea) ''' |
| #include "APP4MCsim.h" |
| #include "Tracer/Tracer.h" |
| #include "Tracer/BTFTracer.h" |
| |
| #include "«getModuleName()».h" |
| //include model elements |
| #include "«swModelTransformer.transform(ModelUtil.getOrCreateSwModel(amalthea)).module».h" |
| #include "«hwModelTransformer.transform(ModelUtil.getOrCreateHwModel(amalthea)).module».h" |
| #include "«mappingModelTransformer.transform(ModelUtil.getOrCreateMappingModel(amalthea)).module».h" |
| #include "«osModelTransformer.transform(ModelUtil.getOrCreateOsModel(amalthea)).module».h" |
| #include "«eventModelTransformer.transform(ModelUtil.getOrCreateEventModel(amalthea)).module».h" |
| #include "«stimuliModelTransformer.transform(ModelUtil.getOrCreateStimuliModel(amalthea)).module».h" |
| |
| |
| //include processing units and memories for tracing ----- |
| «FOR tu: processingUnitTransformer.cache.values» |
| #include "«tu.module».h" |
| «ENDFOR» |
| «FOR tu: memoryTransformer.cache.values» |
| #include "«tu.module».h" |
| «ENDFOR» |
| // tracing includes ----------------- |
| |
| INITIALIZE_EASYLOGGINGPP; |
| |
| int sc_main(int argc, char *argv[]) { |
| //static code ---------------------- |
| START_EASYLOGGINGPP(argc, argv); |
| sc_core::sc_set_time_resolution(1.0,sc_core::SC_NS); |
| //end static code ------------------ |
| |
| /* Hardware */ |
| «hwModelTransformer.transform(amalthea.hwModel).call»; |
| |
| /* Software */ |
| «swModelTransformer.transform(amalthea.swModel).call»; |
| |
| /* OS */ |
| «osModelTransformer.transform(amalthea.osModel).call»; |
| |
| |
| /* Mapping */ |
| «mappingModelTransformer.transform(amalthea.mappingModel).call»; |
| |
| /* Event */ |
| «eventModelTransformer.transform(amalthea.eventModel).call»; |
| |
| /* Stimuli */ |
| «stimuliModelTransformer.transform(amalthea.stimuliModel).call»; |
| |
| «val tracer = super.getProperty("tracer", "BtfTracer")» |
| |
| auto tracer = std::make_shared<«tracer»>(); |
| TraceManager::setTracer(tracer); |
| |
| //static code ---------------------- |
| sc_core::sc_trace_file *tf = sc_core::sc_create_vcd_trace_file("trace"); |
| |
| //trace processing units and memories ----- |
| «FOR tu: processingUnitTransformer.cache.values» |
| sc_trace(tf, &*«tu.call»(), "«tu.module.replaceAll("/", "_")»"); |
| «ENDFOR» |
| «FOR tu: memoryTransformer.cache.values» |
| sc_trace(tf, &*«tu.call»(), "«tu.module.replaceAll("/", "_")»"); |
| «ENDFOR» |
| // tracing includes ----------------- |
| |
| |
| try { |
| «val simDuration = super.getProperty("simDurationInMS", "1000")» |
| sc_core::sc_start(«simDuration», sc_core::SC_MS); |
| } |
| catch (sc_core::sc_report e) { |
| const char* file = e.get_file_name(); |
| const int line = e.get_line_number(); |
| const char* msg = e.get_msg(); |
| VLOG(0) << msg << "\nin file: " << file << "\nline: " << line; |
| return -1; |
| } |
| |
| sc_core::sc_close_vcd_trace_file(tf); |
| |
| VLOG(0) << " done "; |
| return 0; |
| }''' |
| |
| def String getCMake() ''' |
| include_directories(${PROJECT_SOURCE_DIR}) |
| add_subdirectory ("./hwModel") |
| add_subdirectory ("./swModel") |
| add_subdirectory ("./mappingModel") |
| add_subdirectory ("./eventModel") |
| add_subdirectory ("./stimuliModel") |
| add_subdirectory ("./osModel") |
| |
| add_executable («getProperty(PropertyKeys.PROJECT_NAME)» |
| "${PROJECT_SOURCE_DIR}/«getModuleName()».cpp" |
| ) |
| |
| target_link_libraries(«getProperty(PropertyKeys.PROJECT_NAME)» app4mc.sim_lib eventModel_lib stimuliModel_lib swModel_lib hwModel_lib mappingModel_lib osModel_lib) |
| target_include_directories(«getProperty(PropertyKeys.PROJECT_NAME)» PUBLIC app4mc.sim_lib eventModel_lib stimuliModel_lib swModel_lib hwModel_lib mappingModel_lib osModel_lib) |
| |
| add_custom_target(model_execution |
| COMMAND «getProperty(PropertyKeys.PROJECT_NAME)» |
| WORKING_DIRECTORY "${MODEL_WORKING_DIR}" |
| ) |
| ''' |
| |
| } |