def print_compile_list_file(mfdo): '''| | Create 'compile_list.txt' file containing a default list of verilog files used in case of co-simulation | All verilog files, which are part of the MyHDL design but are not auto-generated must be specified in this 'compile_list.txt' file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/compile_list.txt' filepath = os.getcwd() + '/' + mfdo.c_path + '/' + mfdo.src_path s += mfdo.module_name + '_top.v\n' if mfdo.verilog != {}: ls = extractFileNames(filename, mfdo) if ls == []: if mfdo.verilog["path"] == '': s += filepath + '/' + mfdo.module_name + '.v\n' else: s += filepath + '/' + mfdo.verilog["name"] + '.v\n' else: for l in ls: s += filepath + l + '\n' s += 'tb_' + mfdo.module_name + '_top.v\n' s.write(filename, overwrite = mfdo.overwrite)
def print_compile_list_file(mfdo): '''| | Create 'compile_list.txt' file containing a default list of verilog files used in case of co-simulation | All verilog files, which are part of the MyHDL design but are not auto-generated must be specified in this 'compile_list.txt' file |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/compile_list.txt' filepath = os.getcwd() + '/' + mfdo.c_path + '/' + mfdo.src_path s += mfdo.module_name + '_top.v\n' if mfdo.verilog != {}: ls = extractFileNames(filename, mfdo) if ls == []: if mfdo.verilog["path"] == '': s += filepath + '/' + mfdo.module_name + '.v\n' else: s += filepath + '/' + mfdo.verilog["name"] + '.v\n' else: for l in ls: s += filepath + l + '\n' s += 'tb_' + mfdo.module_name + '_top.v\n' s.write(filename, overwrite=mfdo.overwrite)
def generate(self, module_name): '''| | Generate the module design directory tree and files |________''' # Create the project directory structure os.makedirs(self.c_path + '/' + self.src_path) os.makedirs(self.c_path + '/' + self.out_path) os.makedirs(self.c_path + '/' + self.test_path) os.makedirs(self.c_path + '/' + self.test_path + '/vectors') mylog.head("Generating design files: " + module_name) # Generate empty _init_ files StrBuilder().write(self.c_path + '/__init__.py', overwrite=True) StrBuilder().write(self.c_path + '/' + self.src_path + '/__init__.py', overwrite=True) StrBuilder().write(self.c_path + '/' + self.test_path + '/__init__.py', overwrite=True) # git hack StrBuilder().write(self.c_path + '/' + self.out_path + '/.gitignore', overwrite=True) StrBuilder().write(self.c_path + '/' + self.test_path + '/vectors/.gitignore', overwrite=True) copy_custom_interfaces(self) print_module_class_file(self) print_btest_file(self) print_utest_file(self) print_compile_list_file(self) if self.modules == []: print_beh_file(self) if self.verilog != {}: if self.verilog["path"] == '': # Generate a verilog file containing only the interface signals. # Implementation to be provided by the designer. print_verilog_file(self) else: # A third-party verilog module to be integrated filename = self.verilog["path"] + '/' + self.verilog[ "name"] + '.v' print_wrap_file(self, filename) shutil.copyfile( filename, self.c_path + '/src/' + self.verilog["name"] + '.v') else: print_rtl_file(self) else: print_beh_file(self) print_rtl_file(self)
def print_gtkw_file(mfdo, cosim = False): '''| | GTKW file to visualize vcd traces from simulation |________''' str_cosim = '' dut = mfdo.module_name + "_top" + '.' if cosim: dut = "tb_" + mfdo.module_name + "_top" + ".dut." str_cosim = '_cosim' s = StrBuilder() stmp = str_cosim + ".gtkw" if cosim else ".gtkw" filename = mfdo.c_path + '/' + mfdo.test_path + '/' + mfdo.module_name + stmp try: with open(filename) as f: mylog.info("File '%s' found. It will NOT be updated!" % filename) except IOError as e: s += '[dumpfile] "' + mfdo.c_path + '/' + mfdo.module_name + '/out/' + mfdo.module_name + '_top' + str_cosim + '.vcd"\n' s += '[savefile] "' + mfdo.c_path + '/' + mfdo.module_name + '/test/' + mfdo.module_name + '_top' + str_cosim + '.gtkw"\n' s += "[timestart] 0\n" s += "[pos] -1 -1\n" s += "[treeopen] tb_" + mfdo.module_name + "_top" + ".\n" s += "[sst_expanded] 1\n" s += dut + mfdo.Reset["name"] + "\n" s += dut + mfdo.Clock["name"] + "\n" # print the interface signals for i in mfdo.interfaces: j = mfdo.getInterfaceObj(i) iname = i["name"] + '_' if len(j) > 1 else '' for k in j: xtra = 'rtl.' if not cosim else '' s += "-\n" cname = '_' + k.inst_name.upper() if len(j) > 1 else '' if k.direction == 1: s += "-" + i["name"].upper() + cname + " (OUT)\n" else: s += "-" + i["name"].upper() + cname + " (IN)\n" for sigName, sigLen in zip(k.get_sig_names(), k.get_sig_lens()): ss = "[" + str(sigLen-1) + ":0]" if (sigLen > 1) else '' s += dut + xtra + iname + k.inst_name + '_' + sigName + ss + "\n" s.write(filename, overwrite=True)
def update_beh_file(mfdo): '''| | Update <module_name>_beh.py file containing custom code used to model behavior |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_beh.py" with open(filename) as f_old: for line in f_old: if line.startswith("def " + mfdo.module_name): if mfdo.interfaces or mfdo.parameters: s += 'def ' + mfdo.module_name + '_beh(' for i in mfdo.interfaces: s += s.noIndent() + i["name"] + ', ' for p in mfdo.parameters: s += s.noIndent() + p["name"] + ', ' s = s-2 + (s.noIndent() + '):\n') else: # the interface and parameter lists are empty s += 'def ' + mfdo.module_name + '_beh():\n' else: s += line s.write(filename, overwrite = mfdo.overwrite)
def print_custom_interfaces_file(mfdo): '''| | TODO: OBSOLETE. Create 'interfaces.py' file containing custom fields interfaces defined in the .json file. | Comand 'update' modifies this file as well. |________''' if mfdo.custom_interfaces == []: return s = StrBuilder() filename = mfdo.c_path + "/interfaces.py" ss = '' indent = 0 for interface in mfdo.custom_interfaces: for tag in interface.keys(): if tag == 'name': sss = interface[tag] + ' = [' indent = len(sss) * ' ' ss += sss if tag == 'fields': for fields in interface[tag]: ss += '("' + fields["name"] + '", ' + fields[ "type"] + '),\n' + indent ss = ss[:-len(indent) - 2] + ']\n' # removes the last comma ss += '#-----------------------------------------------------------\n\n' s += "from myhdl import *\n\n" s += ss s.write(filename, overwrite=True) # make the interface visible in pihdf custom_interfaces = imp.load_source('interfaces', filename) for iname in dir(custom_interfaces): itype = getattr(custom_interfaces, iname) if isinstance(itype, list): sys._getframe(1).f_globals[iname] = itype
def print_custom_interfaces_file(mfdo): '''| | TODO: OBSOLETE. Create 'interfaces.py' file containing custom fields interfaces defined in the .json file. | Comand 'update' modifies this file as well. |________''' if mfdo.custom_interfaces == []: return s = StrBuilder() filename = mfdo.c_path + "/interfaces.py" ss = '' indent = 0 for interface in mfdo.custom_interfaces: for tag in interface.keys(): if tag == 'name': sss = interface[tag] + ' = [' indent = len(sss) * ' ' ss += sss if tag == 'fields': for fields in interface[tag]: ss += '("' + fields["name"] + '", ' + fields["type"] + '),\n' + indent ss = ss[:-len(indent)-2] + ']\n' # removes the last comma ss += '#-----------------------------------------------------------\n\n' s += "from myhdl import *\n\n" s += ss s.write(filename, overwrite=True) # make the interface visible in pihdf custom_interfaces = imp.load_source('interfaces', filename) for iname in dir(custom_interfaces): itype = getattr(custom_interfaces, iname) if isinstance(itype, list): sys._getframe(1).f_globals[iname] = itype
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_beh_file(mfdo): '''| | Create <module_name>_beh.py file. It is an empty (template) file used to model behavior |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.src_path + '/' + mfdo.module_name + "_beh.py" if mfdo.interfaces or mfdo.parameters: s += 'def ' + mfdo.module_name + '_beh(' for i in mfdo.interfaces: s += s.noIndent() + i["name"] + ', ' for p in mfdo.parameters: s += s.noIndent() + p["name"] + ', ' s = s-2 + (s.noIndent() + '):\n') else: # we start without a .json file, so the interface and parameter lists are empty s += 'def ' + mfdo.module_name + '_beh():\n' s += s.indent() + s.header_comment('Specify the behavior, describe data processing; there is no notion of clock. ' + \ 'Access the in/out interfaces via get() and append() methods. ' + \ 'The "' + mfdo.module_name + '_beh" function does not return values.') s.newLine() s += 'print "Warning: Behavior model not implemented yet!"\n\n' 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 copy_custom_interfaces(mfdo): '''| | Copy the specified custom interfaces to module/imp/ directory. |________''' if mfdo.custom_interfaces == []: return m_path = mfdo.c_path + '/imp/' if os.path.exists(m_path): # In case of command 'update' shutil.rmtree(m_path, ignore_errors=True) os.makedirs(m_path) StrBuilder().write(m_path + '__init__.py', overwrite=True) for p in mfdo.custom_interfaces: pfile = mfdo.c_path + '/' + p['file'] shutil.copy(pfile, m_path + p['name'] + '.py')
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_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_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_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_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_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_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_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_dotty_file(mfdo): '''| | Create <module_name>.dot, a dotty graph representing the connections between the modules of a structured design |________''' s = StrBuilder() filename = mfdo.c_path + '/' + mfdo.module_name + ".dot" my_graph = [] for i in mfdo.interfaces: if "direction" in i: if i["direction"]=="IN": my_graph.append([i["name"], "IN", '']) elif i["direction"]=="OUT": my_graph.append([i["name"], '', "OUT"]) else: # TODO: Bus interface mylog.warn("Top-level interface '{:}' has no direction! This interface will not be present in the .dot file!".format(i["name"])) #my_graph.append([i["name"], '', '']) for i in mfdo.local_interfaces: my_graph.append([i["name"], '', '']) # What about parameters? # What about single source multiple destinations? for m in mfdo.modules: for c in m["connections"]: for i in my_graph: if c["connect_to"] == i[0]: my_position = 1 if c["direction"]=='OUT' else 2 i[my_position] = m["name"] # Perform some checks on the graph errs = False for e in my_graph: if e[1]=='': mylog.warn("Interface '{:}' has destination ({:}) but no source!".format(e[0],e[2])) e[1] = "ERR_SRC" errs = True if e[2]=='': mylog.warn("Interface '{:}' has source ({:}) but no destination!".format(e[0],e[1])) e[2] = "ERR_DST" errs = True # Consolidate all in and out edges between two nodes into single in and single out edge my_new_graph = [] my_dict = {} for e in my_graph: my_name = e[0] my_dst = e[1] my_src = e[2] my_new_name = '' for ee in my_graph: if ee[1] == my_dst and ee[2] == my_src: my_new_name += ee[0] + "\\n" if not (my_dst,my_src) in my_dict: my_dict[(my_dst,my_src)]=1 my_new_graph.append([my_new_name, my_dst, my_src]) s += 'digraph ' + mfdo.module_name + ' {\n' s += s.indent() + 'bgcolor=white\n' # s += 'splines=compound;\n' # s += 'splines=true\n' s += 'rankdir=LR;\n' if errs: s += 'node [shape=ellipse, style=filled, color=orange]; ERR_SRC ERR_DST;\n' s += 'node [shape=doublecircle, style=filled, color=lightgray]; IN OUT;\n' s += 'node [shape=ellipse]; IN OUT;\n' for i in my_new_graph: s += i[1] + ' -> ' + i[2] + ' [ label = "' + i[0] + '" ];\n' s += '}\n' # s += 'a1 -> b3 [dir=both color="red:blue"];\n' # s += 'b2 -> a3 [dir=none color="green:red;0.25:blue"];\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_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)