mirror of
https://github.com/Minres/RDL-Editor.git
synced 2025-07-01 21:43:26 +02:00
fix #1 'Generate register access functions for FW'
This commit is contained in:
@ -0,0 +1,86 @@
|
||||
package com.minres.rdl.generator
|
||||
|
||||
import com.minres.rdl.rdl.ComponentDefinition
|
||||
import com.minres.rdl.rdl.ComponentDefinitionType
|
||||
import java.util.Date
|
||||
|
||||
import static extension com.minres.rdl.RdlUtil.*
|
||||
|
||||
class FwAddrmapGenerator extends RdlBaseGenerator {
|
||||
|
||||
val ComponentDefinition componentDefinition
|
||||
|
||||
new(ComponentDefinition definition) {
|
||||
componentDefinition=definition
|
||||
}
|
||||
|
||||
val nameMap = newLinkedHashSet()
|
||||
|
||||
override generateHeader() {'''
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020, 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.effectiveName.toUpperCase»_MAP_H_
|
||||
#define _«componentDefinition.effectiveName.toUpperCase»_MAP_H_
|
||||
|
||||
«FOR instantiation : componentDefinition.instantiationsOfType(ComponentDefinitionType.REGFILE)»
|
||||
«IF instantiation.component !== null && !nameMap.contains(instantiation.component.name)»
|
||||
#include "«instantiation.component.name».h"«nameMap.add(instantiation.component.name)»
|
||||
«ENDIF»
|
||||
«IF instantiation.componentRef !== null && !nameMap.contains(instantiation.componentRef.name)»
|
||||
#include "«instantiation.componentRef.name».h"«nameMap.add(instantiation.componentRef.name)»
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
|
||||
|
||||
«FOR instantiation : componentDefinition.instantiationsOfType(ComponentDefinitionType.REGFILE)»
|
||||
«FOR instance : instantiation.componentInstances»
|
||||
«IF instantiation.component !== null»
|
||||
using «instance.name» = «instantiation.component.name»<«instance.addressValue»ULL>;
|
||||
«ENDIF»
|
||||
«IF instantiation.componentRef !== null»
|
||||
using «instance.name» = «instantiation.componentRef.name»<«instance.addressValue»ULL>;
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
«ENDFOR»
|
||||
|
||||
#endif /* _«componentDefinition.effectiveName.toUpperCase»_MAP_H_ */
|
||||
'''
|
||||
}
|
||||
|
||||
override generateSource() {
|
||||
''
|
||||
}
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
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
|
||||
import com.minres.rdl.rdl.Range
|
||||
|
||||
import static extension com.minres.rdl.RdlUtil.*
|
||||
|
||||
class FwRegfileGenerator extends RdlBaseGenerator{
|
||||
|
||||
val ComponentDefinition componentDefinition
|
||||
|
||||
new(ComponentDefinition definition) {
|
||||
componentDefinition=definition
|
||||
}
|
||||
|
||||
override String generateHeader()'''
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020, 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 <util/bit_field.h>
|
||||
#include <nonstd/span.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
template<size_t BASE_ADDR>
|
||||
struct «componentDefinition.name» {
|
||||
|
||||
«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»
|
||||
BEGIN_BF_DECL(«instantiation.component.effectiveName»_t, uint«instantiation.size»_t);
|
||||
«instantiation.definingComponent.genFieldDeclarations»
|
||||
END_BF_DECL() «instantiation.componentInstances.filter[it.range===null].map['r_'+it.name].join(', ')»;
|
||||
|
||||
«ENDIF»
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
// register access
|
||||
«FOR instantiation : componentDefinition.instantiations»
|
||||
«FOR instance : instantiation.componentInstances»
|
||||
«IF instance.range===null»
|
||||
«IF instantiation.isFilledByField»
|
||||
static inline uint«instantiation.size»_t& «instance.name»(){
|
||||
return *reinterpret_cast<«instance.name»_t*>(BASE_ADDR+«instance.addressValue»UL);
|
||||
}
|
||||
«ENDIF»
|
||||
«IF !instantiation.isFilledByField»
|
||||
static inline «instance.name»_t& «instance.name»(){
|
||||
return *reinterpret_cast<«instance.name»_t*>(BASE_ADDR+«instance.addressValue»UL);
|
||||
}
|
||||
«ENDIF»
|
||||
«ENDIF»
|
||||
«IF instance.range!==null»
|
||||
«IF instantiation.isFilledByField»
|
||||
static inline nonstd::span<uint«instantiation.size»_t, «instance.range.absSize»>& «instance.name»(){
|
||||
return *reinterpret_cast<nonstd::span<uint«instantiation.size»_t, «instance.range.absSize»>*>(BASE_ADDR+«instance.addressValue»UL);
|
||||
}
|
||||
«ENDIF»
|
||||
«IF !instantiation.isFilledByField»
|
||||
static inline nonstd::span<«instance.name»_t, «instance.range.absSize»>& «instance.name»(){
|
||||
return *reinterpret_cast<nonstd::span<«instance.name»_t, «instance.range.absSize»>*>(BASE_ADDR+«instance.addressValue»UL);
|
||||
}
|
||||
«ENDIF»
|
||||
«ENDIF»
|
||||
«ENDFOR»
|
||||
«ENDFOR»
|
||||
};
|
||||
|
||||
#endif // _«componentDefinition.name.toUpperCase»_H_
|
||||
'''
|
||||
|
||||
def long absSize(Range range){
|
||||
if(range.size!==null)
|
||||
return (range.size as IntegerWithRadix).value
|
||||
else
|
||||
return Math.abs((range.left as IntegerWithRadix).value - (range.right as IntegerWithRadix).value)+1
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -10,6 +10,7 @@ import org.eclipse.xtext.generator.AbstractGenerator
|
||||
import org.eclipse.xtext.generator.IFileSystemAccess2
|
||||
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.
|
||||
@ -20,20 +21,22 @@ class RDLGenerator extends AbstractGenerator {
|
||||
|
||||
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
|
||||
resource.resourceSet.allContents.filter[ it instanceof ComponentDefinition].map[it as ComponentDefinition].forEach[
|
||||
val gen = it.fileGenerator
|
||||
if(gen!==null){
|
||||
val genMap = it.fileGenerator
|
||||
if(genMap!==null) genMap.forEach[p1, gen |
|
||||
val header = gen.generateHeader
|
||||
if(header!==null && header.length>0) fsa.generateFile(it.effectiveName+'.h', fsa.outputConfig('incl-out'), header)
|
||||
if(header!==null && header.length>0)
|
||||
fsa.generateFile(p1+'/'+it.effectiveName+'.h', fsa.outputConfig('incl-out'), header)
|
||||
val source = gen.generateSource
|
||||
if(source!==null && source.length>0) fsa.generateFile(it.effectiveName+'.cpp', fsa.outputConfig('src-out'), source)
|
||||
}
|
||||
if(source!==null && source.length>0)
|
||||
fsa.generateFile(p1+'/'+it.effectiveName+'.cpp', fsa.outputConfig('src-out'), source)
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
def RdlBaseGenerator fileGenerator(ComponentDefinition definition){
|
||||
def Map<String, RdlBaseGenerator> fileGenerator(ComponentDefinition definition){
|
||||
switch(definition.type){
|
||||
case ComponentDefinitionType.REGFILE: new RegfileGenerator(definition)
|
||||
case ComponentDefinitionType.ADDRMAP: new AddrmapGenerator(definition)
|
||||
case ComponentDefinitionType.REGFILE: #{'vp' -> new RegfileGenerator(definition), 'fw' -> new FwRegfileGenerator(definition)}
|
||||
case ComponentDefinitionType.ADDRMAP: #{'vp' -> new AddrmapGenerator(definition), 'fw' -> new FwAddrmapGenerator(definition)}
|
||||
default: null
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user