Source code for rtl.testbench_common

"""
================
Testbench_common
================
Common properties and methods for RTL testbench creation and manipulation

Initially written by Marko Kosunen 20190108, marko.kosunen@aalto.fi
Refactored from 'testbench' by Marko Kosunen 20221119, marko.kosunen@aalto.fi

"""
import os
import sys
from thesdk import *
from rtl import *
from rtl.module import module
from rtl.sv.verilog_module import verilog_module
from rtl.vhdl.vhdl_entity import vhdl_entity

[docs] class testbench_common(module): ''' Testbench class. Extends `module` ''' def __init__(self, parent=None,**kwargs): '''Parameters ---------- parent: object, None (mandatory to define). TheSyDeKick parent entity object for this testbench. **kwargs : None ''' if parent==None: self.print_log(type='F', msg="Parent of testbench not given") else: self.parent=parent try: # The proper files are determined in rtl based on simulation model self.file = self.parent.simtb self._dutfile = self.parent.simdut except: self.print_log(type='F', msg="Testbench file definition failed") self._name='' self._parameters=Bundle() @property def rtl_timescale(self): return self.parent.rtl_timescale @property def rtl_timeprecision(self): return self.parent.rtl_timeprecision @property def lang(self): if not hasattr(self,'_lang'): self._lang=self.parent.lang return self._lang @lang.setter def lang(self,val): self._lang = val @property def connectors(self): if not hasattr(self,'_connectors'): self._connectors=rtl_connector_bundle(lang=self.lang) return self._connectors @connectors.setter def connectors(self,val): self._connectors = val @property def assignment_matchlist(self): if not hasattr(self,'_assignment_matchlist'): self._assignment_matchlist=[] return self._assignment_matchlist @assignment_matchlist.setter def assignment_matchlist(self,val): self._assignment_matchlist = val @property def dut_instance(self): """RTL module parsed from the verilog or VHDL file of the parent depending on `parent.model` """ if not hasattr(self,'_dut_instance'): if self.parent.model == 'icarus': self._dut_instance=verilog_module(**{'file':self._dutfile}) if self.parent.model == 'sv': self._dut_instance=verilog_module(**{'file':self._dutfile}) elif self.parent.model == 'vhdl': self._dut_instance=vhdl_entity(**{'file':self._dutfile}) elif self.parent.model == 'ghdl': self._dut_instance=vhdl_entity(**{'file':self._dutfile}) else: self.print_log(t='F', msg='Mpdel %s not supported' %(self.parent.model)) return self._dut_instance #We should not need this, but it is wise to enable override @dut_instance.setter def dut_instance(self,value): self._dut_instance=value @property def verilog_instances(self): """Verilog instances Bundle to be added to tesbench Todo Need to handle VHDL instance too. """ if not hasattr(self,'_verilog_instances'): self._verilog_instances=Bundle() return self._verilog_instances
[docs] def verilog_instance_add(self,**kwargs): """Add verilog instance to the Bundle fro a file Parameters ---------- **kwargs: name : str name of the module file : File defining the module """ # TODO: need to handle vhdl instances too name=kwargs.get('name') file=kwargs.get('file') self.verilog_instances.Members[name]=verilog_module(file=file,instname=name) # Addc connectors from the imported instance self.connectors.update(bundle=self.verilog_instances.Members[name].io_signals.Members)
@property def dumpfile(self): """String Code that generates a VCD dumpfile when running the testbench with icarus verilog. This dumpfile can be used with gtkwave. """ if self.parent.model == 'icarus' and self.parent.interactive_rtl: dump_str="// Generates dumpfile with iverilog\n" dump_str += "initial begin\n" dump_str += ' $dumpfile("' + self.parent.rtlsimpath + '/'+ self.parent.name + '_dump.vcd");\n' dump_str += " $dumpvars(0, tb_" + self.parent.name + ");\nend \n" else: dump_str = '' return dump_str
if __name__=="__main__": pass