def print_wrap_file(mfdo, v_fname=None): '''| | Create <module_name>_wrp.py file | This file is used to integrate third-party verilog module in a MyHDL design | The verilog module must have the same interface signals as the generated in this file signals | All verilog implementation files must be specified in file 'compile_list.txt' file in order to be included for co-simulation |________''' if v_fname != None: verilog_file = v_fname else: verilog_file = mfdo.verilog["path"] + '/' + mfdo.verilog["name"] + '.v' gwf = GenWrapperFile() gwf.initialize(verilog_file) s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_wrp.py" s += 'from myhdl import *\n\n' s += 'def ' + mfdo.module_name + '_wrp(' s += s.noIndent() + mfdo.printInterfaces() s += s.noIndent() + ', INST_NAME):\n\n' s += s.indent() + '""" Interface signals """\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) if len(j) > 1: mfdo.printBusInterfaces(s, j, i["name"]) iname = i["name"] + '_' if len(j) > 1 else '' for k in j: for sigName in k.get_sig_names(): s += iname + k.inst_name + "_" + sigName + "," s.noIndent() stmp = ".get_src_signals() # produce data\n" if k.direction == 1 else ".get_snk_signals() # consume data\n" # 1=Out s = s - 1 + (s.noIndent() + " = " + iname + k.inst_name + stmp) s.newLine() s += '# Need this in order to work...\n' s += '@always(' + mfdo.Clock["name"] + '.posedge, ' + mfdo.Reset[ "name"] + ')\n' s += 'def pass_thru():\n' s += s.indent() + 'pass\n\n' s.dedent() gwf.genTheWrapper(s) s.write(filename, overwrite=mfdo.overwrite)
def print_wrap_file(mfdo, v_fname=None): '''| | Create <module_name>_wrp.py file | This file is used to integrate third-party verilog module in a MyHDL design | The verilog module must have the same interface signals as the generated in this file signals | All verilog implementation files must be specified in file 'compile_list.txt' file in order to be included for co-simulation |________''' if v_fname != None: verilog_file = v_fname else: verilog_file = mfdo.verilog["path"] + '/' + mfdo.verilog["name"] + '.v' gwf = GenWrapperFile() gwf.initialize(verilog_file) s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_wrp.py" s += 'from myhdl import *\n\n' s += 'def ' + mfdo.module_name + '_wrp(' s += s.noIndent() + mfdo.printInterfaces() s += s.noIndent() + ', INST_NAME):\n\n' s += s.indent() + '""" Interface signals """\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) if len(j) > 1: mfdo.printBusInterfaces(s, j, i["name"]) iname = i["name"] + '_' if len(j) > 1 else '' for k in j: for sigName in k.get_sig_names(): s += iname + k.inst_name + "_" + sigName + "," s.noIndent() stmp = ".get_src_signals() # produce data\n" if k.direction == 1 else ".get_snk_signals() # consume data\n" # 1=Out s = s-1 + (s.noIndent() + " = " + iname + k.inst_name + stmp) s.newLine() s += '# Need this in order to work...\n' s += '@always(' + mfdo.Clock["name"] + '.posedge, ' + mfdo.Reset["name"] + ')\n' s += 'def pass_thru():\n' s += s.indent() + 'pass\n\n' s.dedent() gwf.genTheWrapper(s) s.write(filename, overwrite = mfdo.overwrite)
def generateWrapperFile(self): '''| | Generate <module_name_wrapper>.py file |________''' print "\nGenerating .py wrapper file." s = StrBuilder() self.genWrapperInterface(s) s += '# Need this in order to work...\n' # We assume that the clock is 'clk'!!!!! s += '@always(clk.posedge)\n' s += 'def pass_thru():\n' s += s.indent() + 'pass\n\n' s.dedent() self.genTheWrapper(s) self.genConvertFunc(s) filename = self.module_name + '_wrp.py' s.write(filename)
def print_json_file(mfdo): '''| | Create/Update a .json file containing the description of a module (interfaces as well as topology if present) |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.module_name + '.json' print_design(mfdo, s) try: with open(filename) as f: # The .json file exist, we use the existing 'structure' section (DO NOT UPDATE) gdf = pihdf.MFDesign() gdf.initialize( filename ) if gdf.modules != []: print_structure(gdf, s) except IOError as e: if mfdo.modules != []: print_structure(mfdo, s) s += s.dedent() + '}\n' s.write(filename, overwrite = mfdo.overwrite)
def print_json_file(mfdo): '''| | Create/Update a .json file containing the description of a module (interfaces as well as topology if present) |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.module_name + '.json' print_design(mfdo, s) try: with open(filename) as f: # The .json file exist, we use the existing 'structure' section (DO NOT UPDATE) gdf = pihdf.MFDesign() gdf.initialize(filename) if gdf.modules != []: print_structure(gdf, s) except IOError as e: if mfdo.modules != []: print_structure(mfdo, s) s += s.dedent() + '}\n' s.write(filename, overwrite=mfdo.overwrite)
def print_btest_file(mfdo): '''| | Create base test class: t_<module_name>.py file. | It also creates 2 .gtkw files used to visualize vcd traces from simulation and co-simulation |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.test_path + '/t_' + mfdo.module_name + ".py" s += 'import myhdl\n' s += 'import pihdf\n' s += 'from pihdf import Testable\n\n' s += 'import os, sys\n\n' s += 'sys.path.append(os.path.dirname(__file__) + "/../..")\n\n' s += 'from ' + mfdo.module_name + '.' + mfdo.module_name + ' import ' + mfdo.module_name + '\n\n' s += 'class t_' + mfdo.module_name + '(Testable):\n' s += s.indent() + s.header_comment('Automatically generated. Do not modify this file.') s += 'pihdf.head("T E S T S")\n' s += 'pihdf.info("Using myhdl version " + myhdl.__version__)\n' s += 'pihdf.info("Using pihdf version " + pihdf.__version__ + \'\\n\')\n\n' s += 'def __init__(self):\n' s.indent() s += '# call base class constructor\n' s += 'Testable.__init__(self)\n\n' # test_path used with test_vectors s += 'self.test_path = os.path.dirname(__file__)\n\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: s += 'self.cond_' + k.inst_name + ' = []\n' if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + ' = []\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + ' = []\n' s += 'self.cond_sim_end = {}\n\n' first = True pre = '' tst_data_str = '' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: pre = '' if first else 26*' ' tst_data_str += pre + '"cond_' + k.inst_name + '":self.cond_' + k.inst_name + ',\\\n' pre = 26*' ' if k.direction == 0: # IN tst_data_str += pre + '"stim_' + k.inst_name + '":self.stim_' + k.inst_name + ',\\\n' elif k.direction == 1: # OUT tst_data_str += pre + '"res_' + k.inst_name + '":self.res_' + k.inst_name + ',\\\n' first = False tst_data_str += pre + '"cond_sim_end": self.cond_sim_end' s += 'self.tst_data = { ' + tst_data_str + ' }\n\n' ref_data_str = '' first = True for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: pre = 26*' ' if not first else '' if k.direction == 1: # OUT first = False ref_data_str += pre + '"' + k.inst_name + '":' + '(self.ref_' + k.inst_name + ', self.res_' + k.inst_name + '),\\\n' s += 'self.ref_' + k.inst_name + ' = []\n' s.newLine() s += 'self.ref_data = { ' + ref_data_str[:-3] + ' }\n\n' s += s.dedent() + '# Automatically executed BEFORE every test case\n' s += 'def setUp(self):\n' s += s.indent() + 'print ""\n\n' s += s.dedent() + '# Automatically executed AFTER every test case\n' s += 'def tearDown(self):\n' s += s.indent() + 'print ""\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: s += 'self.cond_' + k.inst_name + ' = []\n' if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + ' = []\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + ' = []\n' s += 'self.ref_' + k.inst_name + ' = []\n' s.newLine() s += s.dedent() + '# Data has been previously generated and written to files\n' s += 'def use_data_from_files(self):\n' s.indent() for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/' + k.inst_name + '.tvr"})\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/my_' + k.inst_name + '.tvr"})\n' s += 'self.ref_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/' + k.inst_name + '.tvr"})\n' s.newLine() s += 'self.checkfiles = True\n' s += 'self.run_it()\n\n' s += s.dedent() + '# Run the simulation and check the results\n' s += 'def run_it(self, checkfiles=False):\n' s += s.indent() + 'self.check_config("' + mfdo.module_name + '")\n\n' s += mfdo.module_name + '_dut = ' + mfdo.module_name + '(IMPL=self.models)\n' s += mfdo.module_name + '_dut.' + 'Simulate(tb_config=self.tb_config, tst_data=self.tst_data, verbose=self.verbose' if mfdo.parameters != []: s += (s.noIndent() + ', dut_params=self.dut_params') s += (s.noIndent() + ')\n') s += mfdo.module_name + '_dut.clean()\n\n' s += 'self.check_results()\n' s.write(filename, overwrite = mfdo.overwrite) print_gtkw_file(mfdo, cosim = False) print_gtkw_file(mfdo, cosim = True)
def print_btest_file(mfdo): '''| | Create base test class: t_<module_name>.py file. | It also creates 2 .gtkw files used to visualize vcd traces from simulation and co-simulation |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.test_path + '/t_' + mfdo.module_name + ".py" s += 'import myhdl\n' s += 'import pihdf\n' s += 'from pihdf import Testable\n\n' s += 'import os, sys\n\n' s += 'sys.path.append(os.path.dirname(__file__) + "/../..")\n\n' s += 'from ' + mfdo.module_name + '.' + mfdo.module_name + ' import ' + mfdo.module_name + '\n\n' s += 'class t_' + mfdo.module_name + '(Testable):\n' s += s.indent() + s.header_comment( 'Automatically generated. Do not modify this file.') s += 'pihdf.head("T E S T S")\n' s += 'pihdf.info("Using myhdl version " + myhdl.__version__)\n' s += 'pihdf.info("Using pihdf version " + pihdf.__version__ + \'\\n\')\n\n' s += 'def __init__(self):\n' s.indent() s += '# call base class constructor\n' s += 'Testable.__init__(self)\n\n' # test_path used with test_vectors s += 'self.test_path = os.path.dirname(__file__)\n\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: s += 'self.cond_' + k.inst_name + ' = []\n' if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + ' = []\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + ' = []\n' s += 'self.cond_sim_end = {}\n\n' first = True pre = '' tst_data_str = '' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: pre = '' if first else 26 * ' ' tst_data_str += pre + '"cond_' + k.inst_name + '":self.cond_' + k.inst_name + ',\\\n' pre = 26 * ' ' if k.direction == 0: # IN tst_data_str += pre + '"stim_' + k.inst_name + '":self.stim_' + k.inst_name + ',\\\n' elif k.direction == 1: # OUT tst_data_str += pre + '"res_' + k.inst_name + '":self.res_' + k.inst_name + ',\\\n' first = False tst_data_str += pre + '"cond_sim_end": self.cond_sim_end' s += 'self.tst_data = { ' + tst_data_str + ' }\n\n' ref_data_str = '' first = True for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: pre = 26 * ' ' if not first else '' if k.direction == 1: # OUT first = False ref_data_str += pre + '"' + k.inst_name + '":' + '(self.ref_' + k.inst_name + ', self.res_' + k.inst_name + '),\\\n' s += 'self.ref_' + k.inst_name + ' = []\n' s.newLine() s += 'self.ref_data = { ' + ref_data_str[:-3] + ' }\n\n' s += s.dedent() + '# Automatically executed BEFORE every test case\n' s += 'def setUp(self):\n' s += s.indent() + 'print ""\n\n' s += s.dedent() + '# Automatically executed AFTER every test case\n' s += 'def tearDown(self):\n' s += s.indent() + 'print ""\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: s += 'self.cond_' + k.inst_name + ' = []\n' if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + ' = []\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + ' = []\n' s += 'self.ref_' + k.inst_name + ' = []\n' s.newLine() s += s.dedent( ) + '# Data has been previously generated and written to files\n' s += 'def use_data_from_files(self):\n' s.indent() for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) for k in j: if k.direction == 0: # IN s += 'self.stim_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/' + k.inst_name + '.tvr"})\n' elif k.direction == 1: # OUT s += 'self.res_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/my_' + k.inst_name + '.tvr"})\n' s += 'self.ref_' + k.inst_name + '.append({"file" : self.test_path + "/vectors/' + k.inst_name + '.tvr"})\n' s.newLine() s += 'self.checkfiles = True\n' s += 'self.run_it()\n\n' s += s.dedent() + '# Run the simulation and check the results\n' s += 'def run_it(self, checkfiles=False):\n' s += s.indent() + 'self.check_config("' + mfdo.module_name + '")\n\n' s += mfdo.module_name + '_dut = ' + mfdo.module_name + '(IMPL=self.models)\n' s += mfdo.module_name + '_dut.' + 'Simulate(tb_config=self.tb_config, tst_data=self.tst_data, verbose=self.verbose' if mfdo.parameters != []: s += (s.noIndent() + ', dut_params=self.dut_params') s += (s.noIndent() + ')\n') s += mfdo.module_name + '_dut.clean()\n\n' s += 'self.check_results()\n' s.write(filename, overwrite=mfdo.overwrite) print_gtkw_file(mfdo, cosim=False) print_gtkw_file(mfdo, cosim=True)
def print_module_class_file(mfdo): '''| | Create <module_name>.py file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.module_name + ".py" #-------------------------------------------------------------------------------------------- # imports #-------------------------------------------------------------------------------------------- s += 'from myhdl import *\n' s += 'from pihdf import Convertible\n' s += 'from pihdf.interfaces import *\n\n' if mfdo.modules != []: # TODO: Needs rethinking in case of structural designs s += 'import sys\n' s += 'import os\n' s += 'module_path = os.path.dirname(__file__)\n\n' # Make third-party-modules 'visible' p_dict = {} t_dict = {} bflg = 0 for p in mfdo.modules: if p["path"] == '': bflg += 1 elif not p["path"] in p_dict: # TODO: Not clear how to deal with the import paths!!! # s += 'lib_path = os.path.abspath(module_path + "/../' + p["path"] + '")\n' # s += 'sys.path.append(lib_path)\n' p_dict[p["path"]] = 1 s.newLine() if bflg > 1: # Make the modules in directory 'modules' visible for each other s += "import site\n" s += "site.addsitedir(module_path + '/src/modules')\n\n" for p in mfdo.custom_interfaces: s += 'from imp.' + p['name'] + ' import *\n\n' s += 'from ' + 'src.' + mfdo.module_name + '_beh import *\n' if mfdo.verilog != {}: s += 'from ' + 'src.' + mfdo.module_name + '_wrp import *\n' else: s += 'from ' + 'src.' + mfdo.module_name + '_rtl import *\n' s.newLine() s += 'class ' + mfdo.module_name + '(Convertible):\n' s += s.indent() + s.header_comment('The design class') s += 'def __init__(self, IMPL={}):\n\n' s.indent() if mfdo.modules != []: s += 'self.structural = True\n' s += 'self.models = IMPL\n' else: s += 'self.structural = False\n' s.newLine() s += 'if isinstance(IMPL, dict):\n' s += s.indent() + 'self.IMPL = IMPL["top"] if "top" in IMPL else IMPL\n' s += s.dedent() + 'else:\n' s += s.indent() + 'self.IMPL = IMPL\n\n' s += s.dedent() + '# call base class constructor\n' s += 'Convertible.__init__(self)\n\n' # TODO: To be extended for any number of reset signals s += 'self.resets = lambda : [\n' s += s.indent( ) + 'Reset(name="' + mfdo.Reset["name"] + '", active=' + mfdo.Reset[ "active"] + ', val=' + mfdo.Reset["active"] + ', async=True)\n' s += s.dedent() + ']\n' s.newLine() # TODO: To be extended for any number of clock signals s += 'self.clocks = lambda : [\n' s += s.indent() + 'Clock(name="' + mfdo.Clock["name"] + '")\n' s += s.dedent() + ']\n' s.newLine() s += "self.interfaces = lambda fdump : [\n" s.indent() for i in mfdo.interfaces: s_width = 'data_width=' + i["width"] + ', ' if "width" in i else '' s_direction = 'direction=self.' + i[ "direction"] + ', ' if "direction" in i else '' s_intfs = 'bus_type=' + i[ "interfaces"] + ', ' if "interfaces" in i else '' s_name = 'name="' + i["name"] + '"' + ', ' if "name" in i else '' s_data = 'data=' + i["data"] + ', ' if "data" in i else '' s_push = 'push=' + i["push"] + ', ' if "push" in i else '' s_regfile = 'reg_file=' + i[ "reg_file"] + ', ' if "reg_file" in i else '' s += i[ "type"] + '(' + s_width + s_direction + s_intfs + s_name + s_data + s_push + s_regfile s += s.noIndent() + 'filedump=fdump),\n' s = s - 2 + (s.noIndent() + '\n') s += s.dedent() + ']\n' s.newLine() if mfdo.parameters != []: s += '# no lambda here\n' s += 'self.parameters = [\n' s.indent() for p in mfdo.parameters: s += 'Parameter("' + p["name"] + '", value=' + p["value"] + '),\n' s = s - 2 + '\n' # remove the last comma s += s.dedent() + ']\n' else: s += 'self.parameters = []\n' s.newLine() s += '# register implementations used in Convertible.gen()\n' s += 'self.funcdict = {\n' s.indent() s_beh = mfdo.module_name + "_beh" s_rtl = mfdo.module_name + "_rtl" if mfdo.verilog == {} else "None" s_vrg = mfdo.module_name + "_wrp" if mfdo.verilog != {} else "None" s += "'beh': " + s_beh + ",\n" s += "'rtl': " + s_rtl + ",\n" s += "'vrg': " + s_vrg + "\n" s += s.dedent() + '}\n' s.dedent() s.newLine(2) generateTop(mfdo, s) s.newLine(2) s += s.dedent(3) + 'if __name__ == "__main__":\n\n' s += s.indent() + 'import myhdl\n' s += 'import pihdf\n\n' s += 'pihdf.info("Using MyHDL version %s" % myhdl.__version__)\n' s += 'pihdf.info("Using MyFramework version %s" % pihdf.__version__)\n\n' s += 'dn = ' + mfdo.module_name + '(IMPL=1)\n' sparams = '' if mfdo.parameters != []: sparams += ', params={' for p in mfdo.parameters: sparams += '"' + p["name"] + '":' + p["value"] + ', ' sparams = sparams[:-2] + '}' # remove the last comma s += 'dn.convert(hdl="verilog"' + sparams + ')\n' s += 'dn.convert(hdl="vhdl"' + sparams + ')\n' s += 'dn.clean()\n' s.write(filename, overwrite=mfdo.overwrite)
def print_utest_file(mfdo): '''| | Create utest_<module_name>.py file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.test_path + '/utest_' + mfdo.module_name + ".py" base_test = 't_' + mfdo.module_name s += 'import unittest\n\n' s += 'from myhdl_lib import *\n\n' s += 'from ' + base_test + ' import ' + base_test + '\n\n' s += 'class Test_' + mfdo.module_name + '(' + base_test + '):\n' s += s.indent() + s.header_comment( 'The main class for unit-testing. Add your tests here.') s += 'def __init__(self):\n' s.indent() s += '# call base class constructor\n' s += base_test + '.__init__(self)\n\n' s += s.dedent() + '# Automatically executed BEFORE every TestCase\n' s += 'def setUp(self):\n' s += s.indent() + base_test + '.setUp(self)\n\n' s += s.dedent() + '# Automatically executed AFTER every TestCase\n' s += 'def tearDown(self):\n' s += s.indent() + base_test + '.tearDown(self)\n\n\n' s += s.dedent( ) + '# ----------------------------------------------------------------------------\n' s += '# @unittest.skip("")\n' s += 'def test_000(self):\n' s += s.indent() + '""" >>>>>> TEST_000: TO DO: describe the test """\n\n' if mfdo.parameters != []: s += 'self.dut_params = {' for p in mfdo.parameters: s += (s.noIndent() + '"' + p["name"] + '":' + p["value"] + ', ') s = s - 2 + (s.noIndent() + '}\n') s += 'self.models = {"top":self.BEH}\n' s += '# Set fdump to True in order to generate test vector files for the global interfaces\n' s += 'self.tb_config = {"simulation_time":"auto", "cosimulation":False, "trace":False, "fdump":False, "ipgi":0, "ipgo":0}\n\n' s += '# TO DO: generate stimuli and reference data here\n\n' s + 'self.run_it()\n\n' # Commented due to problems in case of structured design using BUS interfaces #if mfdo.modules != []: #s += s.dedent() + '# ----------------------------------------------------------------------------\n' #s += '@unittest.skip("")\n' #s += 'def test_0000(self):\n' #s += s.indent() + '""" >>>>>> TEST_0000: Test template for using stimuli files """\n\n' #if mfdo.parameters != []: #s += 'self.dut_params = {' #for p in mfdo.parameters: #s += (s.noIndent() + '"' + p["name"] + '":' + p["value"] + ', ') #s = s-2 + (s.noIndent() + '}\n') #s += 'self.models = {"top":self.RTL' #for m in mfdo.modules: #s += (s.noIndent() + ', "' + m["name"] + '":self.BEH') #s += (s.noIndent() + '}\n') #s += '# Set fdump to True in order to generate test vector files for the local interfaces\n' #s += 'self.tb_config = {"simulation_time":"auto", "cosimulation":False, "trace":False, "fdump":False, "ipgi":0, "ipgo":0}\n\n' #s += '# TO DO: Provide stimuli and reference files here\n' #for i in mfdo.interfaces: #if i["direction"]=='IN': #s += 'self.stim_' + i["name"] + '.append({"file" : self.test_path + "/vectors/stim_' + i["name"] + '.tvr"})\n' #elif i["direction"]=='OUT': #s += 'self.res_' + i["name"] + '.append({"file" : self.test_path + "/vectors/res_' + i["name"] + '.tvr"})\n' #s += 'self.ref_' + i["name"] + '.append({"file" : self.test_path + "/vectors/ref_' + i["name"] + '.tvr"})\n' #s.newLine() #s + 'self.run_it(checkfiles=True)\n\n\n' s += s.dedent( ) + '# ----------------------------------------------------------------------------\n' s.write(filename, overwrite=mfdo.overwrite)
def print_rtl_file(mfdo): '''| | Create <module_name>_rtl.py file | It is an empty (template) file used to specify (synthesizable) implementation at RTL | Interface signals are generated as well |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_rtl.py" s += 'from myhdl import *\n' s += 'from pihdf import *\n' s += 'from myhdl_lib import *\n\n' if mfdo.modules != []: #s += 'import os\n\n' pp_dict = {} tt_dict = {} for p in mfdo.modules: if p["path"] == '': if not p["type"] in tt_dict: tt_dict[p["type"]] = 1 s += 'from modules.' + p["type"] + '.' + p[ "type"] + ' import ' + p["type"] + '\n' elif not p["path"] in pp_dict: if not p["type"] in tt_dict: tt_dict[p["type"]] = 1 # TODO: Not clear how to deal with the import paths!!! s += 'from ' + p["type"] + '.' + p[ "type"] + ' import ' + p["type"] + '\n' #spath = p["path"][3:].replace("/", ".") #s += 'from ' + spath + ' import ' + p["type"] + '\n' s += s.noIndent() + '\n' s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText( filename, "#--- Custom code begin ---#", "#--- Custom code end ---#") s += "#--- Custom code end ---#\n\n" s += 'def ' + mfdo.module_name + '_rtl(' s += s.noIndent() + mfdo.printInterfaces() if mfdo.modules != []: s += s.noIndent() + ', IMPL, FDUMP):\n' else: s += s.noIndent() + '):\n' s += s.indent() + s.header_comment( 'Top-level MyHDL description. This is converted to RTL velilog...') s.newLine() s += '""" Interface signals """\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) if len(j) > 1: mfdo.printBusInterfaces(s, j, i["name"]) for k in j: stype = '.get_src_signals() # produce data\n' if k.direction == 1 else '.get_snk_signals() # consume data\n' snames = ', '.join(k.get_sig_full_names()) s += snames + " = " + k.inst_name + stype s += s.noIndent() + '\n' #------------------------------------------------------------------------------------------- # generate an empty (template) file used to specify RTL (synthesizable) implementation #------------------------------------------------------------------------------------------- if mfdo.modules == []: s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText( filename, " #--- Custom code begin ---#", " #--- Custom code end ---#") s += "#--- Custom code end ---#\n\n" s += 'return all_instances(' + mfdo.Reset["name"] + ', ' + mfdo.Clock[ "name"] + ')\n' else: #--------------------------------------------------------------------------------------- # generate the gen() body (connected components given in the .json file) #--------------------------------------------------------------------------------------- # declaration of the interfaces s += '""" Local interfaces """\n' for i in mfdo.local_interfaces: s_tmp = i["width"] if("width" in i) else \ 'data=' + i["data"] if("data" in i) else '' s_buf_size = ', buf_size=' + i["buf_size"] if ("buf_size" in i) else '' s_push = ', push=' + i["push"] if ("push" in i) else '' s_terminate = ', terminate=' + i[ "terminate"] if "terminate" in i else '' s += i["name"] + ' = ' + i[ "type"] + '(' + s_tmp + s_buf_size + s_push + s_terminate + ', filedump=FDUMP)\n' s += s.noIndent() + '\n' # declaration of the local parameters if mfdo.local_parameters != []: s += '# Parameters\n' for p in mfdo.local_parameters: s += p["name"] + ' = ' + p["value"] + '\n' s.newLine() s += 'if isinstance(IMPL, dict):\n' s.indent() cc = 1 for m in mfdo.modules: inst_name = m[ "name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + '_impl = IMPL["' + inst_name + '"] if "' + inst_name + '" in IMPL else IMPL["top"]\n' cc += 1 s += s.dedent() + 'else:\n' s.indent() cc = 1 for m in mfdo.modules: inst_name = m[ "name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + '_impl = IMPL\n' cc += 1 s.dedent() s += s.noIndent() + '\n' # instance of the modules (and port map) s += '""" Components """\n' cc = 1 for m in mfdo.modules: inst_name = m[ "name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + ' = ' + m["type"] + '(' + inst_name + '_impl).gen(' cc += 1 for key, value in m.iteritems(): if key != "name" and key != "path" and key != "type" and key != "connections": s.noIndent() s += key + '=' + value + ', ' s = s - 2 + (s.noIndent() + ')\n') # remove the last comma s += s.noIndent() + '\n' s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText( filename, " #--- Custom code begin ---#", " #--- Custom code end ---#") s += "#--- Custom code end ---#\n" s.newLine() s += 'return all_instances(' + mfdo.Reset["name"] + ', ' + mfdo.Clock[ "name"] + ')\n' s.write(filename, overwrite=mfdo.overwrite)
def print_verilog_file(mfdo): '''| | Create <module_name>.v file | It is an empty (template) verilog file containing the interface signals, which must be used to integrate a | verilog module in a MyHDL design. The integration is done by using the auto-generated verilog wrapper file | The verilog module implementation has to be provided in this, and possibly other, files by the designers | Additional verilog files must be specified in file 'compile_list.txt' in order to be included for co-simulation |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + '.v' s += 'module ' + mfdo.module_name if mfdo.parameters != []: s.newLine() s += s.indent(2) + '#(\n' for p in mfdo.parameters: s += 'parameter ' + p["name"] + ' = ' + p["value"] + ',\n' s = s - 2 + '\n' s += ')(\n' else: s += ' (\n' s.indent(2) if mfdo.Reset != None: s += 'input wire \t\t' + mfdo.Reset["name"] + ',\n' else: print "Warning: RESET signal not specified!" if mfdo.Clock != None: s += 'input wire \t\t' + mfdo.Clock["name"] + ',\n' else: print "Warning: CLOCK signal not specified!" for i in mfdo.interfaces: s.newLine() j = mfdo.getInterfaceObj(i) if len(j) > 1: s += '// ' + i["name"] + ' (Bus interface)\n' # print the interface signals iname = i["name"] + '_' if len(j) > 1 else '' for k in j: itype = ' (consume data)\n' if k.direction == 0 else ' (produce data)\n' s += '// ' + iname + k.inst_name + itype for sigName, sigLen in zip(k.get_sig_names(), k.get_sig_lens()): str_dir = 'input ' if k.direction == 0 else 'output ' if sigName == 'ready': str_dir = 'input ' if str_dir == 'output ' else 'output ' sigLenStr = ' \t' if sigLen == 1 else '[' + str(sigLen - 1) + ':0]\t' s += str_dir + 'wire ' + sigLenStr + iname + k.inst_name + '_' + sigName + ',\n' s = s - 2 + '\n' s += ');\n\n' s.dedent(2) s += '/* Custom code begin */\n' s += s.noIndent() + mfdo.extractText(filename, "/* Custom code begin */", "/* Custom code end */") s += "/* Custom code end */\n\n" s += 'endmodule\n' s.write(filename, overwrite=mfdo.overwrite) print_wrap_file(mfdo, filename)
def print_verilog_file(mfdo): '''| | Create <module_name>.v file | It is an empty (template) verilog file containing the interface signals, which must be used to integrate a | verilog module in a MyHDL design. The integration is done by using the auto-generated verilog wrapper file | The verilog module implementation has to be provided in this, and possibly other, files by the designers | Additional verilog files must be specified in file 'compile_list.txt' in order to be included for co-simulation |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + '.v' s += 'module ' + mfdo.module_name if mfdo.parameters != []: s.newLine() s += s.indent(2) + '#(\n' for p in mfdo.parameters: s += 'parameter ' + p["name"] + ' = ' + p["value"] + ',\n' s = s-2 + '\n' s += ')(\n' else: s += ' (\n' s.indent(2) if mfdo.Reset != None: s += 'input wire \t\t' + mfdo.Reset["name"] + ',\n' else: print "Warning: RESET signal not specified!" if mfdo.Clock != None: s += 'input wire \t\t' + mfdo.Clock["name"] + ',\n' else: print "Warning: CLOCK signal not specified!" for i in mfdo.interfaces: s.newLine() j = mfdo.getInterfaceObj(i) if len(j) > 1: s += '// ' + i["name"] + ' (Bus interface)\n' # print the interface signals iname = i["name"] + '_' if len(j) > 1 else '' for k in j: itype = ' (consume data)\n' if k.direction == 0 else ' (produce data)\n' s += '// ' + iname + k.inst_name + itype for sigName, sigLen in zip(k.get_sig_names(), k.get_sig_lens()): str_dir = 'input ' if k.direction == 0 else 'output ' if sigName=='ready': str_dir = 'input ' if str_dir=='output ' else 'output ' sigLenStr = ' \t' if sigLen==1 else '[' + str(sigLen-1) + ':0]\t' s += str_dir + 'wire ' + sigLenStr + iname + k.inst_name + '_' + sigName + ',\n' s = s-2 + '\n' s += ');\n\n' s.dedent(2) s += '/* Custom code begin */\n' s += s.noIndent() + mfdo.extractText(filename, "/* Custom code begin */", "/* Custom code end */") s += "/* Custom code end */\n\n" s += 'endmodule\n' s.write(filename, overwrite = mfdo.overwrite) print_wrap_file(mfdo, filename)
def print_utest_file(mfdo): '''| | Create utest_<module_name>.py file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.test_path + '/utest_' + mfdo.module_name + ".py" base_test = 't_' + mfdo.module_name s += 'import unittest\n\n' s += 'from myhdl_lib import *\n\n' s += 'from ' + base_test + ' import ' + base_test + '\n\n' s += 'class Test_' + mfdo.module_name + '(' + base_test + '):\n' s += s.indent() + s.header_comment('The main class for unit-testing. Add your tests here.') s += 'def __init__(self):\n' s.indent() s += '# call base class constructor\n' s += base_test + '.__init__(self)\n\n' s += s.dedent() + '# Automatically executed BEFORE every TestCase\n' s += 'def setUp(self):\n' s += s.indent() + base_test + '.setUp(self)\n\n' s += s.dedent() + '# Automatically executed AFTER every TestCase\n' s += 'def tearDown(self):\n' s += s.indent() + base_test + '.tearDown(self)\n\n\n' s += s.dedent() + '# ----------------------------------------------------------------------------\n' s += '# @unittest.skip("")\n' s += 'def test_000(self):\n' s += s.indent() + '""" >>>>>> TEST_000: TO DO: describe the test """\n\n' if mfdo.parameters != []: s += 'self.dut_params = {' for p in mfdo.parameters: s += (s.noIndent() + '"' + p["name"] + '":' + p["value"] + ', ') s = s-2 + (s.noIndent() + '}\n') s += 'self.models = {"top":self.BEH}\n' s += '# Set fdump to True in order to generate test vector files for the global interfaces\n' s += 'self.tb_config = {"simulation_time":"auto", "cosimulation":False, "trace":False, "fdump":False, "ipgi":0, "ipgo":0}\n\n' s += '# TO DO: generate stimuli and reference data here\n\n' s + 'self.run_it()\n\n' # Commented due to problems in case of structured design using BUS interfaces #if mfdo.modules != []: #s += s.dedent() + '# ----------------------------------------------------------------------------\n' #s += '@unittest.skip("")\n' #s += 'def test_0000(self):\n' #s += s.indent() + '""" >>>>>> TEST_0000: Test template for using stimuli files """\n\n' #if mfdo.parameters != []: #s += 'self.dut_params = {' #for p in mfdo.parameters: #s += (s.noIndent() + '"' + p["name"] + '":' + p["value"] + ', ') #s = s-2 + (s.noIndent() + '}\n') #s += 'self.models = {"top":self.RTL' #for m in mfdo.modules: #s += (s.noIndent() + ', "' + m["name"] + '":self.BEH') #s += (s.noIndent() + '}\n') #s += '# Set fdump to True in order to generate test vector files for the local interfaces\n' #s += 'self.tb_config = {"simulation_time":"auto", "cosimulation":False, "trace":False, "fdump":False, "ipgi":0, "ipgo":0}\n\n' #s += '# TO DO: Provide stimuli and reference files here\n' #for i in mfdo.interfaces: #if i["direction"]=='IN': #s += 'self.stim_' + i["name"] + '.append({"file" : self.test_path + "/vectors/stim_' + i["name"] + '.tvr"})\n' #elif i["direction"]=='OUT': #s += 'self.res_' + i["name"] + '.append({"file" : self.test_path + "/vectors/res_' + i["name"] + '.tvr"})\n' #s += 'self.ref_' + i["name"] + '.append({"file" : self.test_path + "/vectors/ref_' + i["name"] + '.tvr"})\n' #s.newLine() #s + 'self.run_it(checkfiles=True)\n\n\n' s += s.dedent() + '# ----------------------------------------------------------------------------\n' s.write(filename, overwrite = mfdo.overwrite)
def print_rtl_file(mfdo): '''| | Create <module_name>_rtl.py file | It is an empty (template) file used to specify (synthesizable) implementation at RTL | Interface signals are generated as well |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_rtl.py" s += 'from myhdl import *\n' s += 'from pihdf import *\n' s += 'from myhdl_lib import *\n\n' if mfdo.modules != []: #s += 'import os\n\n' pp_dict = {} tt_dict = {} for p in mfdo.modules: if p["path"]=='': if not p["type"] in tt_dict: tt_dict[p["type"]]=1 s += 'from modules.' + p["type"] + '.' + p["type"] + ' import ' + p["type"] + '\n' elif not p["path"] in pp_dict: if not p["type"] in tt_dict: tt_dict[p["type"]] = 1 # TODO: Not clear how to deal with the import paths!!! s += 'from ' + p["type"] + '.' + p["type"] + ' import ' + p["type"] + '\n' #spath = p["path"][3:].replace("/", ".") #s += 'from ' + spath + ' import ' + p["type"] + '\n' s += s.noIndent() + '\n' s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText(filename, "#--- Custom code begin ---#", "#--- Custom code end ---#") s += "#--- Custom code end ---#\n\n" s += 'def ' + mfdo.module_name + '_rtl(' s += s.noIndent() + mfdo.printInterfaces() if mfdo.modules != []: s += s.noIndent() + ', IMPL, FDUMP):\n' else: s += s.noIndent() + '):\n' s += s.indent() + s.header_comment('Top-level MyHDL description. This is converted to RTL velilog...') s.newLine() s += '""" Interface signals """\n' for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) if len(j) > 1: mfdo.printBusInterfaces(s, j, i["name"]) for k in j: stype = '.get_src_signals() # produce data\n' if k.direction == 1 else '.get_snk_signals() # consume data\n' snames = ', '.join(k.get_sig_full_names()) s += snames + " = " + k.inst_name + stype s += s.noIndent() + '\n' #------------------------------------------------------------------------------------------- # generate an empty (template) file used to specify RTL (synthesizable) implementation #------------------------------------------------------------------------------------------- if mfdo.modules == []: s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText(filename, " #--- Custom code begin ---#", " #--- Custom code end ---#") s += "#--- Custom code end ---#\n\n" s += 'return all_instances(' + mfdo.Reset["name"] + ', ' + mfdo.Clock["name"] + ')\n' else: #--------------------------------------------------------------------------------------- # generate the gen() body (connected components given in the .json file) #--------------------------------------------------------------------------------------- # declaration of the interfaces s += '""" Local interfaces """\n' for i in mfdo.local_interfaces: s_tmp = i["width"] if("width" in i) else \ 'data=' + i["data"] if("data" in i) else '' s_buf_size = ', buf_size=' + i["buf_size"] if("buf_size" in i) else '' s_push = ', push=' + i["push"] if("push" in i) else '' s_terminate = ', terminate=' + i["terminate"] if "terminate" in i else '' s += i["name"] + ' = ' + i["type"] + '(' + s_tmp + s_buf_size + s_push + s_terminate + ', filedump=FDUMP)\n' s += s.noIndent() + '\n' # declaration of the local parameters if mfdo.local_parameters != []: s += '# Parameters\n' for p in mfdo.local_parameters: s += p["name"] + ' = ' + p["value"] + '\n' s.newLine() s += 'if isinstance(IMPL, dict):\n' s.indent() cc = 1 for m in mfdo.modules: inst_name = m["name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + '_impl = IMPL["' + inst_name + '"] if "' + inst_name + '" in IMPL else IMPL["top"]\n' cc += 1 s += s.dedent() + 'else:\n' s.indent() cc = 1 for m in mfdo.modules: inst_name = m["name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + '_impl = IMPL\n' cc += 1 s.dedent() s += s.noIndent() + '\n' # instance of the modules (and port map) s += '""" Components """\n' cc = 1 for m in mfdo.modules: inst_name = m["name"] if "name" in m else 'inst_' + m["type"] + str(cc) s += inst_name + ' = ' + m["type"] + '(' + inst_name + '_impl).gen(' cc += 1 for key, value in m.iteritems(): if key != "name" and key != "path" and key != "type" and key != "connections": s.noIndent() s += key + '=' + value + ', ' s = s-2 + (s.noIndent() + ')\n') # remove the last comma s += s.noIndent() + '\n' s += '#--- Custom code begin ---#\n' s += s.noIndent() + mfdo.extractText(filename, " #--- Custom code begin ---#", " #--- Custom code end ---#") s += "#--- Custom code end ---#\n" s.newLine() s += 'return all_instances(' + mfdo.Reset["name"] + ', ' + mfdo.Clock["name"] + ')\n' s.write(filename, overwrite = mfdo.overwrite)
def print_module_class_file(mfdo): '''| | Create <module_name>.py file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.module_name + ".py" #-------------------------------------------------------------------------------------------- # imports #-------------------------------------------------------------------------------------------- s += 'from myhdl import *\n' s += 'from pihdf import Convertible\n' s += 'from pihdf.interfaces import *\n\n' if mfdo.modules != []: # TODO: Needs rethinking in case of structural designs s += 'import sys\n' s += 'import os\n' s += 'module_path = os.path.dirname(__file__)\n\n' # Make third-party-modules 'visible' p_dict = {} t_dict = {} bflg = 0 for p in mfdo.modules: if p["path"]=='': bflg += 1 elif not p["path"] in p_dict: # TODO: Not clear how to deal with the import paths!!! # s += 'lib_path = os.path.abspath(module_path + "/../' + p["path"] + '")\n' # s += 'sys.path.append(lib_path)\n' p_dict[p["path"]] = 1 s.newLine() if bflg > 1: # Make the modules in directory 'modules' visible for each other s += "import site\n" s += "site.addsitedir(module_path + '/src/modules')\n\n" for p in mfdo.custom_interfaces: s += 'from imp.' + p['name'] + ' import *\n\n' s += 'from ' + 'src.' + mfdo.module_name + '_beh import *\n' if mfdo.verilog != {}: s += 'from ' + 'src.' + mfdo.module_name + '_wrp import *\n' else: s += 'from ' + 'src.' + mfdo.module_name + '_rtl import *\n' s.newLine() s += 'class ' + mfdo.module_name + '(Convertible):\n' s += s.indent() + s.header_comment('The design class') s += 'def __init__(self, IMPL={}):\n\n' s.indent() if mfdo.modules != []: s += 'self.structural = True\n' s += 'self.models = IMPL\n' else: s += 'self.structural = False\n' s.newLine() s += 'if isinstance(IMPL, dict):\n' s += s.indent() + 'self.IMPL = IMPL["top"] if "top" in IMPL else IMPL\n' s += s.dedent() + 'else:\n' s += s.indent() + 'self.IMPL = IMPL\n\n' s += s.dedent() + '# call base class constructor\n' s += 'Convertible.__init__(self)\n\n' # TODO: To be extended for any number of reset signals s += 'self.resets = lambda : [\n' s += s.indent() + 'Reset(name="' + mfdo.Reset["name"] + '", active=' + mfdo.Reset["active"] + ', val=' + mfdo.Reset["active"] + ', async=True)\n' s += s.dedent() + ']\n' s.newLine() # TODO: To be extended for any number of clock signals s += 'self.clocks = lambda : [\n' s += s.indent() + 'Clock(name="' + mfdo.Clock["name"] + '")\n' s += s.dedent() + ']\n' s.newLine() s += "self.interfaces = lambda fdump : [\n" s.indent() for i in mfdo.interfaces: s_width = 'data_width=' + i["width"] + ', ' if "width" in i else '' s_direction = 'direction=self.' + i["direction"] + ', ' if "direction" in i else '' s_intfs = 'bus_type=' + i["interfaces"] + ', ' if "interfaces" in i else '' s_name = 'name="' + i["name"] + '"' + ', ' if "name" in i else '' s_data = 'data=' + i["data"] + ', ' if "data" in i else '' s_push = 'push=' + i["push"] + ', ' if "push" in i else '' s_regfile = 'reg_file=' + i["reg_file"] + ', ' if "reg_file" in i else '' s += i["type"] + '(' + s_width + s_direction + s_intfs + s_name + s_data + s_push + s_regfile s += s.noIndent() + 'filedump=fdump),\n' s = s-2 + (s.noIndent() + '\n') s += s.dedent() + ']\n' s.newLine() if mfdo.parameters != []: s += '# no lambda here\n' s += 'self.parameters = [\n' s.indent() for p in mfdo.parameters: s += 'Parameter("' + p["name"] + '", value=' + p["value"] + '),\n' s = s-2 + '\n' # remove the last comma s += s.dedent() + ']\n' else: s += 'self.parameters = []\n' s.newLine() s += '# register implementations used in Convertible.gen()\n' s += 'self.funcdict = {\n' s.indent() s_beh = mfdo.module_name + "_beh" s_rtl = mfdo.module_name + "_rtl" if mfdo.verilog == {} else "None" s_vrg = mfdo.module_name + "_wrp" if mfdo.verilog != {} else "None" s += "'beh': " + s_beh + ",\n" s += "'rtl': " + s_rtl + ",\n" s += "'vrg': " + s_vrg + "\n" s += s.dedent() + '}\n' s.dedent() s.newLine(2) generateTop(mfdo, s) s.newLine(2) s += s.dedent(3) + 'if __name__ == "__main__":\n\n' s += s.indent() + 'import myhdl\n' s += 'import pihdf\n\n' s += 'pihdf.info("Using MyHDL version %s" % myhdl.__version__)\n' s += 'pihdf.info("Using MyFramework version %s" % pihdf.__version__)\n\n' s += 'dn = ' + mfdo.module_name + '(IMPL=1)\n' sparams = '' if mfdo.parameters != []: sparams += ', params={' for p in mfdo.parameters: sparams += '"' + p["name"] + '":' + p["value"] + ', ' sparams = sparams[:-2] + '}'# remove the last comma s += 'dn.convert(hdl="verilog"' + sparams + ')\n' s += 'dn.convert(hdl="vhdl"' + sparams + ')\n' s += 'dn.clean()\n' s.write(filename, overwrite = mfdo.overwrite)