def ag_constraints(self, moduleList, module): # Due to area groups, we first need a closure to generate tcl. agCompileDirectory = moduleList.compileDirectory + '/' agTcl = agCompileDirectory + module.name + ".ag.tcl" refName = module.wrapperName() area_constraints = area_group_tool.AreaConstraints(moduleList) def ag_tcl_closure(moduleList): def ag_tcl(target, source, env): # TODO: Eventually, we'll need to examine the contstraints to decide if we need to rebuild. area_constraints.loadAreaConstraints() # give our area constraint is a MODULE_NAME, if it doesn't have one. if (not 'MODULE_NAME' in area_constraints.constraints[ module.name].attributes): area_constraints.constraints[ module.name].attributes['MODULE_NAME'] = refName area_constraints.constraints[ module.name].attributes['SHARE_PLACEMENT'] = False agFile = open(agTcl, 'w') area_constraints.emitModuleConstraintsVivado( agFile, module.name, useSourcePath=True) agFile.close() return ag_tcl moduleList.env.Command([agTcl], [area_constraints.areaConstraintsFile()], ag_tcl_closure(moduleList)) return agTcl
def __init__(self, moduleList): fpga_part_xilinx = moduleList.env['DEFS']['FPGA_PART_XILINX'] xilinx_apm_name = moduleList.compileDirectory + '/' + moduleList.apmName # If we got an area group placement data structure, now is the # time to convert it into a UCF. if ('AREA_GROUPS' in moduleList.topModule.moduleDependency): area_constraints = area_group_tool.AreaConstraints(moduleList) area_group_file = moduleList.compileDirectory + '/areagroups.ucf' # user ucf may be overridden by our area group ucf. Put our # generated ucf first. moduleList.topModule.moduleDependency['UCF'].insert( 0, area_group_file) def area_group_ucf_closure(moduleList): def area_group_ucf(target, source, env): area_constraints.loadAreaConstraints() area_constraints.emitConstraintsXilinx(area_group_file) return area_group_ucf moduleList.env.Command([area_group_file], area_constraints.areaConstraintsFile(), area_group_ucf_closure(moduleList)) # Concatenate UCF files if (len(moduleList.topModule.moduleDependency['UCF']) > 0): xilinx_ucf = moduleList.env.Command( xilinx_apm_name + '.ucf', moduleList.topModule.moduleDependency['UCF'], 'cat $SOURCES > $TARGET') if len(moduleList.env['DEFS']['GIVEN_BMMS']) != 0: xilinx_bmm = moduleList.env.Command( xilinx_apm_name + '.bmm', Utils.clean_split(moduleList.env['DEFS']['GIVEN_BMMS'], sep=' '), 'cat $SOURCES > $TARGET') #./ works around crappy xilinx parser bmm = ' -bm ./' + xilinx_apm_name + '.bmm' else: xilinx_bmm = '' bmm = '' # Generate include for each synthesis boundary. (Synplify build uses # subdirectories.) sd_list = [ moduleList.env['DEFS']['ROOT_DIR_HW_MODEL'], moduleList.compileDirectory ] for module in moduleList.synthBoundaries(): w = moduleList.compileDirectory + '/' + module.wrapperName() sd_list += [ w, moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + module.buildPath + '/' ] given_netlists = [ moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + netlist for netlist in moduleList.getAllDependenciesWithPaths('GIVEN_NGCS') + moduleList.getAllDependenciesWithPaths('GIVEN_EDFS') ] module_ngcs = moduleList.getAllDependencies('SYNTHESIS') # We are really depending on the top level being an .ngc Since ISE # is going away, this will probably not cost us anything. xilinx_ngd = moduleList.env.Command( xilinx_apm_name + '.ngd', moduleList.topModule.moduleDependency['SYNTHESIS'] + given_netlists, [ SCons.Script.Delete(xilinx_apm_name + '.bld'), SCons.Script.Delete(xilinx_apm_name + '_ngdbuild.xrpt'), # Xilinx project files are created automatically by Xilinx tools, but not # needed for command line tools. The project files may be corrupt due # to parallel invocation of xst. Until we figure out how to move them # or guarantee their safety, just delete them. SCons.Script.Delete('xlnx_auto_0.ise'), SCons.Script.Delete('xlnx_auto_0_xdb'), 'ngdbuild -aul -aut -p ' + fpga_part_xilinx + \ ' -sd ' + ' -sd '.join(sd_list) + \ ' -uc ' + xilinx_apm_name + '.ucf ' + bmm + moduleList.topModule.wrapperName() + '.ngc $TARGET | tee ' + xilinx_apm_name +'.ngdrpt', SCons.Script.Move(moduleList.compileDirectory + '/netlist.lst', 'netlist.lst') ]) moduleList.env.Depends( xilinx_ngd, given_netlists + module_ngcs + xilinx_ucf + xilinx_bmm) moduleList.topModule.moduleDependency['NGD'] = [xilinx_ngd] SCons.Script.Clean(xilinx_ngd, moduleList.compileDirectory + '/netlist.lst') # Alias for NGD moduleList.env.Alias('ngd', xilinx_ngd)
def edf_to_dcp(self, moduleList, module): edfCompileDirectory = moduleList.compileDirectory + '/' + module.name + '_synth/' dcp = edfCompileDirectory + module.name + ".synth.dcp" edfTcl = edfCompileDirectory + module.name + ".synth.tcl" if not os.path.isdir(edfCompileDirectory): os.mkdir(edfCompileDirectory) gen_netlists = module.getDependencies('GEN_NGCS') given_netlists = [ moduleList.env['DEFS']['ROOT_DIR_HW'] + '/' + netlist for netlist in moduleList.getAllDependenciesWithPaths('GIVEN_NGCS') + moduleList.getAllDependenciesWithPaths('GIVEN_EDFS') ] constraintsFile = [] area_constraints = None if (moduleList.getAWBParamSafe('area_group_tool', 'AREA_GROUPS_ENABLE')): area_constraints = area_group_tool.AreaConstraints(moduleList) constraintsFile = [area_constraints.areaConstraintsFile()] def edf_to_dcp_tcl_closure(moduleList): def edf_to_dcp_tcl(target, source, env): edfTclFile = open(edfTcl, 'w') for netlist in gen_netlists + given_netlists: edfTclFile.write('read_edif ' + model.rel_if_not_abspath( netlist, edfCompileDirectory) + '\n') refName = module.wrapperName() # If this is an platform/user-defined area group, the wrapper name may be different. if ((not self.firstPassLIGraph is None) and (module.name in self.firstPassLIGraph.modules)): if (not self.firstPassLIGraph.modules[module.name]. getAttribute('BLACK_BOX_AREA_GROUP') is None): area_constraints.loadAreaConstraints() refName = area_constraints.constraints[ module.name].attributes['MODULE_NAME'] if (module.getAttribute('TOP_MODULE') is None): edfTclFile.write("link_design -mode out_of_context -top " + refName + " -part " + self.part + "\n") edfTclFile.write( "set_property HD.PARTITION 1 [current_design]\n") else: edfTclFile.write("link_design -top " + refName + " -part " + self.part + "\n") if (not module.platformModule): edfTclFile.write("opt_design -quiet\n") edfTclFile.write('write_checkpoint -force ' + module.name + ".synth.dcp" + '\n') edfTclFile.close() return edf_to_dcp_tcl moduleList.env.Command([edfTcl], constraintsFile, edf_to_dcp_tcl_closure(moduleList)) # generate bitfile return moduleList.env.Command([ dcp ], [gen_netlists] + [given_netlists] + [edfTcl], [ 'cd ' + edfCompileDirectory + '; touch start.txt; vivado -mode batch -source ' + module.name + ".synth.tcl" + ' -log ' + module.name + '.synth.checkpoint.log' ])
def place_dcp(self, moduleList, module): # Due to area groups, we first need a closure to generate tcl. placeCompileDirectory = moduleList.compileDirectory + '/' + module.name + '_physical/' dcp = placeCompileDirectory + module.name + ".place.dcp" edfTcl = placeCompileDirectory + module.name + ".place.tcl" constraintsTcl = placeCompileDirectory + module.name + ".constraints.tcl" checkpoint = model.convertDependencies( module.getDependencies('GEN_VIVADO_DCPS')) if not os.path.isdir(placeCompileDirectory): os.mkdir(placeCompileDirectory) area_constraints = area_group_tool.AreaConstraints(moduleList) def place_dcp_tcl_closure(moduleList): def place_dcp_tcl(target, source, env): # TODO: Eventually, we'll need to examine the contstraints to decide if we need to rebuild. area_constraints.loadAreaConstraints() edfTclFile = open(edfTcl, 'w') constraintsTclFile = open(constraintsTcl, 'w') edfTclFile.write('read_checkpoint ' + model.rel_if_not_abspath( checkpoint[0], placeCompileDirectory) + '\n') # throw out area group constraints. (and maybe loc constraints too?) # Some modules may not have placement information. Ignore them for now. needToLink = True refName = module.wrapperName() # 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 = area_constraints.constraints[ module.name].attributes['MODULE_NAME'] if ((self.firstPassLIGraph.modules[module.name].getAttribute( 'BLACK_BOX_AREA_GROUP') is None) or moduleList.getAWBParamSafe( 'area_group_tool', 'AREA_GROUPS_PAR_DEVICE_AG')): if (not area_constraints.emitModuleConstraintsVivado( constraintsTclFile, module.name, useSourcePath=False) is None): # for platform modules, we need to insert the tcl environment. constraintsTclFile.write('set IS_TOP_BUILD 0\n') constraintsTclFile.write('set AG_OBJECT ' + module.name + '\n') constraintsTclFile.write('set IS_AREA_GROUP_BUILD 1\n') constraintsTclFile.write( 'source ' + model.rel_if_not_abspath( self.paramTclFile, placeCompileDirectory) + '\n') for tcl_header in self.tcl_headers: constraintsTclFile.write( 'source ' + model.rel_if_not_abspath( tcl_header, placeCompileDirectory) + '\n') for tcl_def in self.tcl_defs: constraintsTclFile.write( 'source ' + model.rel_if_not_abspath( tcl_def, placeCompileDirectory) + '\n') for tcl_func in self.tcl_funcs: constraintsTclFile.write( 'source ' + model.rel_if_not_abspath( tcl_func, placeCompileDirectory) + '\n') constraintsTclFile.write("annotateModelClock\n") constraintsTclFile.write("annotateCLK_SRC\n") for tcl_alg in self.tcl_algs: constraintsTclFile.write( 'source ' + model.rel_if_not_abspath( tcl_alg, placeCompileDirectory) + '\n') edfTclFile.write( 'add_file ' + model.rel_if_not_abspath( constraintsTcl, placeCompileDirectory) + '\n') if (not 'NO_PLACE' in area_constraints.constraints[ module.name].attributes): if (not 'NO_ROUTE' in area_constraints.constraints[ module.name].attributes and self.routeAG): edfTclFile.write( "set_property USED_IN {synthesis implementation opt_design place_design phys_opt_design route_design out_of_context} [get_files " + model.rel_if_not_abspath( constraintsTcl, placeCompileDirectory) + "]\n") else: edfTclFile.write( "set_property USED_IN {synthesis implementation opt_design place_design phys_opt_design out_of_context} [get_files " + model.rel_if_not_abspath( constraintsTcl, placeCompileDirectory) + "]\n") # linking lets us pull in placement constraints. edfTclFile.write( "link_design -mode out_of_context -top " + refName + " -part " + self.part + "\n") needToLink = False # if ended here... if (not 'NO_PLACE' in area_constraints.constraints[ module.name].attributes): edfTclFile.write("place_design -no_drc \n") edfTclFile.write("report_timing_summary -file " + module.name + ".place.twr\n") edfTclFile.write("phys_opt_design \n") if (not 'NO_ROUTE' in area_constraints.constraints[ module.name].attributes and self.routeAG): edfTclFile.write("route_design\n") edfTclFile.write( "report_timing_summary -file " + module.name + ".route.twr\n") edfTclFile.write("report_route_status\n") # still need to link design. if (needToLink): edfTclFile.write( "link_design -mode out_of_context -top " + refName + " -part " + self.part + "\n") edfTclFile.write('write_checkpoint -force ' + module.name + ".place.dcp" + '\n') edfTclFile.close() constraintsTclFile.close() return place_dcp_tcl moduleList.env.Command([edfTcl, constraintsTcl], [area_constraints.areaConstraintsFile()], place_dcp_tcl_closure(moduleList)) # generate checkpoint return moduleList.env.Command( [dcp], [checkpoint] + [edfTcl, constraintsTcl] + self.tcl_headers + self.tcl_algs + self.tcl_defs + self.tcl_funcs, [ 'cd ' + placeCompileDirectory + '; touch start.txt; vivado -mode batch -source ' + module.name + ".place.tcl" + ' -log ' + module.name + '.place.log' ])
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)