"""
=============
Module common
=============
Class containing common properties and methods for all language dependent modules
Initially written by Marko Kosunen, 28.10.2022
"""
import os
from thesdk import *
from rtl import *
from copy import deepcopy
[docs]
class module_common(thesdk):
def __init__(self, **kwargs):
'''Parameters
----------
**kwargs :
file: str
Verilog file containing the module
name: str
Name of the module
instname: str, self.name
Name of the instance
lang: str, language of the module 'sv' | 'vhdl' not supported yet.
Default: 'sv'
'''
self.file=kwargs.get('file','')
self._name=kwargs.get('name','')
self._instname=kwargs.get('instname',self.name)
self._lang=kwargs.get('lang',self.lang)
if not self.file and not self._name:
self.print_log(type='F', msg='Either name or file must be defined')
@property
def lang(self):
'''Description language used.
Default: `sv`
'''
if not hasattr(self,'_lang'):
self._lang='sv'
return self._lang
@lang.setter
def lang(self,value):
self._lang=value
@property
def name(self):
"""Name of the module. Derived from the file name.
"""
if not self._name:
self._name=os.path.splitext(os.path.basename(self.file))[0]
return self._name
@property
def instname(self):
"""Name of the instance, when instantiated inside other module.
Default: `self.name_DUT`
"""
if not hasattr(self,'_instname'):
self._instname=self.name+'_DUT'
return self._instname
@instname.setter
def instname(self,value):
self._instname=value
@property
@abstractmethod
def ios(self):
'''Connector bundle containing connectors for all module IOS.
All the IOs are connected to signal connectors that
have the same name than the IOs. This is due to fact the we have decided
that all signals are connectors.
'''
return self.langmodule.ios
@property
@abstractmethod
def parameters(self):
'''Parameters of the verilog module. Bundle of values of type string.
'''
return self.langmodule.parameters
@parameters.setter
def parameters(self,value):
self.langmodule.parameters.Members=deepcopy(value)
@property
@abstractmethod
def contents(self):
'''Contents of the module. String containing the Verilog code after
the module definition.
'''
return self.langmodule.contents
@property
@abstractmethod
def io_signals(self):
'''Bundle containing the signal connectors for IO connections.
'''
return self.langmodule.io_signals
@property
@abstractmethod
def definition(self):
'''Module definition part extracted for the file. Contains parameters and
IO definitions.
'''
return self.langmodule.definition
#Methods
[docs]
@abstractmethod
def export(self,**kwargs):
'''Method to export the module to a given file.
Parameters
----------
**kwargs :
force: Bool
'''
self.langmodule.export(force=kwargs.get('force'))
# Instance is defined through the io_signals
# Therefore it is always regenerated
@property
def verilog_instance(self):
'''Instantioation string of the module/entity for use inside of verilog modules.
'''
#First we write the parameter section
if self.parameters.Members:
parameters=''
first=True
for name, val in self.parameters.Members.items():
if first:
parameters='#(\n .%s(%s)' %(name,name)
first=False
else:
parameters=parameters+',\n .%s(%s)' %(name,name)
parameters=parameters+'\n)'
self._verilog_instance='%s %s %s' %(self.name, parameters, self.instname)
else:
self._verilog_instance='%s %s ' %(self.name, self.instname)
first=True
# Then we write the IOs
if self.ios.Members:
for ioname, io in self.ios.Members.items():
if first:
self._verilog_instance=self._verilog_instance+'(\n'
first=False
else:
self._verilog_instance=self._verilog_instance+',\n'
if io.cls in [ 'input', 'output', 'inout' ]:
self._verilog_instance=(self._verilog_instance+
(' .%s(%s)' %(io.name, io.connect.name)))
else:
self.print_log(type='F', msg='Assigning signal direction %s to verilog module IO.' %(io.cls))
self._verilog_instance=self._verilog_instance+('\n)')
self._verilog_instance=self._verilog_instance+(';\n')
return self._verilog_instance
@property
def vhdl_instance(self):
'''Instantioation string of the module/entity for use inside of vhdl entities.
'''
#First we write the parameter section
if self.parameters.Members:
parameters=''
first=True
for name, val in self.parameters.Members.items():
if first:
parameters='generic map(\n %s => %s' %(name,name)
first=False
else:
parameters=parameters+',\n %s > %s' %(name,name)
parameters=parameters+'\n)'
self._vhdl_instance='%s is entity work.%s\n%s\n' %(self.instname, self.name, parameters)
else:
self._vhdl_instance='%s : entity work.%s\n ' %(self.instname, self.name)
first=True
# Then we write the IOs
if self.ios.Members:
for ioname, io in self.ios.Members.items():
if first:
self._vhdl_instance=self._vhdl_instance+'port map(\n'
first=False
else:
self._vhdl_instance=self._vhdl_instance+',\n'
if io.cls in [ 'input', 'output', 'inout' ]:
self._vhdl_instance=(self._vhdl_instance+
(' %s => %s' %(io.name, io.connect.name)))
else:
self.print_log(type='F', msg='Assigning signal direction %s to VHDL entity IO.' %(io.cls))
self._vhdl_instance=self._vhdl_instance+('\n )')
self._vhdl_instance=self._vhdl_instance+(';\n')
return self._vhdl_instance
if __name__=="__main__":
pass