mirror of
https://github.com/Minres/RDL-Editor.git
synced 2025-07-01 21:43:26 +02:00
Changed grammar and added code generator
* changed the grammar to ease code generation * added a code generator and a standalone setup to generate SystemC code using SC-Components lib
This commit is contained in:
@ -36,7 +36,12 @@ Workflow {
|
||||
fragment = scoping.ImportNamespacesScopingFragment2 auto-inject {}
|
||||
fragment = exporting.SimpleNamesFragment2 auto-inject {}
|
||||
|
||||
|
||||
parserGenerator = {
|
||||
options = {
|
||||
backtrack = true
|
||||
}
|
||||
}
|
||||
|
||||
serializer = {
|
||||
generateStub = false
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ generate rdl "http://www.minres.com/rdl/RDL"
|
||||
Root:
|
||||
(
|
||||
includes+=Include |
|
||||
componentDefinitions+=ComponentDefinition |
|
||||
enumDefinitions+=EnumDefinition |
|
||||
namedInstantiations+=NamedInstantiation |
|
||||
propertyAssignments+=PropertyAssignment |
|
||||
propertyDefinitions+=PropertyDefinition
|
||||
)*
|
||||
componentDefinitions+=ComponentDefinition';'|
|
||||
enumDefinitions+=EnumDefinition ';'|
|
||||
instantiations+=Instantiation ';'|
|
||||
propertyAssignments+=PropertyAssignment ';'|
|
||||
propertyDefinitions+=PropertyDefinition ';'
|
||||
) *
|
||||
;
|
||||
|
||||
Include:
|
||||
@ -48,25 +48,21 @@ enum PropertyComponent:
|
||||
ComponentDefinition:
|
||||
type=ComponentDefinitionType name=ID?
|
||||
'{'
|
||||
( componentDefinitions+=ComponentDefinition
|
||||
| namedInstantiations+=NamedInstantiation
|
||||
| propertyAssignments+=PropertyAssignment
|
||||
| enumDefinitions+=EnumDefinition
|
||||
)* '}' immediateInstantiation=ImmediateInstantiation? ';'
|
||||
( componentDefinitions+=ComponentDefinition ';'
|
||||
| instantiations+=Instantiation ';'
|
||||
| propertyAssignments+=PropertyAssignment ';'
|
||||
| enumDefinitions+=EnumDefinition ';'
|
||||
)* '}'
|
||||
;
|
||||
|
||||
enum ComponentDefinitionType:
|
||||
SIGNAL="signal" | ADDRMAP="addrmap" | REGFILE="regfile" | REG="reg" | FIELD="field"
|
||||
;
|
||||
|
||||
// Instantiation: NamedInstantiation|ImmediateInstantiation;
|
||||
|
||||
NamedInstantiation:
|
||||
(external?="external")? (internal?="internal")? ("alias" alias=ID)? component=[ComponentDefinition] componentInstances+=ComponentInstance (',' componentInstances+=ComponentInstance)* ';'
|
||||
;
|
||||
|
||||
ImmediateInstantiation:
|
||||
(external?="external")? componentInstances+=ComponentInstance (',' componentInstances+=ComponentInstance)*
|
||||
Instantiation:
|
||||
(
|
||||
instanceType=EnumInstanceType? ("alias" alias=ID)? componentRef=[ComponentDefinition]| component=ComponentDefinition instanceType=EnumInstanceType?
|
||||
) componentInstances+=ComponentInstance (',' componentInstances+=ComponentInstance)*
|
||||
;
|
||||
|
||||
ComponentInstance:
|
||||
@ -82,7 +78,7 @@ ComponentInstance:
|
||||
;
|
||||
|
||||
Range:
|
||||
'[' (start=NUM ':' end=NUM | size=NUM) ']'
|
||||
'[' (left=NUM ':' right=NUM | size=NUM) ']'
|
||||
;
|
||||
|
||||
PropertyAssignment:
|
||||
@ -94,27 +90,27 @@ DefaultProperyAssignment:
|
||||
;
|
||||
|
||||
ExplicitPropertyAssignment :
|
||||
modifier=PropertyModifier name=Property ';' |
|
||||
name=Property ('=' rhs=PropertyAssignmentRhs)? ';'
|
||||
modifier=PropertyModifier name=Property |
|
||||
name=Property ('=' rhs=PropertyAssignmentRhs)?
|
||||
;
|
||||
|
||||
PostPropertyAssignment:
|
||||
(instance=HierInstanceRef '->' (propertyEnum=Property | property=[PropertyDefinition]) |
|
||||
property=[PropertyDefinition] ) ('=' rhs=PropertyAssignmentRhs)? ';'
|
||||
property=[PropertyDefinition] ) ('=' rhs=PropertyAssignmentRhs)?
|
||||
;
|
||||
|
||||
InstancePropertyRef:
|
||||
instance=InstanceRef ('->' (propertyEnum=Property | property=[PropertyDefinition]))?
|
||||
;
|
||||
|
||||
// unused rules to infer inheritance
|
||||
// unused rule to infer inheritance
|
||||
Entity:
|
||||
ComponentInstance|EnumDefinition|PropertyDefinition
|
||||
;
|
||||
|
||||
InstanceRef:
|
||||
instance=[Entity] ( "." tail=HierInstanceRef)?
|
||||
;
|
||||
;
|
||||
|
||||
HierInstanceRef returns InstanceRef:
|
||||
instance=[ComponentInstance] ( "." tail=HierInstanceRef)?
|
||||
@ -358,7 +354,7 @@ enum PropertyModifier:
|
||||
;
|
||||
|
||||
EnumDefinition:
|
||||
"enum" name=ID body=EnumBody ';'
|
||||
"enum" name=ID body=EnumBody
|
||||
;
|
||||
|
||||
EnumBody:
|
||||
@ -373,6 +369,9 @@ EnumProperty:
|
||||
( name='name' '=' value=STR | name='desc' '=' value=STR ) ';'
|
||||
;
|
||||
|
||||
EnumInstanceType:
|
||||
EXTERNAL="external" | INTERNAL="internal"
|
||||
;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// the terminals
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.minres.rdl.generator
|
||||
|
||||
import com.minres.rdl.generator.RdlBaseGenerator
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
|
||||
class AddrmapGenerator extends RdlBaseGenerator {
|
||||
|
||||
val ComponentDefinition componentDefinition
|
||||
|
||||
new(ComponentDefinition definition) {
|
||||
componentDefinition=definition
|
||||
}
|
||||
|
||||
override generateHeader() {'''
|
||||
#ifndef _E300_PLAT_MAP_H_
|
||||
#define _E300_PLAT_MAP_H_
|
||||
// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
|
||||
const std::array<sysc::target_memory_map_entry<32>, 3> e300_plat_map = {{
|
||||
{&i_gpio, 0x10012000, 0x1000},
|
||||
{&i_uart, 0x10013000, 0x1000},
|
||||
{&i_spi, 0x10014000, 0x1000}
|
||||
}};
|
||||
|
||||
#endif /* _E300_PLAT_MAP_H_ */
|
||||
'''
|
||||
}
|
||||
|
||||
override generateSource() {
|
||||
''
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package com.minres.rdl.generator
|
||||
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Provider
|
||||
import com.minres.rdl.RDLStandaloneSetup
|
||||
import java.lang.reflect.MalformedParametersException
|
||||
import java.util.ArrayList
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.emf.mwe.utils.ProjectMapping
|
||||
import org.eclipse.emf.mwe.utils.StandaloneSetup
|
||||
import org.eclipse.xtext.generator.GeneratorContext
|
||||
import org.eclipse.xtext.generator.GeneratorDelegate
|
||||
import org.eclipse.xtext.generator.JavaIoFileSystemAccess
|
||||
import org.eclipse.xtext.resource.XtextResource
|
||||
import org.eclipse.xtext.resource.XtextResourceSet
|
||||
import org.eclipse.xtext.util.CancelIndicator
|
||||
import org.eclipse.xtext.validation.CheckMode
|
||||
import org.eclipse.xtext.validation.IResourceValidator
|
||||
import java.text.ParseException
|
||||
|
||||
class Main {
|
||||
static class Option {
|
||||
String flag
|
||||
String value
|
||||
def Option(String flag, String value) {
|
||||
this.flag = flag
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
|
||||
def static main(String[] args) {
|
||||
if (args.empty) {
|
||||
System::err.println('Aborting: no path to EMF resource provided!')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration
|
||||
injector.getInstance(Main).run(args)
|
||||
} catch(MalformedParametersException e){
|
||||
print("Command line error "+e.message)
|
||||
} catch(IllegalArgumentException e){
|
||||
print("generation error "+e.message)
|
||||
e.printStackTrace
|
||||
} catch(ParseException e){
|
||||
print("parse problem "+e.message+" ("+ e.errorOffset+")")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Inject Provider<ResourceSet> resourceSetProvider
|
||||
|
||||
@Inject IResourceValidator validator
|
||||
|
||||
@Inject GeneratorDelegate generator
|
||||
|
||||
@Inject JavaIoFileSystemAccess fileAccess
|
||||
|
||||
var optsList = new ArrayList<Option>();
|
||||
var argsList = new ArrayList<String>()
|
||||
val shortOptMap = newLinkedHashMap('i' -> 'incl-out', 's' -> 'src-out')
|
||||
|
||||
def protected parseOptions(String[] args) {
|
||||
for (arg : args) {
|
||||
switch (arg) {
|
||||
case arg.startsWith('--'): {
|
||||
if (arg.length < 3)
|
||||
throw new MalformedParametersException("not a valid argument: " + arg);
|
||||
val res = arg.substring(2).split('=')
|
||||
var opt = new Option()
|
||||
val longOpt = shortOptMap.values.findFirst[String s|s == res.get(0)]
|
||||
if(longOpt === null) throw new IllegalArgumentException("unknown option: " + arg);
|
||||
opt.flag = res.get(0)
|
||||
if (res.size == 2)
|
||||
opt.value = res.get(1)
|
||||
optsList += opt
|
||||
}
|
||||
case arg.startsWith('-'): {
|
||||
if (arg.length < 2)
|
||||
throw new MalformedParametersException("not a valid argument: " + arg);
|
||||
// -opt
|
||||
var res = arg.substring(1).split('=')
|
||||
val longOpt = shortOptMap.get(res.get(0))
|
||||
if(longOpt === null) throw new MalformedParametersException("unknown option: " + arg);
|
||||
var opt = new Option()
|
||||
opt.flag = longOpt
|
||||
if (res.size == 2)
|
||||
opt.value = res.get(1)
|
||||
optsList += opt
|
||||
|
||||
}
|
||||
default: {
|
||||
argsList += arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def run(String[] args){
|
||||
parseOptions(args)
|
||||
val repo = optsList.findFirst[it.flag == "repository"]
|
||||
if(repo!==null){
|
||||
val projectMapping = new ProjectMapping
|
||||
projectMapping.projectName = "RDL Repository"
|
||||
projectMapping.path = repo.value
|
||||
new StandaloneSetup().addProjectMapping(projectMapping)
|
||||
}
|
||||
argsList.forEach[runGenerator(it)]
|
||||
}
|
||||
|
||||
def protected runGenerator(String string) {
|
||||
// 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)
|
||||
// Validate the resource
|
||||
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
|
||||
if (!issues.empty) {
|
||||
System.err.println("Error validating "+resource.URI)
|
||||
issues.forEach[System.err.println(it)]
|
||||
throw new ParseException("error validating "+resource.URI, issues.size)
|
||||
}
|
||||
// Configure and start the generator
|
||||
fileAccess.outputPath = 'src-gen/'
|
||||
optsList.filter[it.flag.matches('.*-out')].forEach[fileAccess.setOutputPath(it.flag, it.value)]
|
||||
fileAccess.outputConfigurations.get('src-out')?.setOverrideExistingResources(true)
|
||||
|
||||
val context = new GeneratorContext => [ cancelIndicator = CancelIndicator.NullImpl ]
|
||||
generator.generate(resource, fileAccess, context)
|
||||
|
||||
System.out.print('Code generation for '+string +' finished, ')
|
||||
try{
|
||||
System.out.print('includes are in '+fileAccess.getURI('', 'incl-out')+', ')
|
||||
}catch(Exception e){
|
||||
System.out.print('includes are in '+fileAccess.getURI('')+', ')
|
||||
}
|
||||
try{
|
||||
System.out.println('sources are in '+fileAccess.getURI('', 'src-out')+', ')
|
||||
}catch(Exception e){
|
||||
System.out.println('sources are in '+fileAccess.getURI('')+', ')
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
*/
|
||||
package com.minres.rdl.generator
|
||||
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
import com.minres.rdl.rdl.ComponentDefinitionType
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import org.eclipse.xtext.generator.AbstractGenerator
|
||||
import org.eclipse.xtext.generator.IFileSystemAccess2
|
||||
@ -16,10 +18,29 @@ import org.eclipse.xtext.generator.IGeneratorContext
|
||||
class RDLGenerator extends AbstractGenerator {
|
||||
|
||||
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
|
||||
// fsa.generateFile('greetings.txt', 'People to greet: ' +
|
||||
// resource.allContents
|
||||
// .filter(Greeting)
|
||||
// .map[name]
|
||||
// .join(', '))
|
||||
}
|
||||
}
|
||||
resource.resourceSet.allContents.filter[ it instanceof ComponentDefinition].map[it as ComponentDefinition].forEach[
|
||||
val gen = it.fileGenerator
|
||||
if(gen!==null){
|
||||
val header = gen.generateHeader
|
||||
if(header!==null && header.length>0) fsa.generateFile(it.name+'.h', fsa.outputConfig('incl-out'), header)
|
||||
val source = gen.generateSource
|
||||
if(source!==null && source.length>0) fsa.generateFile(it.name+'.cpp', fsa.outputConfig('src-out'), source)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def RdlBaseGenerator fileGenerator(ComponentDefinition definition){
|
||||
switch(definition.type){
|
||||
case ComponentDefinitionType.REGFILE: new RegfileGenerator(definition)
|
||||
case ComponentDefinitionType.ADDRMAP: new AddrmapGenerator(definition)
|
||||
default: null
|
||||
}
|
||||
}
|
||||
|
||||
def String outputConfig(IFileSystemAccess2 fsa, String string){
|
||||
var output_config = string
|
||||
try {fsa.getURI("", output_config)} catch (Exception e) {output_config ='DEFAULT_OUTPUT'}
|
||||
return output_config
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
package com.minres.rdl.generator
|
||||
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
import com.minres.rdl.rdl.ExplicitPropertyAssignment
|
||||
import com.minres.rdl.rdl.PropertyAssignment
|
||||
import com.minres.rdl.rdl.PropertyEnum
|
||||
import com.minres.rdl.IntegerWithRadix
|
||||
import com.minres.rdl.rdl.Instantiation
|
||||
import com.minres.rdl.rdl.PropertyAssignmentRhs
|
||||
import com.minres.rdl.rdl.RValue
|
||||
import com.minres.rdl.rdl.RValueConstant
|
||||
import com.minres.rdl.rdl.InstancePropertyRef
|
||||
import com.minres.rdl.rdl.ComponentDefinitionType
|
||||
|
||||
abstract class RdlBaseGenerator {
|
||||
def long accessWidth(ComponentDefinition definition){
|
||||
var size = 32L
|
||||
val pa = definition.propertyAssignments.findFirst[PropertyAssignment pa |
|
||||
pa instanceof ExplicitPropertyAssignment && (pa as ExplicitPropertyAssignment).name==PropertyEnum.ACCESSWIDTH
|
||||
]
|
||||
if(pa !== null){
|
||||
val sz = new IntegerWithRadix((pa as ExplicitPropertyAssignment).rhs.effectiveValue)
|
||||
size=sz.value
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
def long getSize(Instantiation instantiation){
|
||||
val componentDef= instantiation.definingComponent
|
||||
switch (componentDef.type) {
|
||||
case ComponentDefinitionType.REG: {
|
||||
val pa = componentDef.propertyAssignments.findFirst[PropertyAssignment pa |
|
||||
pa instanceof ExplicitPropertyAssignment && (pa as ExplicitPropertyAssignment).name==PropertyEnum.REGWIDTH
|
||||
]
|
||||
if(pa !== null){
|
||||
val sz = new IntegerWithRadix((pa as ExplicitPropertyAssignment).rhs.effectiveValue)
|
||||
return sz.value
|
||||
}
|
||||
return 32L
|
||||
}
|
||||
case ComponentDefinitionType.FIELD:{
|
||||
val pa = componentDef.propertyAssignments.findFirst[PropertyAssignment pa |
|
||||
pa instanceof ExplicitPropertyAssignment && (pa as ExplicitPropertyAssignment).name==PropertyEnum.FIELDWIDTH
|
||||
]
|
||||
if(pa !== null){
|
||||
val sz = new IntegerWithRadix((pa as ExplicitPropertyAssignment).rhs.effectiveValue)
|
||||
return sz.value
|
||||
}
|
||||
return 1L
|
||||
}
|
||||
default: {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def String effectiveName(ComponentDefinition definition){
|
||||
if(definition.name!==null){
|
||||
definition.name
|
||||
} else{
|
||||
val pa = definition.propertyAssignments.findFirst[PropertyAssignment pa |
|
||||
pa instanceof ExplicitPropertyAssignment && (pa as ExplicitPropertyAssignment).name==PropertyEnum.NAME
|
||||
]
|
||||
(pa as ExplicitPropertyAssignment).rhs.effectiveValue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def String effectiveValue(PropertyAssignmentRhs rhs){
|
||||
if(rhs.value!== null)
|
||||
rhs.value.effectiveValue
|
||||
else if(rhs.instPropRef!==null)
|
||||
rhs.instPropRef.effectiveValue
|
||||
else if(rhs.enumRef!==null)
|
||||
rhs.enumRef.name
|
||||
}
|
||||
|
||||
def String effectiveValue(RValue rvalue){
|
||||
if(rvalue.str!==null){
|
||||
rvalue.str
|
||||
} else if(rvalue.^val!=RValueConstant.UNDEFINED)
|
||||
rvalue.^val.literal
|
||||
else if(rvalue.num!==null){
|
||||
val num = rvalue.num as IntegerWithRadix
|
||||
num.toString
|
||||
}
|
||||
}
|
||||
|
||||
def String effectiveValue(InstancePropertyRef ref){
|
||||
|
||||
}
|
||||
|
||||
def ComponentDefinition definingComponent(Instantiation instantiation){
|
||||
if(instantiation.componentRef!==null) instantiation.componentRef else instantiation.component
|
||||
}
|
||||
|
||||
def String generateHeader()
|
||||
|
||||
def String generateSource()
|
||||
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
package com.minres.rdl.generator
|
||||
|
||||
import com.minres.rdl.IntegerWithRadix
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
import com.minres.rdl.rdl.ComponentDefinitionType
|
||||
import com.minres.rdl.rdl.ComponentInstance
|
||||
import com.minres.rdl.rdl.Instantiation
|
||||
import java.util.Date
|
||||
|
||||
class RegfileGenerator extends RdlBaseGenerator{
|
||||
|
||||
val ComponentDefinition componentDefinition
|
||||
|
||||
new(ComponentDefinition definition) {
|
||||
componentDefinition=definition
|
||||
}
|
||||
|
||||
override String generateHeader()'''
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017, 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>
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _«componentDefinition.name.toUpperCase»_H_
|
||||
#define _«componentDefinition.name.toUpperCase»_H_
|
||||
|
||||
#include <sysc/utilities.h>
|
||||
#include <util/bit_field.h>
|
||||
#include <sysc/register.h>
|
||||
#include <sysc/tlm_target.h>
|
||||
|
||||
namespace sysc {
|
||||
|
||||
class «componentDefinition.name» :
|
||||
public sc_core::sc_module,
|
||||
public sysc::resetable
|
||||
{
|
||||
protected:
|
||||
// storage declarations
|
||||
«FOR cdef : componentDefinition.componentDefinitions»
|
||||
«IF cdef.type == ComponentDefinitionType.REG»
|
||||
BEGIN_BF_DECL(«cdef.effectiveName»+'_t'», uint«cdef»_t);
|
||||
«cdef.genFieldDeclarations»
|
||||
END_BF_DECL();
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
«FOR instantiation : componentDefinition.instantiations»
|
||||
«IF instantiation.componentRef !==null && instantiation.componentRef.type == ComponentDefinitionType.REG»
|
||||
«instantiation.componentRef.effectiveName»+'_t' «instantiation.componentInstances.map[it.name].join(', ')»;
|
||||
«ENDIF»
|
||||
«IF instantiation.component !== null && instantiation.component.type == ComponentDefinitionType.REG»
|
||||
«IF instantiation.isFilledByField»
|
||||
uint«instantiation.size»_t «instantiation.componentInstances.map['r_'+it.name].join(', ')»;
|
||||
«ENDIF»
|
||||
«IF !instantiation.isFilledByField»
|
||||
BEGIN_BF_DECL(«instantiation.component.effectiveName»_t, uint«instantiation.size»_t);
|
||||
«instantiation.definingComponent.genFieldDeclarations»
|
||||
END_BF_DECL() «instantiation.componentInstances.map['r_'+it.name].join(', ')»;
|
||||
«ENDIF»
|
||||
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
// register declarations
|
||||
«FOR instantiation : componentDefinition.instantiations»
|
||||
«FOR instance : instantiation.componentInstances»
|
||||
«IF instantiation.isFilledByField»
|
||||
sysc::sc_register<uint«instantiation.size»_t> «instance.name»;
|
||||
«ENDIF»
|
||||
«IF !instantiation.isFilledByField»
|
||||
sysc::sc_register<typename «instantiation.component.effectiveName»_t::StorageType> «instance.name»;
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
«ENDFOR»
|
||||
|
||||
public:
|
||||
«componentDefinition.name»(sc_core::sc_module_name nm);
|
||||
|
||||
template<unsigned BUSWIDTH=32>
|
||||
void registerResources(sysc::tlm_target<BUSWIDTH>& target);
|
||||
};
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// member functions
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline sysc::«componentDefinition.name»::«componentDefinition.name»(sc_core::sc_module_name nm)
|
||||
: sc_core::sc_module(nm)
|
||||
«FOR instantiation : componentDefinition.instantiations»
|
||||
«FOR instance : instantiation.componentInstances»
|
||||
, NAMED(«instance.name», r_«instance.name», 0, *this)
|
||||
«ENDFOR»
|
||||
«ENDFOR»
|
||||
{
|
||||
}
|
||||
|
||||
template<unsigned BUSWIDTH>
|
||||
inline void sysc::«componentDefinition.name»::registerResources(sysc::tlm_target<BUSWIDTH>& target) {
|
||||
«FOR instantiation : componentDefinition.instantiations»
|
||||
«FOR instance : instantiation.componentInstances»
|
||||
target.addResource(«instance.name», 0x«Long.toHexString((instance.address as IntegerWithRadix).value)»UL, 0x«Long.toHexString((instantiation.size+7)/8)»UL);
|
||||
«ENDFOR»
|
||||
«ENDFOR»
|
||||
}
|
||||
|
||||
#endif // _«componentDefinition.name.toUpperCase»_H_
|
||||
'''
|
||||
|
||||
def boolean isFilledByField(Instantiation instantiation){
|
||||
val fieldCount = instantiation.component.instanceCountOfType(ComponentDefinitionType.FIELD)
|
||||
if(fieldCount==1) {
|
||||
val instSize=instantiation.size
|
||||
val field = instantiation.component.instantiationsOfType(ComponentDefinitionType.FIELD).get(0)
|
||||
val inst = field.componentInstances.get(0)
|
||||
val range = inst.range
|
||||
if(range===null)
|
||||
return instSize==field.size
|
||||
if(range.size !== null)
|
||||
return instSize==(range.size as IntegerWithRadix).value
|
||||
else {
|
||||
val left=(range.left as IntegerWithRadix).value
|
||||
val right=(range.right as IntegerWithRadix).value
|
||||
val size = if(left>right) left-right+1 else right-left+1
|
||||
return instSize==size
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
def int instanceCountOfType(ComponentDefinition definition, ComponentDefinitionType type){
|
||||
definition.instantiationsOfType(type).map[it.componentInstances.size].reduce[p1, p2|p1+p1]
|
||||
}
|
||||
|
||||
def instantiationsOfType(ComponentDefinition definition, ComponentDefinitionType type){
|
||||
definition.instantiations.filter[it.definingComponent.type == type]
|
||||
}
|
||||
|
||||
override generateSource() {
|
||||
''
|
||||
}
|
||||
|
||||
def String genFieldDeclarations(ComponentDefinition componentDef){
|
||||
var i=0L;
|
||||
var res = ""
|
||||
for( Instantiation inst: componentDef.instantiations){
|
||||
for(ComponentInstance compInst : inst.componentInstances){
|
||||
if(compInst.range.size!==null){
|
||||
res+='''BF_FIELD(«compInst.name», «i», «(compInst.range.size as IntegerWithRadix).value»);
|
||||
'''
|
||||
i+=(compInst.range.size as IntegerWithRadix).value
|
||||
} else {
|
||||
val start =(compInst.range.left as IntegerWithRadix).value
|
||||
val end = (compInst.range.right as IntegerWithRadix).value
|
||||
res+='''BF_FIELD(«compInst.name», «end», «start-end+1»);
|
||||
'''
|
||||
i=Math.max(start, end)+1
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -4,19 +4,11 @@
|
||||
package com.minres.rdl.scoping
|
||||
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
import com.minres.rdl.rdl.ComponentInstance
|
||||
import com.minres.rdl.rdl.EnumDefinition
|
||||
import com.minres.rdl.rdl.InstanceRef
|
||||
import com.minres.rdl.rdl.NamedInstantiation
|
||||
import com.minres.rdl.rdl.Root
|
||||
import java.util.ArrayList
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EReference
|
||||
import org.eclipse.xtext.EcoreUtil2
|
||||
import org.eclipse.xtext.scoping.IScope
|
||||
import org.eclipse.xtext.scoping.Scopes
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import java.util.List
|
||||
|
||||
/**
|
||||
* This class contains custom scoping description.
|
||||
@ -67,47 +59,47 @@ class RDLScopeProvider extends AbstractRDLScopeProvider { //AbstractDeclarativeS
|
||||
return Scopes.scopeFor(compDefs)
|
||||
}
|
||||
|
||||
dispatch def IScope getScopeWithInstancesAndEnums(ComponentDefinition componentDef){
|
||||
var res = new ArrayList<ComponentInstance>()
|
||||
for(NamedInstantiation inst:componentDef.namedInstantiations)
|
||||
if(inst.componentInstances.size>0) res.addAll(inst.componentInstances)
|
||||
for(ComponentDefinition definition:componentDef.componentDefinitions)
|
||||
if(definition.immediateInstantiation!==null && definition.immediateInstantiation.componentInstances.size>0)
|
||||
res.addAll(definition.immediateInstantiation.componentInstances)
|
||||
return Scopes.scopeFor(res+componentDef.enumDefinitions, getScopeWithInstancesAndEnums(componentDef.eContainer))
|
||||
}
|
||||
// dispatch def IScope getScopeWithInstancesAndEnums(ComponentDefinition componentDef){
|
||||
// var res = new ArrayList<ComponentInstance>()
|
||||
// for(NamedInstantiation inst:componentDef.namedInstantiations)
|
||||
// if(inst.componentInstances.size>0) res.addAll(inst.componentInstances)
|
||||
// for(ComponentDefinition definition:componentDef.componentDefinitions)
|
||||
// if(definition.immediateInstantiation!==null && definition.immediateInstantiation.componentInstances.size>0)
|
||||
// res.addAll(definition.immediateInstantiation.componentInstances)
|
||||
// return Scopes.scopeFor(res+componentDef.enumDefinitions, getScopeWithInstancesAndEnums(componentDef.eContainer))
|
||||
// }
|
||||
//
|
||||
// dispatch def IScope getScopeWithInstancesAndEnums(Root root){
|
||||
// var res = new ArrayList<ComponentInstance>()
|
||||
// for(instantiation: root.namedInstantiations)
|
||||
// if(instantiation.componentInstances.size>0)
|
||||
// res.addAll(instantiation.componentInstances)
|
||||
// for(ComponentDefinition definition:root.componentDefinitions)
|
||||
// if(definition.immediateInstantiation!==null && definition.immediateInstantiation.componentInstances.size>0)
|
||||
// res.addAll(definition.immediateInstantiation.componentInstances)
|
||||
// var enums = EcoreUtil2.getAllContentsOfType(root, EnumDefinition)
|
||||
// for (incl : root.includes) {
|
||||
// val resource = EcoreUtil2.getResource(root.eResource, incl.importURI);
|
||||
// enums+=EcoreUtil2.getAllContentsOfType(resource.contents.head as Root, EnumDefinition)
|
||||
// }
|
||||
// return Scopes.scopeFor(res+enums)
|
||||
// }
|
||||
|
||||
dispatch def IScope getScopeWithInstancesAndEnums(Root root){
|
||||
var res = new ArrayList<ComponentInstance>()
|
||||
for(instantiation: root.namedInstantiations)
|
||||
if(instantiation.componentInstances.size>0)
|
||||
res.addAll(instantiation.componentInstances)
|
||||
for(ComponentDefinition definition:root.componentDefinitions)
|
||||
if(definition.immediateInstantiation!==null && definition.immediateInstantiation.componentInstances.size>0)
|
||||
res.addAll(definition.immediateInstantiation.componentInstances)
|
||||
var enums = EcoreUtil2.getAllContentsOfType(root, EnumDefinition)
|
||||
for (incl : root.includes) {
|
||||
val resource = EcoreUtil2.getResource(root.eResource, incl.importURI);
|
||||
enums+=EcoreUtil2.getAllContentsOfType(resource.contents.head as Root, EnumDefinition)
|
||||
}
|
||||
return Scopes.scopeFor(res+enums)
|
||||
}
|
||||
|
||||
private def Root root(EObject definition){
|
||||
var container = definition.eContainer
|
||||
while(!(container instanceof Root)) container=container.eContainer
|
||||
return container as Root
|
||||
}
|
||||
|
||||
private def ComponentDefinition componentDefinition(EObject obj){
|
||||
var container = obj.eContainer
|
||||
while(!(container instanceof Root)){
|
||||
if(container instanceof NamedInstantiation) return container.component
|
||||
if(container instanceof ComponentDefinition) return container
|
||||
container=container.eContainer
|
||||
}
|
||||
return null
|
||||
}
|
||||
// private def Root root(EObject definition){
|
||||
// var container = definition.eContainer
|
||||
// while(!(container instanceof Root)) container=container.eContainer
|
||||
// return container as Root
|
||||
// }
|
||||
//
|
||||
// private def ComponentDefinition componentDefinition(EObject obj){
|
||||
// var container = obj.eContainer
|
||||
// while(!(container instanceof Root)){
|
||||
//// if(container instanceof NamedInstantiation) return container.component
|
||||
// if(container instanceof ComponentDefinition) return container
|
||||
// container=container.eContainer
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
|
||||
// dispatch def Iterable<ComponentDefinition> allComponentDefinitions(ComponentDefinition definition){
|
||||
// return definition.componentDefinitions + definition.eContainer.allComponentDefinitions
|
||||
|
Reference in New Issue
Block a user