blob: d483247a7ff8c7cb50a3b44debbd0f10a325d20e [file] [log] [blame]
/**
* *******************************************************************************
* 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}"
)
'''
}