Example #1
0
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)
Example #2
0
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)
Example #3
0
    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)
Example #4
0
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)
Example #5
0
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)
Example #6
0
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
Example #7
0
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
Example #8
0
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)
Example #9
0
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)
Example #10
0
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)
Example #11
0
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')
Example #12
0
    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)
Example #13
0
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)
Example #14
0
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)
Example #15
0
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)
Example #16
0
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)
Example #17
0
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)
Example #18
0
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)
Example #19
0
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)
Example #20
0
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)
Example #21
0
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)
Example #22
0
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)
Example #23
0
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)
Example #24
0
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)
Example #25
0
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)