extends configurability of generator

This commit is contained in:
2022-10-24 20:18:49 +02:00
parent 1c9c0ee340
commit 1d2384257e
19 changed files with 826 additions and 684 deletions

View File

@ -4,6 +4,7 @@ import com.minres.rdl.rdl.ComponentDefinition
import com.minres.rdl.rdl.ComponentDefinitionType
import static extension com.minres.rdl.RdlUtil.*
import java.util.Date
class AddrmapGenerator extends RdlBaseGenerator {
@ -18,8 +19,18 @@ class AddrmapGenerator extends RdlBaseGenerator {
}
override generateHeader(String namespace) {'''
#ifndef _«componentDefinition.effectiveName.toUpperCase»_MAP_H_
#define _«componentDefinition.effectiveName.toUpperCase»_MAP_H_
/*
* Copyright (c) 2019 -2022 MINRES Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*
* Created on: «new Date»
* * «componentDefinition.effectiveName».h Author: <RDL Generator>
*
*/
#pragma once
// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
const std::array<scc::target_memory_map_entry<32>, «componentDefinition.instanceCount(ComponentDefinitionType.REGFILE)»> «componentDefinition.effectiveName»_map = {{
«FOR instantiation : componentDefinition.instantiationsOfType(ComponentDefinitionType.REGFILE)»

View File

@ -21,43 +21,17 @@ class FwAddrmapGenerator extends RdlBaseGenerator {
}
override generateHeader(String namespace) {'''
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020-2022, MINRES Technologies GmbH
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Created on: «new Date»
// * «componentDefinition.name».h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*
* Copyright (c) 2019 -2022 MINRES Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*
* Created on: «new Date»
* * «componentDefinition.effectiveName».h Author: <RDL Generator>
*
*/
#ifndef _«componentDefinition.effectiveName.toUpperCase»_MAP_H_
#define _«componentDefinition.effectiveName.toUpperCase»_MAP_H_
#pragma once
«FOR instantiation : componentDefinition.instantiationsOfType(ComponentDefinitionType.REGFILE)»
«IF instantiation.component !== null && !nameMap.contains(instantiation.component.name)»

View File

@ -22,43 +22,17 @@ class FwRegfileGenerator extends RdlBaseGenerator{
}
override String generateHeader(String namespace)'''
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020-2022, MINRES Technologies GmbH
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Created on: «new Date»
// * «componentDefinition.name».h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*
* Copyright (c) 2019 -2022 MINRES Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*
* Created on: «new Date»
* * «componentDefinition.effectiveName».h Author: <RDL Generator>
*
*/
#ifndef _«componentDefinition.name.toUpperCase»_H_
#define _«componentDefinition.name.toUpperCase»_H_
#pragma once
#include <util/bit_field.h>
#include <nonstd/span.hpp>

View File

@ -23,7 +23,9 @@ import java.io.File
class Main {
val USAGE_STR = "RDL2code [-h] [-v] [-f] [-n <namespace>] [-I <RDL include dir] [-o <output dir>] <input file> <input file>";
val USAGE_STR = '''
RDL2code [-h] [-v] [-f] [-fw] [-sc [-n <namespace>]] [-I <RDL include dir] [-o <output dir>] <input file> <input file>
'''
def static main(String[] args) {
if (args.empty) {
@ -56,7 +58,6 @@ class Main {
@Inject JavaIoFileSystemAccess fileAccess
def run(String[] args) {
val opt = new Options(args, 0, Integer.MAX_VALUE);
opt.getSet().addOption("h", Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("v", Multiplicity.ZERO_OR_ONE);
@ -64,6 +65,8 @@ class Main {
opt.getSet().addOption("n", Separator.BLANK, Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("o", Separator.BLANK, Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("I", Separator.BLANK, Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("fw", Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("sc", Multiplicity.ZERO_OR_ONE);
if (!opt.check(false, false)) { // Print usage hints
System.err.println("Usage is: " + USAGE_STR);
throw new MalformedParametersException(opt.getCheckErrors());
@ -87,19 +90,18 @@ class Main {
fileAccess.outputPath = opt.getSet().getOption('o').getResultValue(0)
fileAccess.outputConfigurations.get(IFileSystemAccess.DEFAULT_OUTPUT)?.setOverrideExistingResources(true)
}
// #{'incl-out' -> false, 'src-out' -> false, 'gen-out' -> true}.forEach[p1, p2|
// if(opt.getSet().isSet(p1.substring(0, 1)))
// fileAccess.setOutputPath(p1, opt.getSet().getOption(p1.substring(0, 1)).getResultValue(0)+'/')
// else
// fileAccess.setOutputPath(p1, 'src-gen/')
// fileAccess.outputConfigurations.get(p1)?.setOverrideExistingResources(p2)
// ]
opt.getSet().getData().forEach [ String string |
if(verbose) println("Processing " + string);
val context = new RdlGeneratorContext => [cancelIndicator = CancelIndicator.NullImpl]
context.forceOverwrite= opt.getSet().isSet('f')
if(opt.getSet().isSet('n'))
context.namespace=opt.getSet().getOption('n').getResultValue(0)
context.generateFw=opt.getSet().isSet('fw')
context.generateSc=opt.getSet().isSet('sc')
opt.getSet().getData().forEach [ String fileName |
if(verbose) println("Processing " + fileName);
// Load the resource
val resourceSet = resourceSetProvider.get as XtextResourceSet
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
val resource = resourceSet.getResource(URI.createFileURI(string), true)
val resource = resourceSet.getResource(URI.createFileURI(fileName), true)
// Validate the resource
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
if (!issues.empty) {
@ -107,22 +109,10 @@ class Main {
issues.forEach[System.err.println(it)]
throw new ParseException("error validating " + resource.URI, issues.size)
}
val context = new RdlGeneratorContext => [cancelIndicator = CancelIndicator.NullImpl]
context.forceOverwrite= opt.getSet().isSet('f')
if(opt.getSet().isSet('n'))
context.namespace=opt.getSet().getOption('n').getResultValue(0)
generator.generate(resource, fileAccess, context)
if(verbose) println('Code generation for ' + string + ' finished')
try {
if(verbose) println('includes are in ' + fileAccess.getURI('', 'incl-out'))
} catch (Exception e) {
if(verbose) {
println('Code generation for ' + fileName + ' finished')
println('includes are in ' + fileAccess.getURI(''))
}
try {
if(verbose) println('sources are in ' + fileAccess.getURI('', 'src-out'))
} catch (Exception e) {
println('sources are in ' + fileAccess.getURI(''))
}
]

View File

@ -1,58 +0,0 @@
/*
* generated by Xtext 2.14.0
*/
package com.minres.rdl.generator
import com.google.inject.Inject
import com.google.inject.Provider
import com.minres.rdl.RDLStandaloneSetup
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtext.generator.GeneratorContext
import org.eclipse.xtext.generator.GeneratorDelegate
import org.eclipse.xtext.generator.JavaIoFileSystemAccess
import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.validation.CheckMode
import org.eclipse.xtext.validation.IResourceValidator
class Main {
def static main(String[] args) {
if (args.empty) {
System::err.println('Aborting: no path to EMF resource provided!')
return
}
val injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration
val main = injector.getInstance(Main)
main.runGenerator(args.get(0))
}
@Inject Provider<ResourceSet> resourceSetProvider
@Inject IResourceValidator validator
@Inject GeneratorDelegate generator
@Inject JavaIoFileSystemAccess fileAccess
def protected runGenerator(String string) {
// Load the resource
val set = resourceSetProvider.get
val resource = set.getResource(URI.createFileURI(string), true)
// Validate the resource
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
if (!issues.empty) {
issues.forEach[System.err.println(it)]
return
}
// Configure and start the generator
fileAccess.outputPath = 'src-gen/'
val context = new GeneratorContext => [
cancelIndicator = CancelIndicator.NullImpl
]
generator.generate(resource, fileAccess, context)
System.out.println('Code generation finished.')
}
}

View File

@ -22,12 +22,12 @@ class ModuleGenerator extends RdlBaseGenerator {
override generateHeader(String namespace){
if(componentDefinition.type!=ComponentDefinitionType.REGFILE) return ''
val addrMaps = componentDefinition.eResource.resourceSet.allContents
.filter[ it instanceof ComponentDefinition]
.map[it as ComponentDefinition]
.filter[it.type == ComponentDefinitionType.ADDRMAP]
.filter[def | def.instantiations.filter[it.componentRef==componentDefinition].size>0]
if(addrMaps.size==0) return ''
// val addrMaps = componentDefinition.eResource.resourceSet.allContents
// .filter[ it instanceof ComponentDefinition]
// .map[it as ComponentDefinition]
// .filter[it.type == ComponentDefinitionType.ADDRMAP]
// .filter[def | def.instantiations.filter[it.componentRef==componentDefinition].size>0]
// if(addrMaps.size==0) return ''
'''
/*
* Copyright (c) 2019 -2022 MINRES Technologies GmbH
@ -35,11 +35,13 @@ class ModuleGenerator extends RdlBaseGenerator {
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _«namespace.toUpperCase»_«componentDefinition.effectiveName.toUpperCase»_H_
#define _«namespace.toUpperCase»_«componentDefinition.effectiveName.toUpperCase»_H_
#pragma once
#include <scc/tlm_target.h>
namespace «namespace» {
«FOR ns : namespace.split('::')»
namespace «ns» {
«ENDFOR»
namespace gen {
class «componentDefinition.effectiveName»_regs;
}
@ -58,7 +60,9 @@ class ModuleGenerator extends RdlBaseGenerator {
std::unique_ptr<gen::«componentDefinition.effectiveName»_regs> regs;
};
} /* namespace «namespace» */
«FOR ns : namespace.split('::').reverse»
} // namespace «ns»
«ENDFOR»
#endif /* _«namespace.toUpperCase»_«componentDefinition.effectiveName.toUpperCase»_H_ */
'''
@ -66,12 +70,12 @@ class ModuleGenerator extends RdlBaseGenerator {
override generateSource(String namespace) {
if(componentDefinition.type!=ComponentDefinitionType.REGFILE) return ''
val addrMaps = componentDefinition.eResource.resourceSet.allContents
.filter[ it instanceof ComponentDefinition]
.map[it as ComponentDefinition]
.filter[it.type == ComponentDefinitionType.ADDRMAP]
.filter[def | def.instantiations.filter[it.componentRef==componentDefinition].size>0]
if(addrMaps.size==0) return ''
// val addrMaps = componentDefinition.eResource.resourceSet.allContents
// .filter[ it instanceof ComponentDefinition]
// .map[it as ComponentDefinition]
// .filter[it.type == ComponentDefinitionType.ADDRMAP]
// .filter[def | def.instantiations.filter[it.componentRef==componentDefinition].size>0]
// if(addrMaps.size==0) return ''
'''
/*
* Copyright (c) 2019 -2022 MINRES Technologies GmbH
@ -84,7 +88,9 @@ class ModuleGenerator extends RdlBaseGenerator {
#include <scc/utilities.h>
namespace «namespace» {
«FOR ns : namespace.split('::')»
namespace «ns» {
«ENDFOR»
SC_HAS_PROCESS(«componentDefinition.effectiveName»);// NOLINT
«componentDefinition.effectiveName»::«componentDefinition.effectiveName»(sc_core::sc_module_name nm)
@ -119,7 +125,9 @@ class ModuleGenerator extends RdlBaseGenerator {
}
}
} /* namespace «namespace» */
«FOR ns : namespace.split('::').reverse»
} // namespace «ns»
«ENDFOR»
'''
}

View File

@ -12,28 +12,28 @@ import org.eclipse.xtext.generator.IGeneratorContext
import static extension com.minres.rdl.RdlUtil.*
import java.util.Map
/**
* Generates code from your model files on save.
*
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
*/
class RDLGenerator extends AbstractGenerator {
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
val force = if(context instanceof RdlGeneratorContext) context.forceOverwrite else false
val namespace = if(context instanceof RdlGeneratorContext) context.namespace else "sysc"
val genFW = if(context instanceof RdlGeneratorContext) context.generateFw else true
val genSC = if(context instanceof RdlGeneratorContext) context.generateSc else true
resource.resourceSet.allContents.filter[ it instanceof ComponentDefinition].map[it as ComponentDefinition].forEach[
val genMap = it.fileGenerator
if(genMap!==null) genMap.forEach[p1, gen |
val header = gen.generateHeader(namespace)
val inclFileName = p1+'/'+it.effectiveName+'.h'
val inclCfg = fsa.outputConfig('incl-out')
if((force || !fsa.isFile(inclFileName, inclCfg) || gen.overwrite) && header!==null && header.length>0)
fsa.generateFile(inclFileName, inclCfg, header)
val source = gen.generateSource(namespace)
val srcFileName = p1+'/'+it.effectiveName+'.cpp'
val srcCfg = fsa.outputConfig('src-out')
if((force || !fsa.isFile(srcFileName, srcCfg) || gen.overwrite) && source!==null && source.length>0)
fsa.generateFile(srcFileName, srcCfg, source)
if((p1=='fw' && genFW) || (p1!='fw' && genSC)) {
val header = gen.generateHeader(namespace)
val prefix = if(p1=="fw") 'fw-' else 'sc-'
val inclFileName = p1+'/'+it.effectiveName+'.h'
val inclCfg = fsa.outputConfig(prefix+'incl-out')
if((force || !fsa.isFile(inclFileName, inclCfg) || gen.overwrite) && header!==null && header.length>0)
fsa.generateFile(inclFileName, inclCfg, header)
val source = gen.generateSource(namespace)
val srcFileName = p1+'/'+it.effectiveName+'.cpp'
val srcCfg = fsa.outputConfig(prefix+'src-out')
if((force || !fsa.isFile(srcFileName, srcCfg) || gen.overwrite) && source!==null && source.length>0)
fsa.generateFile(srcFileName, srcCfg, source)
}
]
]
}

View File

@ -1,8 +1,26 @@
package com.minres.rdl.generator
import org.eclipse.xtext.generator.GeneratorContext
import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.generator.IGeneratorContext
class RdlGeneratorContext implements IGeneratorContext {
class RdlGeneratorContext extends GeneratorContext {
public boolean forceOverwrite = false
public String namespace ="scc"
public String namespace ="sysc"
public CancelIndicator cancelIndicator;
public boolean generateFw = true;
public String fwPathModifier = ""
public boolean generateSc = true;
public String scPathModifier =""
override getCancelIndicator() {
return cancelIndicator
}
}

View File

@ -32,8 +32,7 @@ class RegfileGenerator extends RdlBaseGenerator{
*
*/
#ifndef _«namespace.toUpperCase»_GEN_«componentDefinition.effectiveName.toUpperCase»_H_
#define _«namespace.toUpperCase»_GEN_«componentDefinition.effectiveName.toUpperCase»_H_
#pragma once
#include <scc/utilities.h>
#include <util/bit_field.h>
@ -45,7 +44,9 @@ class RegfileGenerator extends RdlBaseGenerator{
«ENDIF»
«ENDFOR»
namespace «namespace» {
«FOR ns : namespace.split('::')»
namespace «ns» {
«ENDFOR»
namespace gen {
class «componentDefinition.effectiveName»_regs :
@ -128,7 +129,9 @@ class RegfileGenerator extends RdlBaseGenerator{
void registerResources(scc::tlm_target<BUSWIDTH>& target, uint64_t offset=0);
};
} // namespace gen
} // namespace «namespac
«FOR ns : namespace.split('::').revers
} // namespace «ns»
«ENDFOR»
//////////////////////////////////////////////////////////////////////////////
// member functions
//////////////////////////////////////////////////////////////////////////////