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 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: // //////////////////////////////////////////////////////////////////////////////// #ifndef _«componentDefinition.name.toUpperCase»_H_ #define _«componentDefinition.name.toUpperCase»_H_ #include #include #include #include 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.filter[it.range===null].map['r_'+it.name].join(', ')»; «FOR componentInstance : instantiation.componentInstances.filter[it.range!==null]» std::array r_«componentInstance.name»; «ENDFOR» «ENDIF» «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(', ')»; «FOR componentInstance : instantiation.componentInstances.filter[it.range!==null]» std::array<«instantiation.component.effectiveName»_t, «componentInstance.range.absSize»> r_«componentInstance.name»; «ENDFOR» «ENDIF» «ENDIF» «ENDFOR» // register declarations «FOR instantiation : componentDefinition.instantiations» «FOR instance : instantiation.componentInstances» «IF instance.range===null» «IF instantiation.isFilledByField» sysc::sc_register «instance.name»; «ENDIF» «IF !instantiation.isFilledByField» sysc::sc_register<«instantiation.component.effectiveName»_t> «instance.name»; «ENDIF» «ENDIF» «IF instance.range!==null» «IF instantiation.isFilledByField» sysc::sc_register_indexed<«instantiation.size»_t, «instance.range.absSize»> «instance.name»; «ENDIF» «IF !instantiation.isFilledByField» sysc::sc_register_indexed<«instantiation.component.effectiveName»_t, «instance.range.absSize»> «instance.name»; «ENDIF» «ENDIF» «ENDFOR» «ENDFOR» public: «componentDefinition.name»(sc_core::sc_module_name nm); template void registerResources(sysc::tlm_target& 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 inline void sysc::«componentDefinition.name»::registerResources(sysc::tlm_target& target) { «FOR instantiation : componentDefinition.instantiations» «FOR instance : instantiation.componentInstances» target.addResource(«instance.name», 0x«Long.toHexString((instance.address as IntegerWithRadix).value)»UL); «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] } 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 } }