Пример #1
0
 def build_con_size_bsh_closure(target, source, env):
     liGraph = LIGraph(li_module.parseLogfiles(source))
     # Should have only one module...
     if(len(liGraph.modules) == 0):
         bshModule = LIModule(module.name, module.name)
     else:
         bshModule = liGraph.modules.values()[0]
     bsh_handle = open(str(target[0]), 'w')
     wrapper_gen_tool.generateConnectionBSH(bshModule, bsh_handle)
     bsh_handle.close()
Пример #2
0
 def build_con_size_bsh_closure(target, source, env):
     liGraph = LIGraph(li_module.parseLogfiles(source))
     # Should have only one module...
     if (len(liGraph.modules) == 0):
         bshModule = LIModule(module.name, module.name)
     else:
         bshModule = liGraph.modules.values()[0]
     bsh_handle = open(str(target[0]), 'w')
     wrapper_gen_tool.generateConnectionBSH(
         bshModule, bsh_handle)
     bsh_handle.close()
Пример #3
0
                def build_synth_stub(target, source, env):
                    liGraph = LIGraph(li_module.parseLogfiles(source))
                    # Should have only one module...
                    if(len(liGraph.modules) == 0):
                        synthModule = LIModule(module.name, module.name)
                    else:
                        synthModule = liGraph.modules.values()[0]

                    synth_handle = open(target[0].path, 'w')
                    wrapper_gen_tool.generateSynthWrapper(synthModule,
                                                          synth_handle,
                                                          moduleList.localPlatformName,
                                                          moduleType=module.interfaceType,
                                                          extraImports=module.extraImports,
                                                          synthBoundaryModule = module)
                    synth_handle.close()
Пример #4
0
                def build_synth_stub(target, source, env):
                    liGraph = LIGraph(li_module.parseLogfiles(source))
                    # Should have only one module...
                    if (len(liGraph.modules) == 0):
                        synthModule = LIModule(module.name, module.name)
                    else:
                        synthModule = liGraph.modules.values()[0]

                    synth_handle = open(target[0].path, 'w')
                    wrapper_gen_tool.generateSynthWrapper(
                        synthModule,
                        synth_handle,
                        moduleList.localPlatformName,
                        moduleType=module.interfaceType,
                        extraImports=module.extraImports,
                        synthBoundaryModule=module)
                    synth_handle.close()
Пример #5
0
    def cutTreeBuild(self, state, target, source, env):
        pipeline_debug = self.parent.pipeline_debug
        boundary_logs = state['boundary_logs']
        moduleList = state['moduleList']
        area_constraints = state['area_constraints']

        # If we got a graph from the first pass, merge it in now.
        if (self.getFirstPassLIGraph is None):
            liGraph = LIGraph(li_module.parseLogfiles(boundary_logs))
        else:
            #cut_tree_build may modify the first pass graph, so we need
            #to make a copy
            liGraph = LIGraph([])
            firstPassGraph = self.getFirstPassLIGraph
            # We should ignore the 'PLATFORM_MODULE'
            liGraph.mergeModules(bsv_tool.getUserModules(firstPassGraph))

            if (area_constraints):
                area_constraints.loadAreaConstraintsPlaced()

        synth_handle = open(state['tree_file_synth'].path,'w')
        wrapper_handle = open(state['tree_file_wrapper'].path,'w')
        state['wrapper_handle'] = wrapper_handle

        fileID = 0
        for tree_file in [wrapper_handle, synth_handle]:
            fileID = fileID + 1
            tree_file.write("// Generated by BSVSynthTreeBuilder.py\n")
            tree_file.write("`ifndef BUILD_" + str(fileID) +  "\n") # these may not be needed
            tree_file.write("`define BUILD_" + str(fileID) + "\n")
            tree_file.write('import Vector::*;\n')
            wrapper_gen_tool.generateWellKnownIncludes(tree_file)
            tree_file.write('// import non-synthesis public files\n')
            tree_file.write('`include "build_tree_compile.bsv"\n')

        #If we are only building logs, we don't really require the build tree. 
        if(self.parent.BUILD_LOGS_ONLY):

            wrapper_handle.write("\n\n(*synthesize*)\n")
            wrapper_handle.write("module mk_build_tree_Wrapper#(Reset baseReset) (Reg#(Bit#(1)));\n")
            wrapper_handle.write("    let m <- mkRegU();\n")
            wrapper_handle.write("    return m;\n")
            wrapper_handle.write("endmodule\n")

            synth_handle.write("module build_tree#(Reset baseReset) (Reg#(Bit#(1)));\n")
            synth_handle.write("    let m <- mkRegU();\n")
            synth_handle.write("    return m;\n")
            synth_handle.write("endmodule\n")

            for tree_file in [wrapper_handle, synth_handle]:

                tree_file.write("// Log build only.  This space intentionally left blank.\n")
                tree_file.write("`endif\n")
                tree_file.close()
            return

        # include all the dependencies in the graph in the wrapper.
        for module in sorted(liGraph.graph.nodes(), key=lambda module: module.name):
            wrapper_handle.write('import ' + module.name + '_Wrapper::*;\n')

        wrapper_handle.write('module mk_empty_Wrapper#(Reset baseReset) (SOFT_SERVICES_SYNTHESIS_BOUNDARY#(0,0,0,0,0, Empty)); return ?; endmodule\n')

        if (pipeline_debug != 0):
            print "LIGraph: " + str(liGraph)

        # Top module has a special, well-known name for stub gen.
        # unless there is only one module in the graph.
        expected_wrapper_count = len(boundary_logs) - 2
        if(not self.getFirstPassLIGraph is None):
            expected_wrapper_count = len(self.getFirstPassLIGraph.modules) - 2

        module_names = [ "__TREE_MODULE__" + str(id) for id in range(expected_wrapper_count)] + ["build_tree"]

        # partition the top level LIM graph to produce a tree of
        # latency insensitive modules.  If there is only a
        # single module, we need to add a vestigial empty module
        # to the graph. This situation only occurs in a handful
        # of multifpga modules.

        # In the first LIM pass, we need to expose all
        # connections.  Doing so through Bluespec results in
        # object code changes, which are unacceptable.  Therefore,
        # We optionally trim the build tree.

        # assign top_module some default.
        top_module = None
        if(self.parent.BUILD_LOGS_ONLY == 0):
            if (len(liGraph.graph.nodes()) == 1):
                # Singleton Modules still need to pass through the
                # trimming phase to remove references to unmatched
                # channels.  If there's only one module, introduce
                # a trivial second module. Having no LI modules is
                # handled correctly.
                liGraph.mergeModules([LIModule("empty", "empty")])

            state['empty_count'] = 0

            # Cut the build into a tree of merged wrappers.  We could merge
            # all of them in a single level, but the Bluespec compiler winds
            # up being too slow.  A hierarchy compiles more efficiently.
            top_module = self.cutRecurse(state, liGraph, 1, module_names)

            # Generate the code for the cut tree.
            self.emitWrappersRecurse(state, top_module, 1)


            # walk the top module to annotate area group paths
            def annotateAreaGroups(treeModule, verilogPath):
                if (isinstance(treeModule, TreeModule)):
                    if (not treeModule.children is None):
                        for child in treeModule.children:
                            annotateAreaGroups(child,verilogPath + getInstanceName(treeModule.name) + treeModule.seperator)
                else:
                    # fill in the area group data structure
                    if (area_constraints and (treeModule.name in area_constraints.constraints)):
                        # We always have synthesis boundaries at the bottom of the tree.
                        area_constraints.constraints[treeModule.name].sourcePath = \
                            verilogPath + getInstanceName(treeModule.name)


            # If necessary, dump out the area groups file.
            if(not self.getFirstPassLIGraph is None):
                # Also load up areaGroups
                # top module has a funny recursive base case.  Fix it here.

                # It is possible the the top_module will be a singleton LI module.
                if(isinstance(top_module,TreeModule)):
                    for child in top_module.children:
                        annotateAreaGroups(child, 'm_sys_sys_syn_m_mod/')
                else:
                    annotateAreaGroups(top_module, 'm_sys_sys_syn_m_mod/')

                # Annotate physical platform. This is sort of a hack.
                if (area_constraints):
                    n = moduleList.localPlatformName + "_platform"
                    if (n in area_constraints.constraints):
                        # Vivado has difficulties in placing platform
                        # code in the presence of device driver area
                        # groups.  We optionally disable the
                        # generation of platform area groups here.
                        if (moduleList.getAWBParam('area_group_tool', 'AREA_GROUPS_GROUP_PLATFORM_CODE')):
                            area_constraints.constraints[n].sourcePath = "m_sys_sys_vp_m_mod"
                        else:
                            area_constraints.constraints[n].sourcePath = None

                    area_constraints.storeAreaConstraints()

        # In multifpga builds, we may have some leftover modules
        # due to the way that the LIM compiler currently
        # operates. We emit dummy modules here to make
        # downstream tools happy.  This can be removed once we
        # reorganize the multifpga compiler.

        for module in module_names:
            wrapper_handle.write("\n\n(*synthesize*)\n")
            wrapper_handle.write("module mk_" + module + '_Wrapper' + " (Reg#(Bit#(1)));\n")
            wrapper_handle.write("    let m <- mkRegU();\n")
            wrapper_handle.write("    return m;\n")
            wrapper_handle.write("endmodule\n")

        # we need to create a top level wrapper module to
        # re-monadize the soft connections so that the platform
        # compiles correctly

        # however the synth file depends only on the build tree wrapper
        # if we have a single module, it will be the case that
        # this module and not a tree build will be returned. Handle both.
        if(top_module is None):
            # If we have no top module, then the build tree is empty.
            synth_handle.write("\n\nmodule [Connected_Module] build_tree();\n")
            synth_handle.write("    //this space intentionally left blank\n")
            synth_handle.write("endmodule\n")
        else:
            wrapper_gen_tool.generateTopSynthWrapper(top_module,
                                                     synth_handle,
                                                     moduleList.localPlatformName,
                                                     areaConstraints = area_constraints)

        for tree_file in [synth_handle, wrapper_handle]:
            tree_file.write("`endif\n")
            tree_file.close()

        return None