Ejemplo n.º 1
0
def linkNGC(moduleList, module, firstPassLIGraph):
    return li_module.linkFirstPassObject(moduleList, module, firstPassLIGraph, 'GEN_NGCS', 'GEN_NGCS')
Ejemplo n.º 2
0
  def __init__(self, moduleList, isPrimaryBuildTarget):

    # if we have a deps build, don't do anything...
    if(moduleList.isDependsBuild):
        return

    APM_NAME = moduleList.env['DEFS']['APM_NAME']
    BSC = moduleList.env['DEFS']['BSC']
    inc_paths = moduleList.swIncDir # we need to depend on libasim

    self.firstPassLIGraph = wrapper_gen_tool.getFirstPassLIGraph()

    # This is not correct for LIM builds and needs to be fixed. 
    TMP_BSC_DIR = moduleList.env['DEFS']['TMP_BSC_DIR']
    ALL_DIRS_FROM_ROOT = moduleList.env['DEFS']['ALL_HW_DIRS']
    ALL_BUILD_DIRS_FROM_ROOT = model.transform_string_list(ALL_DIRS_FROM_ROOT, ':', '', '/' + TMP_BSC_DIR)
    ALL_LIB_DIRS_FROM_ROOT = ALL_DIRS_FROM_ROOT + ':' + ALL_BUILD_DIRS_FROM_ROOT


    # Due to the bluespec linker, for LI second pass builds, the final
    # verilog link step must occur in a different directory than the
    # bsc object code wrapper compilation step.  However, non-LIM
    # linker builds need to build in the original .bsc directory to
    # pick up VPI.
    vexe_vdir = moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + moduleList.env['DEFS']['ROOT_DIR_MODEL'] + '/' + moduleList.env['DEFS']['TMP_BSC_DIR'] 
    if(not self.firstPassLIGraph is None):
        vexe_vdir = vexe_vdir + '_vlog'

    if not os.path.isdir(vexe_vdir):
        os.mkdir(vexe_vdir)

    LI_LINK_DIR = ""
    if (not self.firstPassLIGraph is None):
        LI_LINK_DIR = model.get_build_path(moduleList, moduleList.topModule) + "/.li/"
        inc_paths += [LI_LINK_DIR]
        ALL_LIB_DIRS_FROM_ROOT = LI_LINK_DIR + ':' +  ALL_LIB_DIRS_FROM_ROOT

    liCodeType = ['VERILOG', 'GIVEN_VERILOG_HS', 'GEN_VPI_CS', 'GEN_VPI_HS']

    # This can be refactored as a function.

    if (not self.firstPassLIGraph is None):     
        for moduleName in self.firstPassLIGraph.modules:                       
            moduleObject = self.firstPassLIGraph.modules[moduleName]
            # we also need the module list object
            moduleListObject = moduleList.modules[moduleName]
            for codeType in liCodeType:
                # If we're linking, clean out any previous code dependencies.  These are guaranteed not to be used. 
                moduleListObject.moduleDependency[codeType] = []
                li_module.linkFirstPassObject(moduleList, moduleListObject, self.firstPassLIGraph, codeType, codeType, linkDirectory=vexe_vdir)
                 
                
    bsc_version = bsv_tool.getBluespecVersion()

    ldflags = ''
    for ld_file in moduleList.getAllDependenciesWithPaths('GIVEN_BLUESIM_LDFLAGSS'):
      ldHandle = open(moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + ld_file, 'r')
      ldflags += ldHandle.read() + ' '    

    BSC_FLAGS_VERILOG = '-steps 10000000 +RTS -K1000M -RTS -keep-fires -aggressive-conditions -wait-for-license -no-show-method-conf -no-opt-bool -licenseWarning 7 -elab -show-schedule ' + ldflags + ' -verilog -v -vsim iverilog '

    # Build in parallel.
    n_jobs = moduleList.env.GetOption('num_jobs')
    if (bsc_version >= 30006):
        BSC_FLAGS_VERILOG += '-parallel-sim-link ' + str(n_jobs) + ' '

    for path in inc_paths:
        BSC_FLAGS_VERILOG += ' -I ' + path + ' ' #+ '-Xv -I' + path + ' '

    LDFLAGS = moduleList.env['DEFS']['LDFLAGS']
    TMP_BSC_DIR = moduleList.env['DEFS']['TMP_BSC_DIR']
    ROOT_WRAPPER_SYNTH_ID = 'mk_' + moduleList.env['DEFS']['ROOT_DIR_MODEL'] + '_Wrapper'

    vexe_gen_command = \
        BSC + ' ' + BSC_FLAGS_VERILOG + ' -vdir ' + vexe_vdir + ' -simdir ' + vexe_vdir + ' -bdir ' + vexe_vdir +' -p +:' +  ALL_LIB_DIRS_FROM_ROOT + ' -vsearch +:' + ALL_LIB_DIRS_FROM_ROOT + ' ' + \
        ' -o $TARGET' 

    if (bsc_version >= 13013):
        # 2008.01.A compiler allows us to pass C++ arguments.
        if (model.getDebug(moduleList)):
            vexe_gen_command += ' -Xc++ -O0'
        else:
            vexe_gen_command += ' -Xc++ -O1'

        # g++ 4.5.2 is complaining about overflowing the var tracking table

        if (model.getGccVersion() >= 40501):
             vexe_gen_command += ' -Xc++ -fno-var-tracking-assignments'

    defs = (software_tool.host_defs()).split(" ")
    for definition in defs:
        vexe_gen_command += ' -Xc++ ' + definition + ' -Xc ' + definition

    # Hack to link against pthreads.  Really we should have a better solution.
    vexe_gen_command += ' -Xl -lpthread '

    # construct full path to BAs
    def modify_path(str):
        array = str.split('/')
        file = array.pop()
        return  moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + '/'.join(array) + '/' + TMP_BSC_DIR + '/' + file 


    # Use systemverilog 2005
    if(moduleList.getAWBParam('verilog_tool', 'ENABLE_SYSTEM_VERILOG')):
        vexe_gen_command += ' -Xv -g2005-sv '

    # Allow .vh/.sv file extensions etc.
    # vexe_gen_command += ' -Xv -Y.vh -Xv -Y.sv '

    # Bluespec requires that source files terminate the command line.
    vexe_gen_command += '-verilog -e ' + ROOT_WRAPPER_SYNTH_ID + ' ' +\
                        moduleList.env['DEFS']['BDPI_CS']

    if (model.getBuildPipelineDebug(moduleList) != 0):
        for m in moduleList.getAllDependencies('BA'):
            print 'BA dep: ' + str(m)
        for m in moduleList.getAllDependencies('VERILOG'):
            print 'VL dep: ' + str(m)
        for m in moduleList.getAllDependencies('VHDL'):
            print 'BA dep: ' + str(m)


    # Generate a thin wrapper around the verilog executable.  This
    # wrapper is used to address a problem in iverilog in which the
    # simulator does not support shared library search paths.  The
    # current wrapper only works for iverilog.  Due to brokeness in
    # the iverilog argument parser, we must construct a correct
    # iverilog command line by analyzing its compiled script. Also,
    # this script is not passing through the arguments that it should
    # be passing through. 
    def generate_vexe_wrapper(target, source, env):
        wrapper_handle = open(str(target[0]),'w')
        wrapper_handle.write('#!/usr/bin/perl\n')
        wrapper_handle.write('# generated by verilog.py\n') 
        wrapper_handle.write('$platform = $ENV{"PLATFORM_DIRECTORY"};\n')
        wrapper_handle.write('@script = `cat $platform/' + TMP_BSC_DIR + '/' + APM_NAME + '_hw.exe' + '`;\n')   
        wrapper_handle.write('$script[0] =~ s/#!/ /g;\n')
        wrapper_handle.write('$vvp = $script[0];\n')
        wrapper_handle.write('chomp($vvp);\n')
        wrapper_handle.write('exec("$vvp -m$platform/directc_mk_model_Wrapper.so $platform/' + TMP_BSC_DIR + '/' + APM_NAME + '_hw.exe' + ' +bscvcd \$* ");\n')
        wrapper_handle.close()
 
    def modify_path_ba_local(path):
        return bsv_tool.modify_path_ba(moduleList, path)

    # Bluesim builds apparently touch this code. This control block
    # preserves their behavior, but it is unclear why the verilog build is 
    # involved.
    if (isPrimaryBuildTarget):
        vbinDeps = []

        # If we got a lim graph, we'll pick up many of our dependencies from it. 
        # These were annotated in the top module above. Really, this seems unclean.
        # we should build a graph during the second pass and just use it.
        if(not self.firstPassLIGraph is None):
            # Collect linked dependencies for every module
            for moduleName in self.firstPassLIGraph.modules:
                moduleListObject = moduleList.modules[moduleName]
                vbinDeps += moduleList.getDependencies(moduleListObject, 'VERILOG') + moduleList.getDependencies(moduleListObject, 'GIVEN_VERILOG_HS') + moduleList.getDependencies(moduleListObject, 'GEN_VPI_HS') + moduleList.getDependencies(moduleListObject, 'GEN_VPI_CS') + moduleList.getDependencies(moduleListObject, 'VHDL') + moduleList.getDependencies(moduleListObject, 'BA') + moduleList.getDependencies(moduleListObject, 'GEN_BAS')

            vbinDeps += moduleList.getDependencies(moduleList.topModule, 'VERILOG') + moduleList.getDependencies(moduleList.topModule, 'GIVEN_VERILOG_HS') + moduleList.getDependencies(moduleList.topModule, 'GEN_VPI_HS') + moduleList.getDependencies(moduleList.topModule, 'GEN_VPI_CS') +moduleList.getDependencies(moduleList.topModule, 'VHDL') + moduleList.getDependencies(moduleList.topModule, 'BA') + map(modify_path_ba_local, moduleList.getModuleDependenciesWithPaths(moduleList.topModule, 'GEN_BAS'))

        # collect dependencies from all awb modules
        else:
            vbinDeps += moduleList.getAllDependencies('VERILOG') + moduleList.getAllDependencies('VHDL') + moduleList.getAllDependencies('BA') + map(modify_path_ba_local, moduleList.getAllDependenciesWithPaths('GEN_BAS'))


        vbin = moduleList.env.Command(
            TMP_BSC_DIR + '/' + APM_NAME + '_hw.exe',
            vbinDeps,
            [ vexe_gen_command,
              SCons.Script.Delete('directc.sft') ])

        vexe = moduleList.env.Command(
            APM_NAME + '_hw.exe',
            vbin,
            [  generate_vexe_wrapper,
              '@chmod a+x $TARGET',
            SCons.Script.Delete(APM_NAME + '_hw.errinfo') ])


        moduleList.topDependency = moduleList.topDependency + [vexe]

    else:
        vbinDeps = moduleList.getAllDependencies('VERILOG') + moduleList.getAllDependencies('VHDL') + moduleList.getAllDependencies('BA') + map(modify_path_ba_local, moduleList.getAllDependenciesWithPaths('GEN_BAS'))

        vbin = moduleList.env.Command(
            TMP_BSC_DIR + '/' + APM_NAME + '_hw.vexe',
            vbinDeps,
            [ vexe_gen_command,
              SCons.Script.Delete('directc.sft') ])


        vexe = moduleList.env.Command(
            APM_NAME + '_hw.vexe',
            vbin,
            [ generate_vexe_wrapper,
              '@chmod a+x $TARGET',
              SCons.Script.Delete(APM_NAME + '_hw.exe'),
            SCons.Script.Delete(APM_NAME + '_hw.errinfo') ])

    moduleList.env.Alias('vexe', vexe)
Ejemplo n.º 3
0
def linkNGC(moduleList, module, firstPassLIGraph):
    return li_module.linkFirstPassObject(moduleList, module, firstPassLIGraph, 'GEN_NGCS', 'GEN_NGCS')
Ejemplo n.º 4
0
  def __init__(self, moduleList):

    # if we have a deps build, don't do anything...
    if(moduleList.isDependsBuild):
        return

    self.firstPassLIGraph = wrapper_gen_tool.getFirstPassLIGraph()

    # A collector for all of the checkpoint objects we will gather/build in the following code. 
    dcps = []

    # Construct the tcl file 
    self.part = moduleList.getAWBParam('physical_platform_config', 'FPGA_PART_XILINX')

    apm_name = moduleList.compileDirectory + '/' + moduleList.apmName

    self.paramTclFile = moduleList.topModule.moduleDependency['PARAM_TCL'][0]

    # If the TMP_XILINX_DIR doesn't exist, create it.
    if not os.path.isdir(moduleList.env['DEFS']['TMP_XILINX_DIR']):
        os.mkdir(moduleList.env['DEFS']['TMP_XILINX_DIR'])

    # Gather Tcl files for handling constraints.
    self.tcl_headers = []
    if(len(moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_HEADERS')) > 0):
        self.tcl_headers = map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_HEADERS'))

    self.tcl_defs = []
    if(len(moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_DEFINITIONS')) > 0):
        self.tcl_defs = map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_DEFINITIONS'))

    self.tcl_funcs = []
    if(len(moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_FUNCTIONS')) > 0):
        self.tcl_funcs = map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_FUNCTIONS'))

    self.tcl_algs = []
    if(len(moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_ALGEBRAS')) > 0):
        self.tcl_algs = map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_VIVADO_TCL_ALGEBRAS'))

    self.tcl_bmms = []
    if(len(moduleList.getAllDependencies('GIVEN_XILINX_BMMS')) > 0):
        self.tcl_bmms = moduleList.getAllDependencies('GIVEN_XILINX_BMMS')

    self.tcl_elfs = []
    if(len(moduleList.getAllDependencies('GIVEN_XILINX_ELFS')) > 0):
        self.tcl_elfs = moduleList.getAllDependencies('GIVEN_XILINX_ELFS')

    self.tcl_ag = []

    #Emit area group definitions
    # If we got an area group placement data structure, now is the
    # time to convert it into a new constraint tcl. 
    self.area_group_file = moduleList.compileDirectory + '/areagroups.xdc'
    if ('AREA_GROUPS' in moduleList.topModule.moduleDependency):
        self.area_constraints = area_group_tool.AreaConstraints(moduleList)
        self.routeAG = (moduleList.getAWBParam('area_group_tool',
                                               'AREA_GROUPS_ROUTE_AG') != 0)

        # user ucf may be overridden by our area group ucf.  Put our
        # generated ucf first.
        #tcl_defs.insert(0,self.area_group_file)
        def area_group_ucf_closure(moduleList):

             def area_group_ucf(target, source, env):
                 self.area_constraints.loadAreaConstraints()
                 self.area_constraints.emitConstraintsVivado(self.area_group_file)

             return area_group_ucf

        moduleList.env.Command( 
            [self.area_group_file],
            self.area_constraints.areaConstraintsFile(),
            area_group_ucf_closure(moduleList)
            )                             



    synthDepsBase =  moduleList.getAllDependencies('GEN_VIVADO_DCPS')

    # We got a stack of synthesis results for the LI modules.  We need
    # to convert these to design checkpoints for the fast place and
    # route flow.
    ngcModules = [module for module in moduleList.synthBoundaries() if not module.liIgnore]

    for module in ngcModules + [moduleList.topModule]:   
        # did we get a dcp from the first pass?  If so, did the lim
        # graph give code for this module?  If both are true, then we
        # will link the old ngc in, rather than regenerate it. 
        if ((not self.firstPassLIGraph is None) and (module.name in self.firstPassLIGraph.modules) and (self.firstPassLIGraph.modules[module.name].getAttribute('RESYNTHESIZE') is None)):
            if (li_module.linkFirstPassObject(moduleList, module, self.firstPassLIGraph, 'GEN_VIVADO_DCPS', 'GEN_VIVADO_DCPS') is None):
                module.moduleDependency['GEN_VIVADO_DCPS'] = [self.edf_to_dcp(moduleList, module)]
            
        # it's possible that we got dcp from this compilation
        # pass. This will happen for the platform modules.
        elif (len(module.getDependencies('GEN_VIVADO_DCPS')) > 0):
            continue

        # we got neither. therefore, we must create a dcp out of the ngc.
        else:            
            module.moduleDependency['GEN_VIVADO_DCPS'] = [self.edf_to_dcp(moduleList, module)]

                        
   

    synthDeps =  moduleList.getAllDependencies('GEN_VIVADO_DCPS')

    postSynthTcl = apm_name + '.physical.tcl'

    topWrapper = moduleList.topModule.wrapperName()

    newTclFile = open(postSynthTcl, 'w')
    newTclFile.write('create_project -force ' + moduleList.apmName + ' ' + moduleList.compileDirectory + ' -part ' + self.part + ' \n')

    # To resolve black boxes, we need to load checkpoints in the
    # following order:
    # 1) topModule
    # 2) platformModule
    # 3) user program, in any order

    userModules = [module for module in moduleList.synthBoundaries() if not module.liIgnore and not module.platformModule]
    platformModules = [module for module in moduleList.synthBoundaries() if not module.liIgnore and module.platformModule]
    checkpointCommands = [] 

    if(not moduleList.getAWBParamSafe('area_group_tool', 'AREA_GROUPS_ENABLE')):
         
        for module in [moduleList.topModule] + platformModules + userModules:   
            dcps.append(module.getDependencies('GEN_VIVADO_DCPS'))
            checkpoint = model.convertDependencies(module.getDependencies('GEN_VIVADO_DCPS'))
            
            # There should only be one checkpoint here. 
            if(len(checkpoint) > 1):
                print "Error too many checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue

            if(len(checkpoint) == 0):
                print "No checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue

            newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

            
    # We're attempting the new, parallel flow. 
    else:
        # we need to issue seperate place commands.  Therefore, we attempt to place each design 

        # There may be some special area groups in platforms -- handle them
        elabAreaConstraints = area_group_tool.AreaConstraints(moduleList)
        elabAreaConstraints.loadAreaConstraintsElaborated()
        #self.area_constraints = area_group_tool.AreaConstraints(moduleList)
        for module in userModules:  
            # Did we get a placed module already?
            if((module.name in elabAreaConstraints.constraints) and ('LIBRARY_DCP' in elabAreaConstraints.constraints[module.name].attributes)):
                # we need to locate the dcp corresponding to this area group. 
                candidates = moduleList.getAllDependencies('GIVEN_VIVADO_DCPS')
                for dcpCandidate in moduleList.getAllDependencies('GIVEN_VIVADO_DCPS'):                   
                   if dcpCandidate.attributes['module'] == module.name:         
                       dcp = str(model.modify_path_hw(dcpCandidate))
                       model.dictionary_list_create_append(module.moduleDependency, 'GEN_VIVADO_PLACEMENT_DCPS', dcp)
                       dcps.append(dcp)
            else:
                dcp = self.place_dcp(moduleList, module)
                model.dictionary_list_create_append(module.moduleDependency, 'GEN_VIVADO_PLACEMENT_DCPS', dcp)
                dcps.append(dcp)

        for module in [moduleList.topModule] + platformModules:   
            checkpoint = model.convertDependencies(module.getDependencies('GEN_VIVADO_DCPS'))
            dcps.append(checkpoint)
              
            # There should only be one checkpoint here. 
            if(len(checkpoint) > 1):
                print "Error too many checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue

            if(len(checkpoint) == 0):
                print "No checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue

            newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

        # We can have parent/child relationships in the user modules.
        # Vivado requires that checkpoints be read in topological
        # order.
        def isBlackBox(module):
            if(self.firstPassLIGraph.modules[module.name].getAttribute('BLACK_BOX_AREA_GROUP')):
                return 1
            return 0


        for module in sorted(userModules, key=isBlackBox):   
            checkpoint = model.convertDependencies(module.getDependencies('GEN_VIVADO_PLACEMENT_DCPS'))

            # There should only be one checkpoint here. 
            if(len(checkpoint) > 1):
                print "Error too many checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue

            if(len(checkpoint) == 0):
                print "No checkpoints for " + str(module.name) + ":  " + str(checkpoint)  
                continue
            #read in new checkoutpoint

            newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

            emitPlatformAreaGroups = (moduleList.getAWBParam('area_group_tool',
                                                             'AREA_GROUPS_GROUP_PLATFORM_CODE') != 0)

            # platformModule refers to the main platform module, not
            # the subordinate device area groups.
            platformModule = (self.firstPassLIGraph.modules[module.name].getAttribute('BLACK_BOX_AREA_GROUP') is None) and (not self.firstPassLIGraph.modules[module.name].getAttribute('PLATFORM_MODULE') is None)

            allowAGPlatform = (not platformModule) or emitPlatformAreaGroups 

            emitDeviceGroups = (moduleList.getAWBParam('area_group_tool',
                                                       'AREA_GROUPS_PAR_DEVICE_AG') != 0)           
            allowAGDevice = (self.firstPassLIGraph.modules[module.name].getAttribute('BLACK_BOX_AREA_GROUP') is None) or emitDeviceGroups

            if (allowAGPlatform and allowAGDevice):               
                refName = module.wrapperName()
                lockPlacement = True
                lockRoute = self.routeAG
                # If this is an platform/user-defined area group, the wrapper name may be different.
                if (not self.firstPassLIGraph.modules[module.name].getAttribute('BLACK_BOX_AREA_GROUP') is None):
                    refName = elabAreaConstraints.constraints[module.name].attributes['MODULE_NAME']
                    lockPlacement = not ('NO_PLACE' in elabAreaConstraints.constraints[module.name].attributes) and lockPlacement
                    lockRoute = not ('NO_ROUTE' in elabAreaConstraints.constraints[module.name].attributes) and lockRoute

                checkpointCommands.append('if { [llength [get_cells -hier -filter {REF_NAME =~ "' + refName + '"}]] } {\n')            
                checkpointCommands.append('    puts "Locking ' + refName + '"\n')
                if (lockRoute):
                    # locking routing requires us to emit an area group. boo. 
                    ag_tcl = self.ag_constraints(moduleList, module)
                    self.tcl_ag.append(ag_tcl)
                    checkpointCommands.append('    source ' + str(ag_tcl) + '\n')
                    checkpointCommands.append('    lock_design -level routing [get_cells -hier -filter {REF_NAME =~ "' + refName + '"}]\n')            
                elif (lockPlacement):
                    checkpointCommands.append('    lock_design -level placement [get_cells -hier -filter {REF_NAME =~ "' + refName + '"}]\n')            
                checkpointCommands.append('}\n')

    given_netlists = [ moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + netlist for netlist in moduleList.getAllDependenciesWithPaths('GIVEN_NGCS') + moduleList.getAllDependenciesWithPaths('GIVEN_EDFS') ]

    for netlist in given_netlists:
        newTclFile.write('read_edif ' + netlist + '\n')

    # We have lots of dangling wires (Thanks, Bluespec).  Set the
    # following properties to silence the warnings. 
   
    newTclFile.write("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]\n")
    newTclFile.write("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]\n")

    newTclFile.write("link_design -top " + topWrapper + " -part " + self.part  + "\n")

    newTclFile.write("report_utilization -file " + apm_name + ".link.util\n")

    newTclFile.write("write_checkpoint -force " + apm_name + ".link.dcp\n")

    # lock down the area group routing.
    newTclFile.write("\n".join(checkpointCommands) + "\n")

    for elf in self.tcl_elfs:
        newTclFile.write("add_file " + model.modify_path_hw(elf) + "\n")
        newTclFile.write("set_property MEMDATA.ADDR_MAP_CELLS {" + str(elf.attributes['ref']) + "} [get_files " + model.modify_path_hw(elf) + "]\n")



    # We will now attempt to link in any bmm that we might have.
    for bmm in self.tcl_bmms:
        newTclFile.write("add_file " + model.modify_path_hw(bmm) + "\n")
        newTclFile.write("set_property SCOPED_TO_REF " + str(bmm.attributes['ref']) + " [get_files " + model.modify_path_hw(bmm) + "]\n")


 
    newTclFile.write('set IS_TOP_BUILD 1\n ')
    newTclFile.write('set IS_AREA_GROUP_BUILD 0\n ')
    newTclFile.write('set SYNTH_OBJECT ""\n')
    newTclFile.write('source ' + self.paramTclFile + '\n')

    for tcl_header in self.tcl_headers:
        newTclFile.write('source ' + tcl_header + '\n')

    for tcl_def in self.tcl_defs:
         newTclFile.write('source ' + tcl_def + '\n') 

    for tcl_func in self.tcl_funcs:
        newTclFile.write('source ' + tcl_func + '\n')

    for tcl_alg in self.tcl_algs:
        newTclFile.write('source ' + tcl_alg + '\n')

    def dumpPBlockCmd(tgt):
        return 'dumpPBlockUtilization "' + moduleList.compileDirectory + '/' + tgt + '.util"\n'

    newTclFile.write(dumpPBlockCmd('link'))
    newTclFile.write("report_timing_summary -file " + apm_name + ".map.twr\n\n")

    newTclFile.write("opt_design -directive AddRemap\n")
    newTclFile.write("report_utilization -file " + apm_name + ".opt.util\n")
    newTclFile.write(dumpPBlockCmd('opt'))
    newTclFile.write("write_checkpoint -force " + apm_name + ".opt.dcp\n\n")

    newTclFile.write("place_design -no_drc -directive WLDrivenBlockPlacement\n")
    newTclFile.write(dumpPBlockCmd('place'))

    newTclFile.write("phys_opt_design -directive AggressiveFanoutOpt\n")
    newTclFile.write("write_checkpoint -force " + apm_name + ".map.dcp\n")
    newTclFile.write(dumpPBlockCmd('phyopt'))
    newTclFile.write("report_utilization -file " + apm_name + ".map.util\n\n")

    newTclFile.write("route_design\n")
    newTclFile.write("write_checkpoint -force " + apm_name + ".par.dcp\n")
    newTclFile.write(dumpPBlockCmd('par'))
    newTclFile.write("report_timing_summary -file " + apm_name + ".par.twr\n\n")

    newTclFile.write("report_utilization -hierarchical -file " + apm_name + ".par.util\n")
    newTclFile.write("report_drc -file " + topWrapper + ".drc\n\n")
 
    newTclFile.write("write_bitstream -force " + apm_name + "_par.bit\n")

    newTclFile.close()

    # generate bitfile
    xilinx_bit = moduleList.env.Command(
      apm_name + '_par.bit',
      synthDeps + self.tcl_algs + self.tcl_defs + self.tcl_funcs + self.tcl_ag + [self.paramTclFile] + dcps + [postSynthTcl], 
      ['touch start.txt; vivado -verbose -mode batch -source ' + postSynthTcl + ' -log ' + moduleList.compileDirectory + '/postsynth.log'])


    moduleList.topModule.moduleDependency['BIT'] = [apm_name + '_par.bit']

    # We still need to generate a download script. 
    xilinx_loader.LOADER(moduleList)
Ejemplo n.º 5
0
    def __init__(self, moduleList, isPrimaryBuildTarget):

        # if we have a deps build, don't do anything...
        if (moduleList.isDependsBuild):
            return

        APM_NAME = moduleList.env['DEFS']['APM_NAME']
        BSC = moduleList.env['DEFS']['BSC']
        inc_paths = moduleList.swIncDir  # we need to depend on libasim

        self.firstPassLIGraph = wrapper_gen_tool.getFirstPassLIGraph()

        # This is not correct for LIM builds and needs to be fixed.
        TMP_BSC_DIR = moduleList.env['DEFS']['TMP_BSC_DIR']
        ALL_DIRS_FROM_ROOT = moduleList.env['DEFS']['ALL_HW_DIRS']
        ALL_BUILD_DIRS_FROM_ROOT = model.transform_string_list(
            ALL_DIRS_FROM_ROOT, ':', '', '/' + TMP_BSC_DIR)
        ALL_LIB_DIRS_FROM_ROOT = ALL_DIRS_FROM_ROOT + ':' + ALL_BUILD_DIRS_FROM_ROOT

        # Due to the bluespec linker, for LI second pass builds, the final
        # verilog link step must occur in a different directory than the
        # bsc object code wrapper compilation step.  However, non-LIM
        # linker builds need to build in the original .bsc directory to
        # pick up VPI.
        vexe_vdir = moduleList.env['DEFS'][
            'ROOT_DIR_HW'] + '/' + moduleList.env['DEFS'][
                'ROOT_DIR_MODEL'] + '/' + moduleList.env['DEFS']['TMP_BSC_DIR']
        if (not self.firstPassLIGraph is None):
            vexe_vdir = vexe_vdir + '_vlog'

        if not os.path.isdir(vexe_vdir):
            os.mkdir(vexe_vdir)

        LI_LINK_DIR = ""
        if (not self.firstPassLIGraph is None):
            LI_LINK_DIR = model.get_build_path(moduleList,
                                               moduleList.topModule) + "/.li/"
            inc_paths += [LI_LINK_DIR]
            ALL_LIB_DIRS_FROM_ROOT = LI_LINK_DIR + ':' + ALL_LIB_DIRS_FROM_ROOT

        liCodeType = [
            'VERILOG', 'GIVEN_VERILOG_HS', 'GEN_VPI_CS', 'GEN_VPI_HS'
        ]

        # This can be refactored as a function.

        if (not self.firstPassLIGraph is None):
            for moduleName in self.firstPassLIGraph.modules:
                moduleObject = self.firstPassLIGraph.modules[moduleName]
                # we also need the module list object
                moduleListObject = moduleList.modules[moduleName]
                for codeType in liCodeType:
                    # If we're linking, clean out any previous code dependencies.  These are guaranteed not to be used.
                    moduleListObject.moduleDependency[codeType] = []
                    li_module.linkFirstPassObject(moduleList,
                                                  moduleListObject,
                                                  self.firstPassLIGraph,
                                                  codeType,
                                                  codeType,
                                                  linkDirectory=vexe_vdir)

        bsc_version = bsv_tool.getBluespecVersion()

        ldflags = ''
        for ld_file in moduleList.getAllDependenciesWithPaths(
                'GIVEN_BLUESIM_LDFLAGSS'):
            ldHandle = open(
                moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + ld_file, 'r')
            ldflags += ldHandle.read() + ' '

        BSC_FLAGS_VERILOG = '-steps 10000000 +RTS -K1000M -RTS -keep-fires -aggressive-conditions -wait-for-license -no-show-method-conf -no-opt-bool -licenseWarning 7 -elab -show-schedule ' + ldflags + ' -verilog -v -vsim iverilog '

        # Build in parallel.
        n_jobs = moduleList.env.GetOption('num_jobs')
        if (bsc_version >= 30006):
            BSC_FLAGS_VERILOG += '-parallel-sim-link ' + str(n_jobs) + ' '

        for path in inc_paths:
            BSC_FLAGS_VERILOG += ' -I ' + path + ' '  #+ '-Xv -I' + path + ' '

        LDFLAGS = moduleList.env['DEFS']['LDFLAGS']
        TMP_BSC_DIR = moduleList.env['DEFS']['TMP_BSC_DIR']
        ROOT_WRAPPER_SYNTH_ID = 'mk_' + moduleList.env['DEFS'][
            'ROOT_DIR_MODEL'] + '_Wrapper'

        vexe_gen_command = \
            BSC + ' ' + BSC_FLAGS_VERILOG + ' -vdir ' + vexe_vdir + ' -simdir ' + vexe_vdir + ' -bdir ' + vexe_vdir +' -p +:' +  ALL_LIB_DIRS_FROM_ROOT + ' -vsearch +:' + ALL_LIB_DIRS_FROM_ROOT + ' ' + \
            ' -o $TARGET'

        if (bsc_version >= 13013):
            # 2008.01.A compiler allows us to pass C++ arguments.
            if (model.getDebug(moduleList)):
                vexe_gen_command += ' -Xc++ -O0'
            else:
                vexe_gen_command += ' -Xc++ -O1'

            # g++ 4.5.2 is complaining about overflowing the var tracking table

            if (model.getGccVersion() >= 40501):
                vexe_gen_command += ' -Xc++ -fno-var-tracking-assignments'

        defs = (software_tool.host_defs()).split(" ")
        for definition in defs:
            vexe_gen_command += ' -Xc++ ' + definition + ' -Xc ' + definition

        # Hack to link against pthreads.  Really we should have a better solution.
        vexe_gen_command += ' -Xl -lpthread '

        # construct full path to BAs
        def modify_path(str):
            array = str.split('/')
            file = array.pop()
            return moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + '/'.join(
                array) + '/' + TMP_BSC_DIR + '/' + file

        # Use systemverilog 2005
        if (moduleList.getAWBParam('verilog_tool', 'ENABLE_SYSTEM_VERILOG')):
            vexe_gen_command += ' -Xv -g2005-sv '

        # Allow .vh/.sv file extensions etc.
        # vexe_gen_command += ' -Xv -Y.vh -Xv -Y.sv '

        # Bluespec requires that source files terminate the command line.
        vexe_gen_command += '-verilog -e ' + ROOT_WRAPPER_SYNTH_ID + ' ' +\
                            moduleList.env['DEFS']['BDPI_CS']

        if (model.getBuildPipelineDebug(moduleList) != 0):
            for m in moduleList.getAllDependencies('BA'):
                print 'BA dep: ' + str(m)
            for m in moduleList.getAllDependencies('VERILOG'):
                print 'VL dep: ' + str(m)
            for m in moduleList.getAllDependencies('VHDL'):
                print 'BA dep: ' + str(m)

        # Generate a thin wrapper around the verilog executable.  This
        # wrapper is used to address a problem in iverilog in which the
        # simulator does not support shared library search paths.  The
        # current wrapper only works for iverilog.  Due to brokeness in
        # the iverilog argument parser, we must construct a correct
        # iverilog command line by analyzing its compiled script. Also,
        # this script is not passing through the arguments that it should
        # be passing through.
        def generate_vexe_wrapper(target, source, env):
            wrapper_handle = open(str(target[0]), 'w')
            wrapper_handle.write('#!/usr/bin/perl\n')
            wrapper_handle.write('# generated by verilog.py\n')
            wrapper_handle.write('$platform = $ENV{"PLATFORM_DIRECTORY"};\n')
            wrapper_handle.write('@script = `cat $platform/' + TMP_BSC_DIR +
                                 '/' + APM_NAME + '_hw.exe' + '`;\n')
            wrapper_handle.write('$script[0] =~ s/#!/ /g;\n')
            wrapper_handle.write('$vvp = $script[0];\n')
            wrapper_handle.write('chomp($vvp);\n')
            wrapper_handle.write(
                'exec("$vvp -m$platform/directc_mk_model_Wrapper.so $platform/'
                + TMP_BSC_DIR + '/' + APM_NAME + '_hw.exe' +
                ' +bscvcd \$* ");\n')
            wrapper_handle.close()

        def modify_path_ba_local(path):
            return bsv_tool.modify_path_ba(moduleList, path)

        # Bluesim builds apparently touch this code. This control block
        # preserves their behavior, but it is unclear why the verilog build is
        # involved.
        if (isPrimaryBuildTarget):
            vbinDeps = []

            # If we got a lim graph, we'll pick up many of our dependencies from it.
            # These were annotated in the top module above. Really, this seems unclean.
            # we should build a graph during the second pass and just use it.
            if (not self.firstPassLIGraph is None):
                # Collect linked dependencies for every module
                for moduleName in self.firstPassLIGraph.modules:
                    moduleListObject = moduleList.modules[moduleName]
                    vbinDeps += moduleList.getDependencies(
                        moduleListObject,
                        'VERILOG') + moduleList.getDependencies(
                            moduleListObject,
                            'GIVEN_VERILOG_HS') + moduleList.getDependencies(
                                moduleListObject,
                                'GEN_VPI_HS') + moduleList.getDependencies(
                                    moduleListObject,
                                    'GEN_VPI_CS') + moduleList.getDependencies(
                                        moduleListObject,
                                        'VHDL') + moduleList.getDependencies(
                                            moduleListObject,
                                            'BA') + moduleList.getDependencies(
                                                moduleListObject, 'GEN_BAS')

                vbinDeps += moduleList.getDependencies(
                    moduleList.topModule,
                    'VERILOG') + moduleList.getDependencies(
                        moduleList.topModule,
                        'GIVEN_VERILOG_HS') + moduleList.getDependencies(
                            moduleList.topModule,
                            'GEN_VPI_HS') + moduleList.getDependencies(
                                moduleList.topModule, 'GEN_VPI_CS'
                            ) + moduleList.getDependencies(
                                moduleList.topModule, 'VHDL'
                            ) + moduleList.getDependencies(
                                moduleList.topModule, 'BA') + map(
                                    modify_path_ba_local,
                                    moduleList.getModuleDependenciesWithPaths(
                                        moduleList.topModule, 'GEN_BAS'))

            # collect dependencies from all awb modules
            else:
                vbinDeps += moduleList.getAllDependencies(
                    'VERILOG') + moduleList.getAllDependencies(
                        'VHDL') + moduleList.getAllDependencies('BA') + map(
                            modify_path_ba_local,
                            moduleList.getAllDependenciesWithPaths('GEN_BAS'))

            vbin = moduleList.env.Command(
                TMP_BSC_DIR + '/' + APM_NAME + '_hw.exe', vbinDeps,
                [vexe_gen_command,
                 SCons.Script.Delete('directc.sft')])

            vexe = moduleList.env.Command(APM_NAME + '_hw.exe', vbin, [
                generate_vexe_wrapper, '@chmod a+x $TARGET',
                SCons.Script.Delete(APM_NAME + '_hw.errinfo')
            ])

            moduleList.topDependency = moduleList.topDependency + [vexe]

        else:
            vbinDeps = moduleList.getAllDependencies(
                'VERILOG') + moduleList.getAllDependencies(
                    'VHDL') + moduleList.getAllDependencies('BA') + map(
                        modify_path_ba_local,
                        moduleList.getAllDependenciesWithPaths('GEN_BAS'))

            vbin = moduleList.env.Command(
                TMP_BSC_DIR + '/' + APM_NAME + '_hw.vexe', vbinDeps,
                [vexe_gen_command,
                 SCons.Script.Delete('directc.sft')])

            vexe = moduleList.env.Command(APM_NAME + '_hw.vexe', vbin, [
                generate_vexe_wrapper, '@chmod a+x $TARGET',
                SCons.Script.Delete(APM_NAME + '_hw.exe'),
                SCons.Script.Delete(APM_NAME + '_hw.errinfo')
            ])

        moduleList.env.Alias('vexe', vexe)
Ejemplo n.º 6
0
    def __init__(self, moduleList):

        # if we have a deps build, don't do anything...
        if (moduleList.isDependsBuild):
            return

        self.firstPassLIGraph = wrapper_gen_tool.getFirstPassLIGraph()

        # A collector for all of the checkpoint objects we will gather/build in the following code.
        dcps = []

        # Construct the tcl file
        self.part = moduleList.getAWBParam('physical_platform_config',
                                           'FPGA_PART_XILINX')

        apm_name = moduleList.compileDirectory + '/' + moduleList.apmName

        self.paramTclFile = moduleList.topModule.moduleDependency['PARAM_TCL'][
            0]

        # If the TMP_FPGA_DIR doesn't exist, create it.
        if not os.path.isdir(moduleList.env['DEFS']['TMP_FPGA_DIR']):
            os.mkdir(moduleList.env['DEFS']['TMP_FPGA_DIR'])

        # Gather Tcl files for handling constraints.
        self.tcl_headers = []
        if (len(
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_HEADERS')) > 0):
            self.tcl_headers = map(
                model.modify_path_hw,
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_HEADERS'))

        self.tcl_defs = []
        if (len(
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_DEFINITIONS')) > 0):
            self.tcl_defs = map(
                model.modify_path_hw,
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_DEFINITIONS'))

        self.tcl_funcs = []
        if (len(
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_FUNCTIONS')) > 0):
            self.tcl_funcs = map(
                model.modify_path_hw,
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_FUNCTIONS'))

        self.tcl_algs = []
        if (len(
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_ALGEBRAS')) > 0):
            self.tcl_algs = map(
                model.modify_path_hw,
                moduleList.getAllDependenciesWithPaths(
                    'GIVEN_VIVADO_TCL_ALGEBRAS'))

        self.tcl_bmms = []
        if (len(moduleList.getAllDependencies('GIVEN_XILINX_BMMS')) > 0):
            self.tcl_bmms = moduleList.getAllDependencies('GIVEN_XILINX_BMMS')

        self.tcl_elfs = []
        if (len(moduleList.getAllDependencies('GIVEN_XILINX_ELFS')) > 0):
            self.tcl_elfs = moduleList.getAllDependencies('GIVEN_XILINX_ELFS')

        self.tcl_ag = []

        #Emit area group definitions
        # If we got an area group placement data structure, now is the
        # time to convert it into a new constraint tcl.
        self.area_group_file = moduleList.compileDirectory + '/areagroups.xdc'
        if ('AREA_GROUPS' in moduleList.topModule.moduleDependency):
            self.area_constraints = area_group_tool.AreaConstraints(moduleList)
            self.routeAG = (moduleList.getAWBParam(
                'area_group_tool', 'AREA_GROUPS_ROUTE_AG') != 0)

            # user ucf may be overridden by our area group ucf.  Put our
            # generated ucf first.
            #tcl_defs.insert(0,self.area_group_file)
            def area_group_ucf_closure(moduleList):
                def area_group_ucf(target, source, env):
                    self.area_constraints.loadAreaConstraints()
                    self.area_constraints.emitConstraintsVivado(
                        self.area_group_file)

                return area_group_ucf

            moduleList.env.Command([self.area_group_file],
                                   self.area_constraints.areaConstraintsFile(),
                                   area_group_ucf_closure(moduleList))

        synthDepsBase = moduleList.getAllDependencies('GEN_VIVADO_DCPS')

        # We got a stack of synthesis results for the LI modules.  We need
        # to convert these to design checkpoints for the fast place and
        # route flow.
        ngcModules = [
            module for module in moduleList.synthBoundaries()
            if not module.liIgnore
        ]

        for module in ngcModules + [moduleList.topModule]:
            # did we get a dcp from the first pass?  If so, did the lim
            # graph give code for this module?  If both are true, then we
            # will link the old ngc in, rather than regenerate it.
            if ((not self.firstPassLIGraph is None)
                    and (module.name in self.firstPassLIGraph.modules)
                    and (self.firstPassLIGraph.modules[
                        module.name].getAttribute('RESYNTHESIZE') is None)):
                if (li_module.linkFirstPassObject(
                        moduleList, module, self.firstPassLIGraph,
                        'GEN_VIVADO_DCPS', 'GEN_VIVADO_DCPS') is None):
                    module.moduleDependency['GEN_VIVADO_DCPS'] = [
                        self.edf_to_dcp(moduleList, module)
                    ]

            # it's possible that we got dcp from this compilation
            # pass. This will happen for the platform modules.
            elif (len(module.getDependencies('GEN_VIVADO_DCPS')) > 0):
                continue

            # we got neither. therefore, we must create a dcp out of the ngc.
            else:
                module.moduleDependency['GEN_VIVADO_DCPS'] = [
                    self.edf_to_dcp(moduleList, module)
                ]

        synthDeps = moduleList.getAllDependencies('GEN_VIVADO_DCPS')

        postSynthTcl = apm_name + '.physical.tcl'

        topWrapper = moduleList.topModule.wrapperName()

        newTclFile = open(postSynthTcl, 'w')
        newTclFile.write('create_project -force ' + moduleList.apmName + ' ' +
                         moduleList.compileDirectory + ' -part ' + self.part +
                         ' \n')

        # To resolve black boxes, we need to load checkpoints in the
        # following order:
        # 1) topModule
        # 2) platformModule
        # 3) user program, in any order

        userModules = [
            module for module in moduleList.synthBoundaries()
            if not module.liIgnore and not module.platformModule
        ]
        platformModules = [
            module for module in moduleList.synthBoundaries()
            if not module.liIgnore and module.platformModule
        ]
        checkpointCommands = []

        if (not moduleList.getAWBParamSafe('area_group_tool',
                                           'AREA_GROUPS_ENABLE')):

            for module in [moduleList.topModule
                           ] + platformModules + userModules:
                dcps.append(module.getDependencies('GEN_VIVADO_DCPS'))
                checkpoint = model.convertDependencies(
                    module.getDependencies('GEN_VIVADO_DCPS'))

                # There should only be one checkpoint here.
                if (len(checkpoint) > 1):
                    print "Error too many checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue

                if (len(checkpoint) == 0):
                    print "No checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue

                newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

        # We're attempting the new, parallel flow.
        else:
            # we need to issue seperate place commands.  Therefore, we attempt to place each design

            # There may be some special area groups in platforms -- handle them
            elabAreaConstraints = area_group_tool.AreaConstraints(moduleList)
            elabAreaConstraints.loadAreaConstraintsElaborated()
            #self.area_constraints = area_group_tool.AreaConstraints(moduleList)
            for module in userModules:
                # Did we get a placed module already?
                if ((module.name in elabAreaConstraints.constraints)
                        and ('LIBRARY_DCP' in elabAreaConstraints.constraints[
                            module.name].attributes)):
                    # we need to locate the dcp corresponding to this area group.
                    candidates = moduleList.getAllDependencies(
                        'GIVEN_VIVADO_DCPS')
                    for dcpCandidate in moduleList.getAllDependencies(
                            'GIVEN_VIVADO_DCPS'):
                        if dcpCandidate.attributes['module'] == module.name:
                            dcp = str(model.modify_path_hw(dcpCandidate))
                            model.dictionary_list_create_append(
                                module.moduleDependency,
                                'GEN_VIVADO_PLACEMENT_DCPS', dcp)
                            dcps.append(dcp)
                else:
                    dcp = self.place_dcp(moduleList, module)
                    model.dictionary_list_create_append(
                        module.moduleDependency, 'GEN_VIVADO_PLACEMENT_DCPS',
                        dcp)
                    dcps.append(dcp)

            for module in [moduleList.topModule] + platformModules:
                checkpoint = model.convertDependencies(
                    module.getDependencies('GEN_VIVADO_DCPS'))
                dcps.append(checkpoint)

                # There should only be one checkpoint here.
                if (len(checkpoint) > 1):
                    print "Error too many checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue

                if (len(checkpoint) == 0):
                    print "No checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue

                newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

            # We can have parent/child relationships in the user modules.
            # Vivado requires that checkpoints be read in topological
            # order.
            def isBlackBox(module):
                if (self.firstPassLIGraph.modules[module.name].getAttribute(
                        'BLACK_BOX_AREA_GROUP')):
                    return 1
                return 0

            for module in sorted(userModules, key=isBlackBox):
                checkpoint = model.convertDependencies(
                    module.getDependencies('GEN_VIVADO_PLACEMENT_DCPS'))

                # There should only be one checkpoint here.
                if (len(checkpoint) > 1):
                    print "Error too many checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue

                if (len(checkpoint) == 0):
                    print "No checkpoints for " + str(
                        module.name) + ":  " + str(checkpoint)
                    continue
                #read in new checkoutpoint

                newTclFile.write('read_checkpoint ' + checkpoint[0] + '\n')

                emitPlatformAreaGroups = (moduleList.getAWBParam(
                    'area_group_tool', 'AREA_GROUPS_GROUP_PLATFORM_CODE') != 0)

                # platformModule refers to the main platform module, not
                # the subordinate device area groups.
                platformModule = (
                    self.firstPassLIGraph.modules[module.name].getAttribute(
                        'BLACK_BOX_AREA_GROUP') is
                    None) and (not self.firstPassLIGraph.modules[
                        module.name].getAttribute('PLATFORM_MODULE') is None)

                allowAGPlatform = (
                    not platformModule) or emitPlatformAreaGroups

                emitDeviceGroups = (moduleList.getAWBParam(
                    'area_group_tool', 'AREA_GROUPS_PAR_DEVICE_AG') != 0)
                allowAGDevice = (self.firstPassLIGraph.modules[
                    module.name].getAttribute('BLACK_BOX_AREA_GROUP') is
                                 None) or emitDeviceGroups

                if (allowAGPlatform and allowAGDevice):
                    refName = module.wrapperName()
                    lockPlacement = True
                    lockRoute = self.routeAG
                    # If this is an platform/user-defined area group, the wrapper name may be different.
                    if (not self.firstPassLIGraph.modules[module.name].
                            getAttribute('BLACK_BOX_AREA_GROUP') is None):
                        refName = elabAreaConstraints.constraints[
                            module.name].attributes['MODULE_NAME']
                        lockPlacement = not (
                            'NO_PLACE' in elabAreaConstraints.constraints[
                                module.name].attributes) and lockPlacement
                        lockRoute = not (
                            'NO_ROUTE' in elabAreaConstraints.constraints[
                                module.name].attributes) and lockRoute

                    checkpointCommands.append(
                        'if { [llength [get_cells -hier -filter {REF_NAME =~ "'
                        + refName + '"}]] } {\n')
                    checkpointCommands.append('    puts "Locking ' + refName +
                                              '"\n')
                    if (lockRoute):
                        # locking routing requires us to emit an area group. boo.
                        ag_tcl = self.ag_constraints(moduleList, module)
                        self.tcl_ag.append(ag_tcl)
                        checkpointCommands.append('    source ' + str(ag_tcl) +
                                                  '\n')
                        checkpointCommands.append(
                            '    lock_design -level routing [get_cells -hier -filter {REF_NAME =~ "'
                            + refName + '"}]\n')
                    elif (lockPlacement):
                        checkpointCommands.append(
                            '    lock_design -level placement [get_cells -hier -filter {REF_NAME =~ "'
                            + refName + '"}]\n')
                    checkpointCommands.append('}\n')

        given_netlists = [
            moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + netlist for netlist
            in moduleList.getAllDependenciesWithPaths('GIVEN_NGCS') +
            moduleList.getAllDependenciesWithPaths('GIVEN_EDFS')
        ]

        for netlist in given_netlists:
            newTclFile.write('read_edif ' + netlist + '\n')

        # We have lots of dangling wires (Thanks, Bluespec).  Set the
        # following properties to silence the warnings.

        newTclFile.write(
            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]\n")
        newTclFile.write(
            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]\n")

        newTclFile.write("link_design -top " + topWrapper + " -part " +
                         self.part + "\n")

        newTclFile.write("report_utilization -file " + apm_name +
                         ".link.util\n")

        newTclFile.write("write_checkpoint -force " + apm_name + ".link.dcp\n")

        # lock down the area group routing.
        newTclFile.write("\n".join(checkpointCommands) + "\n")

        for elf in self.tcl_elfs:
            newTclFile.write("add_file " + model.modify_path_hw(elf) + "\n")
            newTclFile.write("set_property MEMDATA.ADDR_MAP_CELLS {" +
                             str(elf.attributes['ref']) + "} [get_files " +
                             model.modify_path_hw(elf) + "]\n")

        # We will now attempt to link in any bmm that we might have.
        for bmm in self.tcl_bmms:
            newTclFile.write("add_file " + model.modify_path_hw(bmm) + "\n")
            newTclFile.write("set_property SCOPED_TO_REF " +
                             str(bmm.attributes['ref']) + " [get_files " +
                             model.modify_path_hw(bmm) + "]\n")

        newTclFile.write('set IS_TOP_BUILD 1\n ')
        newTclFile.write('set IS_AREA_GROUP_BUILD 0\n ')
        newTclFile.write('set SYNTH_OBJECT ""\n')
        newTclFile.write('source ' + self.paramTclFile + '\n')

        for tcl_header in self.tcl_headers:
            newTclFile.write('source ' + tcl_header + '\n')

        for tcl_def in self.tcl_defs:
            newTclFile.write('source ' + tcl_def + '\n')

        for tcl_func in self.tcl_funcs:
            newTclFile.write('source ' + tcl_func + '\n')

        for tcl_alg in self.tcl_algs:
            newTclFile.write('source ' + tcl_alg + '\n')

        def dumpPBlockCmd(tgt):
            return 'dumpPBlockUtilization "' + moduleList.compileDirectory + '/' + tgt + '.util"\n'

        newTclFile.write(dumpPBlockCmd('link'))
        newTclFile.write("report_timing_summary -file " + apm_name +
                         ".map.twr\n\n")

        newTclFile.write("opt_design -directive AddRemap\n")
        newTclFile.write("report_utilization -file " + apm_name +
                         ".opt.util\n")
        newTclFile.write(dumpPBlockCmd('opt'))
        newTclFile.write("write_checkpoint -force " + apm_name +
                         ".opt.dcp\n\n")

        newTclFile.write(
            "place_design -no_drc -directive WLDrivenBlockPlacement\n")
        newTclFile.write(dumpPBlockCmd('place'))

        newTclFile.write("phys_opt_design -directive AggressiveFanoutOpt\n")
        newTclFile.write("write_checkpoint -force " + apm_name + ".map.dcp\n")
        newTclFile.write(dumpPBlockCmd('phyopt'))
        newTclFile.write("report_utilization -file " + apm_name +
                         ".map.util\n\n")

        newTclFile.write("route_design\n")
        newTclFile.write("write_checkpoint -force " + apm_name + ".par.dcp\n")
        newTclFile.write(dumpPBlockCmd('par'))
        newTclFile.write("report_timing_summary -file " + apm_name +
                         ".par.twr\n\n")

        newTclFile.write("report_utilization -hierarchical -file " + apm_name +
                         ".par.util\n")
        newTclFile.write("report_drc -file " + topWrapper + ".drc\n\n")

        newTclFile.write("write_bitstream -force " + apm_name + "_par.bit\n")

        newTclFile.close()

        # generate bitfile
        xilinx_bit = moduleList.env.Command(
            apm_name + '_par.bit',
            synthDeps + self.tcl_algs + self.tcl_defs + self.tcl_funcs +
            self.tcl_ag + [self.paramTclFile] + dcps + [postSynthTcl], [
                'touch start.txt; vivado -verbose -mode batch -source ' +
                postSynthTcl + ' -log ' + moduleList.compileDirectory +
                '/postsynth.log'
            ])

        moduleList.topModule.moduleDependency['BIT'] = [apm_name + '_par.bit']

        # We still need to generate a download script.
        xilinx_loader.LOADER(moduleList)