def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'Interconnect', 'clock_period': 1.1, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # RTL Generation 'array_width': 32, 'array_height': 16, 'interconnect_only': False, # Testing 'testbench_name': 'Interconnect_tb', } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') Tile_MemCore = Step(this_dir + '/Tile_MemCore') Tile_PE = Step(this_dir + '/Tile_PE') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_power = Step(this_dir + '/../common/custom-power-hierarchical') custom_cts = Step(this_dir + '/custom-cts-overrides') custom_lvs = Step(this_dir + '/custom-lvs-rules') gls_args = Step(this_dir + '/gls_args') testbench = Step(this_dir + '/testbench') # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) vcs_sim = Step('synopsys-vcs-sim', default=True) # Add cgra tile macro inputs to downstream nodes dc.extend_inputs(['Tile_PE.db']) dc.extend_inputs(['Tile_MemCore.db']) pt_signoff.extend_inputs(['Tile_PE.db']) pt_signoff.extend_inputs(['Tile_MemCore.db']) genlibdb.extend_inputs(['Tile_PE.db']) genlibdb.extend_inputs(['Tile_MemCore.db']) # These steps need timing info for cgra tiles tile_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff, gdsmerge ] for step in tile_steps: step.extend_inputs(['Tile_PE_tt.lib', 'Tile_PE.lef']) step.extend_inputs(['Tile_MemCore_tt.lib', 'Tile_MemCore.lef']) # Need the netlist and SDF files for gate-level sim vcs_sim.extend_inputs(['Tile_PE.vcs.v', 'Tile_PE.sdf']) vcs_sim.extend_inputs(['Tile_MemCore.vcs.v', 'Tile_MemCore.sdf']) # Need the cgra tile gds's to merge into the final layout gdsmerge.extend_inputs(['Tile_PE.gds']) gdsmerge.extend_inputs(['Tile_MemCore.gds']) # Need LVS verilog files for both tile types to do LVS lvs.extend_inputs(['Tile_PE.lvs.v']) lvs.extend_inputs(['Tile_MemCore.lvs.v']) # Need sram spice file for LVS lvs.extend_inputs(['sram.spi']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) cts.extend_inputs(custom_cts.all_outputs()) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(Tile_MemCore) g.add_step(Tile_PE) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(custom_cts) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(custom_lvs) g.add_step(lvs) g.add_step(debugcalibre) g.add_step(gls_args) g.add_step(testbench) g.add_step(vcs_sim) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) # In our CGRA, the tile pattern is: # PE PE PE Mem PE PE PE Mem ... # Thus, if there are < 4 columns, the the array won't contain any # memory tiles. If this is the case, we don't need to run the # memory tile flow. if parameters['array_width'] > 3: g.connect_by_name(Tile_MemCore, dc) g.connect_by_name(Tile_MemCore, iflow) g.connect_by_name(Tile_MemCore, init) g.connect_by_name(Tile_MemCore, power) g.connect_by_name(Tile_MemCore, place) g.connect_by_name(Tile_MemCore, cts) g.connect_by_name(Tile_MemCore, postcts_hold) g.connect_by_name(Tile_MemCore, route) g.connect_by_name(Tile_MemCore, postroute) g.connect_by_name(Tile_MemCore, signoff) g.connect_by_name(Tile_MemCore, pt_signoff) g.connect_by_name(Tile_MemCore, genlibdb) g.connect_by_name(Tile_MemCore, gdsmerge) g.connect_by_name(Tile_MemCore, drc) g.connect_by_name(Tile_MemCore, lvs) # These rules LVS BOX the SRAM macro, so they should # only be used if memory tile is present g.connect_by_name(custom_lvs, lvs) g.connect_by_name(Tile_MemCore, vcs_sim) g.connect_by_name(Tile_PE, dc) g.connect_by_name(Tile_PE, iflow) g.connect_by_name(Tile_PE, init) g.connect_by_name(Tile_PE, power) g.connect_by_name(Tile_PE, place) g.connect_by_name(Tile_PE, cts) g.connect_by_name(Tile_PE, postcts_hold) g.connect_by_name(Tile_PE, route) g.connect_by_name(Tile_PE, postroute) g.connect_by_name(Tile_PE, signoff) g.connect_by_name(Tile_PE, pt_signoff) g.connect_by_name(Tile_PE, genlibdb) g.connect_by_name(Tile_PE, gdsmerge) g.connect_by_name(Tile_PE, drc) g.connect_by_name(Tile_PE, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_cts, cts) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, genlibdb) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) g.connect_by_name(adk, vcs_sim) g.connect_by_name(testbench, vcs_sim) g.connect_by_name(gls_args, vcs_sim) g.connect_by_name(signoff, vcs_sim) g.connect_by_name(Tile_PE, vcs_sim) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # genlibdb -- Remove 'report-interface-timing.tcl' beacuse it takes # very long and is not necessary order = genlibdb.get_param('order') order.remove('write-interface-timing.tcl') genlibdb.update_params({'order': order}) # init -- Add 'dont-touch.tcl' before reporting order = init.get_param('order') # get the default script run order reporting_idx = order.index('reporting.tcl') # find reporting.tcl # Add dont-touch before reporting order.insert(reporting_idx, 'dont-touch.tcl') init.update_params({'order': order}) # We are overriding certain pin types for CTS, so we need to # add the script that does that to the CTS order order = cts.get_param('order') main_idx = order.index('main.tcl') order.insert(main_idx, 'cts-overrides.tcl') cts.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'freepdk-45nm' adk_view = 'view-standard' parameters = { 'construct_path' : __file__, 'design_name' : 'SramWrapper', 'clock_period' : 2.0, 'adk' : adk_name, 'adk_view' : adk_view, 'topographical' : True, } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps sram = Step( this_dir + '/sram' ) rtl = Step( this_dir + '/rtl' ) constraints = Step( this_dir + '/constraints' ) pin_placement = Step( this_dir + '/pin-placement' ) floorplan = Step( this_dir + '/floorplan' ) power_sram = Step( this_dir + '/power-sram' ) lvs = Step( this_dir + '/mentor-calibre-lvs') # Default steps info = Step( 'info', default=True ) dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) drc = Step( 'mentor-calibre-drc', default=True ) pt_timing = Step( 'synopsys-pt-timing-signoff', default=True ) # ERROR: doesn't read SRAM spice #lvs = Step( 'mentor-calibre-lvs', default=True ) # ERROR: doesn't read SRAM dbs genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) # Not tested # pt_power_rtl = Step( 'synopsys-ptpx-rtl', default=True ) # gls # pt_power_gls #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( sram ) g.add_step( rtl ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( pin_placement) g.add_step( floorplan ) g.add_step( init ) g.add_step( power_sram ) g.add_step( power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( signoff ) g.add_step( genlibdb ) g.add_step( gdsmerge ) g.add_step( drc ) g.add_step( lvs ) g.add_step( pt_timing ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges dc.extend_inputs(['sram_tt_1p1V_25C.db']) pt_timing.extend_inputs(['sram_tt_1p1V_25C.db']) genlibdb.extend_inputs(['sram_tt_1p1V_25C.db']) init.extend_inputs(['floorplan.tcl', 'pin-assignments.tcl']) power.extend_inputs(['globalnetconnect.tcl', 'power-strategy-singlemesh.tcl']) for step in [iflow, init, power, place, cts, postcts_hold, route, postroute, signoff]: step.extend_inputs(['sram_tt_1p1V_25C.lib', 'sram.lef']) gdsmerge.extend_inputs(['sram.gds']) lvs.extend_inputs(['sram.sp']) # Add a set units command to init as a temporary fix for conflicting # units between SRAM lib and stdcells.lib init.pre_extend_commands( [ r'echo -e "setLibraryUnit -cap 1fF -time 1ns\n$(cat scripts/main.tcl)"' r' > scripts/main.tcl', ] ) # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, genlibdb ) g.connect_by_name( adk, gdsmerge ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( adk, pt_timing ) g.connect_by_name( rtl, dc ) g.connect_by_name( constraints, dc ) g.connect_by_name( sram, dc ) g.connect_by_name( sram, iflow ) g.connect_by_name( sram, init ) g.connect_by_name( sram, power ) g.connect_by_name( sram, place ) g.connect_by_name( sram, cts ) g.connect_by_name( sram, postcts_hold ) g.connect_by_name( sram, route ) g.connect_by_name( sram, postroute ) g.connect_by_name( sram, signoff ) g.connect_by_name( sram, gdsmerge ) g.connect_by_name( sram, lvs ) g.connect_by_name( sram, pt_timing ) g.connect_by_name( sram, genlibdb ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( dc, power ) g.connect_by_name( dc, place ) g.connect_by_name( dc, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, signoff ) g.connect_by_name( floorplan, init ) g.connect_by_name( pin_placement,init ) g.connect_by_name( init, power ) g.connect_by_name( power_sram, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, signoff ) g.connect_by_name( signoff, genlibdb ) g.connect_by_name( signoff, gdsmerge ) g.connect_by_name( signoff, drc ) g.connect_by_name( gdsmerge, drc ) g.connect_by_name( signoff, lvs ) g.connect_by_name( gdsmerge, lvs ) g.connect_by_name( signoff, pt_timing ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'skywater-130nm-adk' adk_view = 'view-hs' parameters = { 'construct_path': __file__, 'design_name': 'fll_core', 'clock_period': 2.0, 'adk': adk_name, 'adk_view': adk_view, 'topographical': True, } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') custom_init = Step(this_dir + '/custom-init') custom_power = Step(this_dir + '/custom-power') custom_geom = Step(this_dir + '/custom-geom') custom_place = Step(this_dir + '/custom-place') constraints = Step(this_dir + '/constraints') dc = Step(this_dir + '/synopsys-dc-synthesis') # qtm = Step(this_dir + '/qtm') # Define blocks function blocks = [] # Added steps for blackbox init = Step(this_dir + '/cadence-innovus-init') cts = Step(this_dir + '/cadence-innovus-cts') place = Step(this_dir + '/cadence-innovus-place') # prelvs = Step(this_dir + '/prelvs_fix') lvs = Step(this_dir + '/open-netgen-lvs') gdsmerge = Step(this_dir + '/mentor-calibre-gdsmerge') magic_drc = Step(this_dir + '/open-magic-drc') magic_def2spice = Step(this_dir + '/open-magic-def2spice') pex = Step(this_dir + '/open-magic-ext2spice') # Default steps info = Step('info', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) # init = Step( 'cadence-innovus-init', default=True ) power = Step('cadence-innovus-power', default=True) # place = Step( 'cadence-innovus-place', default=True ) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) # gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) # drc = Step( 'mentor-calibre-drc', default=True ) # lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add extra inputs to innovus init and power steps init.extend_inputs(custom_init.all_outputs()) init.extend_inputs(custom_geom.all_outputs()) power.extend_inputs(custom_power.all_outputs()) power.extend_inputs(custom_geom.all_outputs()) place.extend_inputs(custom_place.all_outputs()) lib_lef_steps = \ [iflow, init, power, place, route, postroute, signoff] # for step in lib_lef_steps: # step.extend_inputs(libs + lefs) # gds_list needed for gds_merge step # spi_list or verilog netlists needed for blackbox LVS #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(genlibdb) g.add_step(gdsmerge) # g.add_step( drc ) g.add_step(lvs) g.add_step(debugcalibre) g.add_step(custom_geom) g.add_step(custom_init) g.add_step(custom_power) g.add_step(custom_place) # g.add_step( prelvs ) g.add_step(magic_def2spice) g.add_step(magic_drc) g.add_step(pex) for block in blocks: g.add_step(block) # g.add_step( qtm ) #g.add_step( custom_geom ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, magic_drc) g.connect_by_name(adk, lvs) g.connect_by_name(adk, magic_def2spice) g.connect_by_name(adk, pex) g.connect_by_name(gdsmerge, magic_drc) g.connect_by_name(signoff, magic_def2spice) g.connect_by_name(signoff, lvs) g.connect_by_name(magic_def2spice, lvs) g.connect_by_name(signoff, pex) g.connect_by_name(magic_def2spice, pex) g.connect_by_name(lvs, pex) # for block in blocks + [qtm]: # g.connect_by_name(block, dc) # g.connect_by_name(block, iflow) # g.connect_by_name(block, init) # g.connect_by_name(block, power) # g.connect_by_name(block, place) # g.connect_by_name(block, cts) # g.connect_by_name(block, postcts_hold) # g.connect_by_name(block, route) # g.connect_by_name(block, postroute) # g.connect_by_name(block, signoff) # g.connect_by_name(block, gdsmerge) # g.connect_by_name(block, lvs) g.connect_by_name(custom_place, place) g.connect_by_name(custom_init, init) g.connect_by_name(custom_geom, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_geom, power) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(place, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(signoff, gdsmerge) # g.connect_by_name( signoff, lvs ) # g.connect_by_name( prelvs, lvs ) g.connect_by_name(signoff, magic_drc) # g.connect_by_name( gdsmerge, magic_drc ) # g.connect_by_name( signoff, lvs ) g.connect_by_name(gdsmerge, lvs) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) #----------------------------------------------------------------------- # Order definition #----------------------------------------------------------------------- order = init.get_param('order') # get the default script run order # Add 'set-geom-vars.tcl' at the beginning order.insert(0, 'set-geom-vars.tcl') init.update_params({'order': order}) #insert variable definition infront of the power planning order = power.get_param('order') # get the default script run order # Add 'set-geom-vars.tcl' at the beginning order.insert(0, 'set-geom-vars.tcl') power.update_params({'order': order}) #order = route.get_param('order') #order.insert(0, 'route-settings.tcl') power.update_params({'order': order}) # postroute_hold.update_params({'hold_target_slack' : parameters['hold_target_slack']}, allow_new=True) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'skywater-130nm-adk' adk_view = 'view-standard' parameters = { 'construct_path': __file__, 'design_name': 'user_proj_example', 'clock_period': 62.5, 'adk': adk_name, 'adk_view': adk_view, 'topographical': True, 'strip_path': 'user_proj_example', 'saif_instance': 'user_proj_example' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') pin_placement = Step(this_dir + '/pin-placement') floorplan = Step(this_dir + '/floorplan') # Power node is custom because power and gnd pins are named differently in # the standard cells compared to the default node, and the layer numbering is # different because of li layer, the default assumes metal 1 is the lowest # layer power = Step(this_dir + '/cadence-innovus-power') # Signoff is custom because it has to output def that the default step does # not do. This is because we use the def instead of gds for generating spice # from layout for LVS signoff = Step(this_dir + '/cadence-innovus-signoff') pt_power_rtl = Step(this_dir + '/synopsys-ptpx-rtl') magic_drc = Step(this_dir + '/open-magic-drc') magic_def2spice = Step(this_dir + '/open-magic-def2spice') magic_gds2spice = Step(this_dir + '/open-magic-gds2spice') netgen_lvs = Step(this_dir + '/open-netgen-lvs') magic_antenna = Step(this_dir + '/open-magic-antenna') calibre_lvs = Step(this_dir + '/mentor-calibre-comparison') pt_timing = Step(this_dir + '/synopsys-pt-timing-signoff') export = Step(this_dir + '/export-to-openlane') dc = Step( this_dir + '/synopsys-dc-synthesis') # NEW DC with netname case sensitivity fix genlibdb = Step(this_dir + '/synopsys-ptpx-genlibdb') # Default steps info = Step('info', default=True) # Need to use clone if you want to instantiate the same node more than once # in your graph but configure it differently, for example, RTL simulation and # gate-level simulation use the same VCS node # cocotb based simulation steps rtl_sim = Step(this_dir + '/rtl-sim') iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) # pt_timing = Step( 'synopsys-pt-timing-signoff', default=True ) gen_saif = Step('synopsys-vcd2saif-convert', default=True) gen_saif_rtl = gen_saif.clone() # gen_saif_gl = gen_saif.clone() gen_saif_rtl.set_name('gen-saif-rtl') # gen_saif_gl.set_name( 'gen-saif-gl' ) netgen_lvs_def = netgen_lvs.clone() netgen_lvs_def.set_name('netgen-lvs-def') netgen_lvs_gds = netgen_lvs.clone() netgen_lvs_gds.set_name('netgen-lvs-gds') # pt_power_gl = Step( 'synopsys-ptpx-gl', default=True ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(rtl_sim) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(pin_placement) g.add_step(floorplan) g.add_step(init) g.add_step(power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(gdsmerge) g.add_step(export) g.add_step(pt_timing) g.add_step(gen_saif_rtl) g.add_step(pt_power_rtl) g.add_step(genlibdb) # g.add_step( gl_sim ) # g.add_step( gen_saif_gl ) # g.add_step( pt_power_gl ) g.add_step(magic_drc) g.add_step(magic_antenna) g.add_step(magic_def2spice) g.add_step(netgen_lvs_def) g.add_step(magic_gds2spice) g.add_step(netgen_lvs_gds) g.add_step(calibre_lvs) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges init.extend_inputs(['floorplan.tcl', 'pin-assignments.tcl']) # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, magic_drc) g.connect_by_name(adk, magic_antenna) g.connect_by_name(adk, magic_def2spice) g.connect_by_name(adk, magic_gds2spice) g.connect_by_name(adk, netgen_lvs_def) g.connect_by_name(adk, netgen_lvs_gds) g.connect_by_name(adk, calibre_lvs) g.connect_by_name(adk, pt_timing) g.connect_by_name(adk, pt_power_rtl) g.connect_by_name(adk, genlibdb) # g.connect_by_name( adk, pt_power_gl ) # g.connect_by_name( pt_timing, genlibdb ) g.connect_by_name(signoff, genlibdb) g.connect_by_name(rtl_sim, gen_saif_rtl) # run.vcd # g.connect_by_name( gl_sim, gen_saif_gl ) # run.vcd g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(gen_saif_rtl, dc) # run.saif g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(dc, pt_power_rtl) # design.namemap g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) # Core place and route flow g.connect_by_name(floorplan, init) g.connect_by_name(pin_placement, init) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, gdsmerge) # Openlane export g.connect_by_name(signoff, export) g.connect_by_name(gdsmerge, export) # DRC, LVS, timing signoff and power signoff g.connect_by_name(gdsmerge, magic_drc) g.connect_by_name(signoff, magic_antenna) # LVS using DEF g.connect_by_name(signoff, magic_def2spice) g.connect_by_name(signoff, netgen_lvs_def) g.connect_by_name(magic_def2spice, netgen_lvs_def) # LVS using GDS g.connect_by_name(gdsmerge, magic_gds2spice) g.connect_by_name(signoff, netgen_lvs_gds) g.connect_by_name(magic_gds2spice, netgen_lvs_gds) # LVS comparision using Calibre g.connect_by_name(signoff, calibre_lvs) g.connect_by_name(magic_gds2spice, calibre_lvs) g.connect_by_name(signoff, pt_timing) g.connect_by_name(signoff, pt_power_rtl) g.connect_by_name(gen_saif_rtl, pt_power_rtl) # run.saif # g.connect_by_name( signoff, pt_power_gl ) # g.connect_by_name( gen_saif_gl, pt_power_gl ) # run.saif # Gate level simulation # g.connect_by_name( adk, gl_sim ) # g.connect( signoff.o( 'design.vcs.pg.v' ), gl_sim.i( 'design.v' ) ) # g.connect( pt_timing.o( 'design.sdf' ), gl_sim.i( 'design.sdf' ) ) # g.connect( testbench.o( 'testbench.sv' ), gl_sim.i( 'testbench.sv' ) ) # g.connect( testbench.o( 'design.args.gls' ), gl_sim.i( 'design.args' ) ) # g.connect( testbench.o( 'test_vectors.txt' ), gl_sim.i( 'test_vectors.txt' ) ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'view-standard' parameters = { 'construct_path': __file__, 'design_name': 'global_buffer', 'clock_period': 1.25, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # hold target slack 'hold_target_slack': 0.045, # array_width = width of CGRA below GLB; `pin-assignments.tcl` uses # these parms to set up per-cgra-column ports connecting glb tile # signals in glb_top to corresponding CGRA tile columns below glb_top 'array_width': 32, 'num_glb_tiles': 16, 'tool': "VCS", # glb tile memory size (unit: KB) 'glb_tile_mem_size': 256, 'rtl_testvectors': ["test1", "test2", "test3", "test4"], 'gls_testvectors': ["test1.pwr", "test2.pwr"] } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') sim_compile = Step(this_dir + '/sim-compile') sim_run = Step(this_dir + '/sim-run') sim_gl_compile = Step(this_dir + '/sim-gl-compile') glb_tile = Step(this_dir + '/glb_tile') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-hierarchical') lib2db = Step(this_dir + '/../common/synopsys-dc-lib2db') # Default steps info = Step('info', default=True) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlib = Step('cadence-genus-genlib', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) if parameters['tool'] == 'VCS': sim_compile.extend_outputs(['simv', 'simv.daidir']) sim_gl_compile.extend_outputs(['simv', 'simv.daidir']) sim_run.extend_inputs(['simv', 'simv.daidir']) elif parameters['tool'] == 'XCELIUM': sim_compile.extend_outputs(['xcelium.d']) sim_gl_compile.extend_outputs(['xcelium.d']) sim_run.extend_inputs(['xcelium.d']) sim_gl_run_nodes = {} ptpx_gl_nodes = {} for test in parameters["gls_testvectors"]: sim_gl_run = Step(this_dir + '/sim-gl-run') ptpx_gl = Step(this_dir + '/synopsys-ptpx-gl') # rename sim_gl_run.set_name(f"sim_gl_run_{test}") ptpx_gl.set_name(f"ptpx_gl_{test}") sim_gl_run_nodes[test] = sim_gl_run ptpx_gl_nodes[test] = ptpx_gl sim_gl_run.update_params({'test': test}, allow_new=True) # Gate-level ptpx node ptpx_gl.set_param("strip_path", "top/dut") ptpx_gl.extend_inputs(glb_tile.all_outputs()) if parameters['tool'] == 'VCS': sim_gl_run.extend_inputs(['simv', 'simv.daidir']) elif parameters['tool'] == 'XCELIUM': sim_gl_run.extend_inputs(['xcelium.d']) # Add header files to outputs rtl.extend_outputs(['header']) rtl.extend_postconditions(["assert File( 'outputs/header' ) "]) # Add (dummy) parameters to the default innovus init step init.update_params({'core_width': 0, 'core_height': 0}, allow_new=True) # Add glb_tile macro inputs to downstream nodes pt_signoff.extend_inputs(['glb_tile_tt.db']) # These steps need timing info for glb_tiles tile_steps = \ [ synth, iflow, init, power, place, cts, postcts_hold, route, postroute, postroute_hold, signoff, genlib ] for step in tile_steps: step.extend_inputs(['glb_tile_tt.lib', 'glb_tile.lef']) # Need the glb_tile gds to merge into the final layout signoff.extend_inputs(['glb_tile.gds']) # Need glb_tile lvs.v file for LVS lvs.extend_inputs(['glb_tile.lvs.v']) # Need sram spice file for LVS lvs.extend_inputs(['sram.spi']) xlist = synth.get_postconditions() xlist = \ [ _ for _ in xlist if 'percent_clock_gated' not in _ ] xlist = synth.set_postconditions(xlist) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(sim_compile) g.add_step(sim_run) g.add_step(sim_gl_compile) g.add_step(glb_tile) g.add_step(constraints) g.add_step(synth) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlib) g.add_step(lib2db) g.add_step(drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) for test in parameters["gls_testvectors"]: g.add_step(sim_gl_run_nodes[test]) g.add_step(ptpx_gl_nodes[test]) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(glb_tile, synth) g.connect_by_name(glb_tile, iflow) g.connect_by_name(glb_tile, init) g.connect_by_name(glb_tile, power) g.connect_by_name(glb_tile, place) g.connect_by_name(glb_tile, cts) g.connect_by_name(glb_tile, postcts_hold) g.connect_by_name(glb_tile, route) g.connect_by_name(glb_tile, postroute) g.connect_by_name(glb_tile, postroute_hold) g.connect_by_name(glb_tile, signoff) g.connect_by_name(glb_tile, pt_signoff) g.connect_by_name(glb_tile, genlib) g.connect_by_name(glb_tile, drc) g.connect_by_name(glb_tile, lvs) g.connect_by_name(rtl, sim_compile) g.connect_by_name(sim_compile, sim_run) g.connect_by_name(rtl, synth) g.connect_by_name(constraints, synth) # glb_tile can use the same rtl as glb_top g.connect_by_name(rtl, glb_tile) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, genlib) g.connect_by_name(signoff, genlib) g.connect_by_name(rtl, sim_gl_compile) g.connect_by_name(adk, sim_gl_compile) g.connect_by_name(glb_tile, sim_gl_compile) g.connect_by_name(signoff, sim_gl_compile) for test in parameters["gls_testvectors"]: g.connect_by_name(sim_gl_compile, sim_gl_run_nodes[test]) for test in parameters["gls_testvectors"]: g.connect_by_name(adk, ptpx_gl_nodes[test]) g.connect_by_name(glb_tile, ptpx_gl_nodes[test]) g.connect_by_name(signoff, ptpx_gl_nodes[test]) g.connect_by_name(sim_gl_run_nodes[test], ptpx_gl_nodes[test]) g.connect_by_name(genlib, lib2db) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # rtl parameters update rtl.update_params({'glb_only': True}, allow_new=True) # pin assignment parameters update init.update_params({'array_width': parameters['array_width']}, allow_new=True) init.update_params({'num_glb_tiles': parameters['num_glb_tiles']}, allow_new=True) # Change nthreads synth.update_params({'nthreads': 4}) iflow.update_params({'nthreads': 4}) order = init.get_param('order') # get the default script run order reporting_idx = order.index('reporting.tcl') # find reporting.tcl # Add dont-touch before reporting order.insert(reporting_idx, 'dont-touch.tcl') init.update_params({'order': order}) # Increase hold slack on postroute_hold step postroute_hold.update_params( {'hold_target_slack': parameters['hold_target_slack']}, allow_new=True) # useful_skew cts.update_params({'useful_skew': False}, allow_new=True) return g
def construct(): g = Graph() # ------------------------------------------------------------------------- # Supported tests # ------------------------------------------------------------------------- test_names = [ # CPU Tests #'apb_mux_test', #'hello_test', #'memory_test', #'dma_single_channel', #'default_slaves_test', #'interrupts_test', #'tlx_test', #'cgra_test', #'master_clock_test', 'app_test', 'harris_test', #'app_test_two_images', #'app_test_reconfig', #'app_test_reconfig_pipeline', #'app_test_2_kernels_1_cgra', # 'cascade_test', #'resnet_test', #'resnet_test_i4_o3', #'demosaic_complex', #'demosaic_complex_twice', #'demosaic_complex_harris', #'resnet_pond', # CXDT Tests 'discovery', ] # ------------------------------------------------------------------------- # Parameters # ------------------------------------------------------------------------- parameters = { 'construct_file': __file__, 'design_name': 'test-soc', 'soc_only': False, 'interconnect_only': False, 'array_width': 32, 'array_height': 16, 'clock_period': 1.0, 'ARM_IP_DIR': '/home/kkoul/aham3soc_armip', 'AHA_IP_DIR': '/sim/kkoul/AhaM3SoC', 'GATE_LEVEL_DIR': '/home/kkoul/gate_level_199', 'GARNET_DIR': '/sim/kkoul/garnet', 'TLX_FWD_DATA_LO_WIDTH': 16, 'TLX_REV_DATA_LO_WIDTH': 45, } # ------------------------------------------------------------------------- # Custom steps # ------------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) garnet_rtl = Step(parameters['GARNET_DIR'] + '/mflowgen/common/rtl') compile_design = Step(this_dir + '/compile_design') compile_design_gls = Step(this_dir + '/compile_design_gls') build_test = Step(this_dir + '/build_test') run_test = Step(this_dir + '/run_test') run_test_gls = Step(this_dir + '/run_test_gls') verdict = Step(this_dir + '/verdict') test_gen = Step(this_dir + '/test_gen') ptpx = Step(this_dir + '/ptpx') # ------------------------------------------------------------------------- # Parallelize test build and run # ------------------------------------------------------------------------- test_count = len(test_names) build_steps = list(map((lambda _: build_test.clone()), range(test_count))) run_steps = list(map((lambda _: run_test.clone()), range(test_count))) run_gls_steps = list( map((lambda _: run_test_gls.clone()), range(test_count))) ptpx_steps = list(map((lambda _: ptpx.clone()), range(test_count))) for step, name in zip(build_steps, test_names): step.set_name('build_' + name) for step, name in zip(run_steps, test_names): step.set_name('run_' + name) for step, name in zip(run_gls_steps, test_names): step.set_name('run_gls_' + name) for step, name in zip(ptpx_steps, test_names): step.set_name('ptpx_' + name) # ------------------------------------------------------------------------- # Input/output dependencies # ------------------------------------------------------------------------- # 'compile_design' step produces a simulation executable and its accompanying collateral compile_design.extend_outputs(['xcelium.d']) compile_design.extend_inputs(['design.v']) compile_design_gls.extend_outputs(['simv']) compile_design_gls.extend_outputs(['simv.daidir']) # 'build_test' produces final images for both the CXDT and CPU for step in build_steps: step.extend_outputs(['CXDT.bin']) # 'run_tests' takes CXDT.bin, CPU.bin, and xcelium.d to produce a log for step, test in zip(run_steps, test_names): step.extend_inputs(['CXDT.bin', 'xcelium.d']) step.extend_outputs(['xrun_run_' + test + '.log']) # 'run_gls_tests' takes CXDT.bin, CPU.bin, and simv and simv.daidir to produce a log for step, test in zip(run_gls_steps, test_names): step.extend_inputs(['CXDT.bin', 'simv', 'simv.daidir']) step.extend_outputs(['run.saif']) # 'ptpx' takes run.saif to produce power reports for step, test in zip(run_gls_steps, test_names): step.extend_inputs(['run.saif']) # 'verdict' consumes the run logs run_logs = list(map((lambda test: 'xrun_run_' + test + '.log'), test_names)) verdict.extend_inputs(run_logs) # ------------------------------------------------------------------------- # Graph -- Add nodes # ------------------------------------------------------------------------- g.add_step(garnet_rtl) g.add_step(compile_design) g.add_step(compile_design_gls) g.add_step(test_gen) for s in build_steps: g.add_step(s) for s in run_steps: g.add_step(s) for s in run_gls_steps: g.add_step(s) for s in ptpx_steps: g.add_step(s) g.add_step(verdict) # ------------------------------------------------------------------------- # Graph -- Add edges # ------------------------------------------------------------------------- g.connect_by_name(garnet_rtl, compile_design) for r, b in zip(run_steps, build_steps): g.connect_by_name(b, r) g.connect_by_name(compile_design, r) g.connect_by_name(r, verdict) for r, b in zip(run_gls_steps, build_steps): g.connect_by_name(b, r) g.connect_by_name(compile_design_gls, r) for p, r in zip(ptpx_steps, run_gls_steps): g.connect_by_name(r, p) # ------------------------------------------------------------------------- # Set general parameters # ------------------------------------------------------------------------- g.update_params(parameters) # ------------------------------------------------------------------------- # Set node-specific parameters # ------------------------------------------------------------------------- # Turn off power domain to improve the speed garnet_rtl.update_params({'PWR_AWARE': False}) garnet_rtl.update_params({'array_width': parameters['array_width']}) garnet_rtl.update_params({'array_height': parameters['array_height']}) for step, test in zip(build_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(run_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(run_gls_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(ptpx_steps, test_names): step.update_params({'TEST_NAME': test}) compile_design.update_params({'CGRA_RD_WS': 4}) # ------------------------------------------------------------------------- # Pre-conditions # ------------------------------------------------------------------------- # 'verdict' requires all tests to have passed verdict.extend_preconditions([ "assert 'TEST PASSED' in File('inputs/" + run_log + "', enable_case_sensitive = True)" for run_log in run_logs ]) # ------------------------------------------------------------------------- # Post-conditions # ------------------------------------------------------------------------- # 'compile_tbench' must be successful compile_design.extend_postconditions([ "assert 'Error' not in File('xrun_compile.log', enable_case_sensitive = True)", "assert File('outputs/xcelium.d')", ]) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path' : __file__, 'design_name' : 'global_controller', 'clock_period' : 10.0, 'adk' : adk_name, 'adk_view' : adk_view, # Synthesis 'flatten_effort' : 3, 'topographical' : True, # RTL Generation 'interconnect_only' : False, # Power Domains (leave this false) 'PWR_AWARE' : False } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/rtl' ) constraints = Step( this_dir + '/constraints' ) custom_init = Step( this_dir + '/custom-init' ) custom_power = Step( this_dir + '/../common/custom-power-leaf' ) # Default steps info = Step( 'info', default=True ) #constraints = Step( 'constraints', default=True ) dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs( custom_init.all_outputs() ) power.extend_inputs( custom_power.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( init ) g.add_step( custom_init ) g.add_step( power ) g.add_step( custom_power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( signoff ) g.add_step( pt_signoff ) g.add_step( genlibdb ) g.add_step( gdsmerge ) g.add_step( drc ) g.add_step( lvs ) g.add_step( debugcalibre ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, gdsmerge ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( rtl, dc ) g.connect_by_name( constraints, dc ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( dc, power ) g.connect_by_name( dc, place ) g.connect_by_name( dc, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, signoff ) g.connect_by_name( custom_init, init ) g.connect_by_name( custom_power, power ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, signoff ) g.connect_by_name( signoff, gdsmerge ) g.connect_by_name( signoff, drc ) g.connect_by_name( signoff, lvs ) g.connect_by_name( gdsmerge, drc ) g.connect_by_name( gdsmerge, lvs ) g.connect_by_name( signoff, genlibdb ) g.connect_by_name( adk, genlibdb ) g.connect_by_name( adk, pt_signoff ) g.connect_by_name( signoff, pt_signoff ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( dc, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # init -- Add 'add-endcaps-welltaps.tcl' after 'floorplan.tcl' order = init.get_param('order') # get the default script run order floorplan_idx = order.index( 'floorplan.tcl' ) # find floorplan.tcl order.insert( floorplan_idx + 1, 'add-endcaps-welltaps.tcl' ) # add here init.update_params( { 'order': order } ) # GLC Uses leaf-level power strategy, which is shared with other blocks # that use power domains flow power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' pwr_aware = True parameters = { 'construct_path': __file__, 'design_name': 'Tile_PE', 'clock_period': 1.15, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # RTL Generation 'interconnect_only': True, # Power Domains 'PWR_AWARE': pwr_aware } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_power = Step(this_dir + '/../common/custom-power-leaf') genlibdb_constraints = Step(this_dir + '/../common/custom-genlibdb-constraints') # Power aware setup if pwr_aware: power_domains = Step(this_dir + '/../common/power-domains') #pwr_aware_gls = Step( this_dir + '/../common/pwr-aware-gls' ) # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) genlibdb.extend_inputs(genlibdb_constraints.all_outputs()) # Extra input to DC for constraints dc.extend_inputs(["common.tcl", "reporting.tcl"]) # Power aware setup if pwr_aware: dc.extend_inputs([ 'designer-interface.tcl', 'upf_Tile_PE.tcl', 'pe-constraints.tcl', 'pe-constraints-2.tcl', 'dc-dont-use-constraints.tcl' ]) init.extend_inputs([ 'upf_Tile_PE.tcl', 'pe-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-pe-floorplan.tcl', 'pe-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'pe-power-switches-setup.tcl', 'add-power-switches.tcl' ]) place.extend_inputs(['place-dont-use-constraints.tcl']) power.extend_inputs(['pd-globalnetconnect.tcl']) cts.extend_inputs(['conn-aon-cells-vdd.tcl']) postcts_hold.extend_inputs(['conn-aon-cells-vdd.tcl']) route.extend_inputs(['conn-aon-cells-vdd.tcl']) postroute.extend_inputs(['conn-aon-cells-vdd.tcl']) signoff.extend_inputs( ['conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl']) #pwr_aware_gls.extend_inputs(['design.vcs.pg.v']) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb_constraints) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(debugcalibre) # Power aware step if pwr_aware: g.add_step(power_domains) #g.add_step( pwr_aware_gls ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(genlibdb_constraints, genlibdb) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Pwr aware steps: if pwr_aware: g.connect_by_name(power_domains, dc) g.connect_by_name(power_domains, init) g.connect_by_name(power_domains, power) g.connect_by_name(power_domains, place) g.connect_by_name(power_domains, cts) g.connect_by_name(power_domains, postcts_hold) g.connect_by_name(power_domains, route) g.connect_by_name(power_domains, postroute) g.connect_by_name(power_domains, signoff) #g.connect_by_name( adk, pwr_aware_gls) #g.connect_by_name( signoff, pwr_aware_gls) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Update PWR_AWARE variable dc.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) if pwr_aware: init.update_params({'flatten_effort': parameters['flatten_effort']}, True) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' order = init.get_param('order') # get the default script run order pin_idx = order.index('pin-assignments.tcl') # find pin-assignments.tcl order.insert(pin_idx + 1, 'edge-blockages.tcl') # add here init.update_params({'order': order}) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index('read_design.tcl') # find read_design.tcl order.insert(read_idx + 1, 'genlibdb-constraints.tcl') # add here genlibdb.update_params({'order': order}) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index('floorplan.tcl') # find floorplan.tcl order.insert(read_idx + 1, 'pe-load-upf.tcl') # add here order.insert(read_idx + 2, 'pd-pe-floorplan.tcl') # add here order.insert(read_idx + 3, 'pe-add-endcaps-welltaps-setup.tcl') # add here order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl') # add here order.insert(read_idx + 5, 'pe-power-switches-setup.tcl') # add here order.insert(read_idx + 6, 'add-power-switches.tcl') # add here order.remove('add-endcaps-welltaps.tcl') init.update_params({'order': order}) # power node order = power.get_param('order') order.insert(0, 'pd-globalnetconnect.tcl') # add here order.remove('globalnetconnect.tcl') power.update_params({'order': order}) # place node order = place.get_param('order') read_idx = order.index('main.tcl') # find main.tcl order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') place.update_params({'order': order}) # cts node order = cts.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here cts.update_params({'order': order}) # postcts_hold node order = postcts_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postcts_hold.update_params({'order': order}) # route node order = route.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here route.update_params({'order': order}) # postroute node order = postroute.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postroute.update_params({'order': order}) # signoff node order = signoff.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here read_idx = order.index( 'generate-results.tcl') # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') signoff.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'view-standard' if which("calibre") is not None: drc_rule_deck = 'calibre-drc-chip.rule' antenna_drc_rule_deck = 'calibre-drc-antenna.rule' power_drc_rule_deck = 'calibre-drc-block.rule' else: drc_rule_deck = 'pegasus-drc-chip.rule' antenna_drc_rule_deck = 'pegasus-drc-antenna.rule' power_drc_rule_deck = 'pegasus-drc-block.rule' parameters = { 'construct_path': __file__, 'design_name': 'GarnetSOC_pad_frame', 'clock_period': 1.3, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 0, 'topographical': True, # RTL Generation 'array_width': 32, 'array_height': 16, 'num_glb_tiles': 16, 'interconnect_only': False, # glb tile memory size (unit: KB) # 'glb_tile_mem_size' : 64, # 64x16 => 1M global buffer 'glb_tile_mem_size': 256, # 256*16 => 4M global buffer # Power Domains 'PWR_AWARE': True, # Include Garnet? 'soc_only': False, # Include SoC core? (use 0 for false, 1 for true) 'include_core': 1, # Include sealring? 'include_sealring': True, # SRAM macros 'num_words': 2048, 'word_size': 64, 'mux_size': 8, 'corner': "tt0p8v25c", 'partial_write': True, # Dragonphy 'dragonphy_rdl_x': '613.565u', 'dragonphy_rdl_y': '3901.872u', # Low Effort flow 'express_flow': False, 'skip_verify_connectivity': True, # Hold fixing 'signoff_engine': True, 'hold_target_slack': 0.060, # LVS # - need lvs2 because dragonphy uses LVT cells 'lvs_extra_spice_include': 'inputs/adk_lvs2/*.cdl', 'lvs_hcells_file': 'inputs/adk/hcells.inc', 'lvs_connect_names': '"VDD VSS VDDPST"', 'lvs_verify_netlist': 0, # TSMC16 support for LVS - need lvs2 because dragonphy uses LVT cells 'adk_view_lvs2': 'multivt', # TLX Ports Partitions 'TLX_FWD_DATA_LO_WIDTH': 16, 'TLX_REV_DATA_LO_WIDTH': 45, # DRC rule deck 'drc_rule_deck': drc_rule_deck, 'antenna_drc_rule_deck': antenna_drc_rule_deck, 'power_drc_rule_deck': power_drc_rule_deck, 'nthreads': 16, # Testbench 'cgra_apps': ["tests/conv_1_2", "tests/conv_2_1"] } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') soc_rtl = Step(this_dir + '/../common/soc-rtl-v2') gen_sram = Step(this_dir + '/../common/gen_sram_macro') constraints = Step(this_dir + '/constraints') read_design = Step(this_dir + '/../common/fc-custom-read-design') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-chip') init_fc = Step(this_dir + '/../common/init-fullchip') io_file = Step(this_dir + '/io_file') pre_route = Step(this_dir + '/pre-route') sealring = Step(this_dir + '/sealring') netlist_fixing = Step(this_dir + '/../common/fc-netlist-fixing') # Block-level designs tile_array = Step(this_dir + '/tile_array') glb_top = Step(this_dir + '/glb_top') global_controller = Step(this_dir + '/global_controller') dragonphy = Step(this_dir + '/dragonphy') # CGRA simulation cgra_rtl_sim_compile = Step(this_dir + '/cgra_rtl_sim_compile') cgra_rtl_sim_run = Step(this_dir + '/cgra_rtl_sim_run') cgra_sim_build = Step(this_dir + '/cgra_sim_build') # cgra_gl_sim_compile = Step( this_dir + '/cgra_gl_sim_compile' ) # cgra_gl_sim_run = Step( this_dir + '/cgra_gl_sim_run' ) # cgra_gl_ptpx = Step( this_dir + '/cgra_gl_ptpx' ) # cgra_rtl_sim_verdict = Step( this_dir + '/cgra_rtl_sim_verdict' ) # cgra_gl_sim_verdict = Step( this_dir + '/cgra_gl_sim_verdict' ) # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) merge_rdl = Step('mentor-calibre-gdsmerge-child', default=True) fill = Step('mentor-calibre-fill', default=True) merge_fill = Step('mentor-calibre-gdsmerge-child', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) merge_rdl = Step('cadence-pegasus-gdsmerge-child', default=True) fill = Step('cadence-pegasus-fill', default=True) merge_fill = Step('cadence-pegasus-gdsmerge-child', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) merge_rdl.set_name('gdsmerge-dragonphy-rdl') merge_fill.set_name('gdsmerge-fill') # Send in the clones # 'power' step now gets its own design-rule check power_drc = drc.clone() power_drc.set_name('power-drc') # Antenna DRC Check antenna_drc = drc.clone() antenna_drc.set_name('antenna-drc') # Add cgra tile macro inputs to downstream nodes synth.extend_inputs(['tile_array_tt.lib', 'tile_array.lef']) synth.extend_inputs(['glb_top_tt.lib', 'glb_top.lef']) synth.extend_inputs(['global_controller_tt.lib', 'global_controller.lef']) synth.extend_inputs(['sram_tt.lib', 'sram.lef']) synth.extend_inputs(['dragonphy_top.lef']) # Exclude dragonphy_top from synth inputs to prevent floating # dragonphy inputs from being tied to 0 pt_signoff.extend_inputs(['tile_array_tt.db']) pt_signoff.extend_inputs(['glb_top_tt.db']) pt_signoff.extend_inputs(['global_controller_tt.db']) pt_signoff.extend_inputs(['sram_tt.db']) pt_signoff.extend_inputs(['dragonphy_top_tt.db']) route.extend_inputs(['pre-route.tcl']) signoff.extend_inputs(sealring.all_outputs()) signoff.extend_inputs(netlist_fixing.all_outputs()) # These steps need timing info for cgra tiles hier_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff] for step in hier_steps: step.extend_inputs(['tile_array_tt.lib', 'tile_array.lef']) step.extend_inputs(['glb_top_tt.lib', 'glb_top.lef']) step.extend_inputs( ['global_controller_tt.lib', 'global_controller.lef']) step.extend_inputs(['sram_tt.lib', 'sram.lef']) step.extend_inputs(['dragonphy_top_tt.lib', 'dragonphy_top.lef']) step.extend_inputs(['dragonphy_RDL.lef']) # Need all block gds's to merge into the final layout gdsmerge_nodes = [signoff, power] for node in gdsmerge_nodes: node.extend_inputs(['tile_array.gds']) node.extend_inputs(['glb_top.gds']) node.extend_inputs(['global_controller.gds']) node.extend_inputs(['sram.gds']) node.extend_inputs(['dragonphy_top.gds']) node.extend_inputs(['dragonphy_RDL.gds']) # Need extracted spice files for both tile types to do LVS lvs.extend_inputs(['tile_array.lvs.v']) lvs.extend_inputs(['tile_array.sram.spi']) lvs.extend_inputs(['glb_top.lvs.v']) lvs.extend_inputs(['glb_top.sram.spi']) lvs.extend_inputs(['global_controller.lvs.v']) lvs.extend_inputs(['sram.spi']) lvs.extend_inputs(['dragonphy_top.spi']) lvs.extend_inputs(['adk_lvs2']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) init.extend_inputs(init_fc.all_outputs()) power.extend_inputs(custom_power.all_outputs()) synth.extend_inputs(soc_rtl.all_outputs()) synth.extend_inputs(read_design.all_outputs()) synth.extend_inputs(["cons_scripts"]) power.extend_outputs(["design-merged.gds"]) if parameters['interconnect_only'] is False: rtl.extend_outputs(['header']) rtl.extend_postconditions(["assert File( 'outputs/header' ) "]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(soc_rtl) g.add_step(gen_sram) g.add_step(tile_array) g.add_step(glb_top) g.add_step(global_controller) g.add_step(dragonphy) g.add_step(constraints) g.add_step(read_design) g.add_step(synth) g.add_step(iflow) g.add_step(init) g.add_step(init_fc) g.add_step(io_file) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(pre_route) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(sealring) g.add_step(netlist_fixing) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(merge_rdl) g.add_step(fill) g.add_step(merge_fill) g.add_step(drc) g.add_step(antenna_drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) # Post-Power DRC check g.add_step(power_drc) # App test nodes g.add_step(cgra_rtl_sim_compile) g.add_step(cgra_sim_build) g.add_step(cgra_rtl_sim_run) # g.add_step( cgra_gl_sim_compile ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, gen_sram) g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, merge_rdl) g.connect_by_name(adk, fill) g.connect_by_name(adk, merge_fill) g.connect_by_name(adk, drc) g.connect_by_name(adk, antenna_drc) g.connect_by_name(adk, lvs) # Post-Power DRC check g.connect_by_name(adk, power_drc) # Connect RTL verification nodes g.connect_by_name(rtl, cgra_rtl_sim_compile) g.connect_by_name(cgra_sim_build, cgra_rtl_sim_run) g.connect_by_name(cgra_rtl_sim_compile, cgra_rtl_sim_run) # Connect GL verification nodes # g.connect_by_name( signoff, cgra_gl_sim_compile ) # All of the blocks within this hierarchical design # Skip these if we're doing soc_only if parameters['soc_only'] == False: blocks = [tile_array, glb_top, global_controller, dragonphy] for block in blocks: g.connect_by_name(block, synth) g.connect_by_name(block, iflow) g.connect_by_name(block, init) g.connect_by_name(block, power) g.connect_by_name(block, place) g.connect_by_name(block, cts) g.connect_by_name(block, postcts_hold) g.connect_by_name(block, route) g.connect_by_name(block, postroute) g.connect_by_name(block, postroute_hold) g.connect_by_name(block, signoff) g.connect_by_name(block, pt_signoff) g.connect_by_name(block, drc) g.connect_by_name(block, lvs) # Tile_array can use rtl from rtl node g.connect_by_name(rtl, tile_array) # glb_top can use rtl from rtl node g.connect_by_name(rtl, glb_top) # global_controller can use rtl from rtl node g.connect_by_name(rtl, global_controller) g.connect_by_name(rtl, synth) g.connect_by_name(soc_rtl, synth) g.connect_by_name(constraints, synth) g.connect_by_name(read_design, synth) g.connect_by_name(soc_rtl, io_file) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(custom_power, power) # SRAM macro g.connect_by_name(gen_sram, synth) g.connect_by_name(gen_sram, iflow) g.connect_by_name(gen_sram, init) g.connect_by_name(gen_sram, power) g.connect_by_name(gen_sram, place) g.connect_by_name(gen_sram, cts) g.connect_by_name(gen_sram, postcts_hold) g.connect_by_name(gen_sram, route) g.connect_by_name(gen_sram, postroute) g.connect_by_name(gen_sram, postroute_hold) g.connect_by_name(gen_sram, signoff) g.connect_by_name(gen_sram, pt_signoff) g.connect_by_name(gen_sram, drc) g.connect_by_name(gen_sram, lvs) # Full chip floorplan stuff g.connect_by_name(io_file, init_fc) g.connect_by_name(init_fc, init) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) # Skipping g.connect(signoff.o('design-merged.gds'), merge_rdl.i('design.gds')) g.connect(dragonphy.o('dragonphy_RDL.gds'), merge_rdl.i('child.gds')) g.connect_by_name(merge_rdl, lvs) # Run Fill on merged GDS g.connect(merge_rdl.o('design_merged.gds'), fill.i('design.gds')) # Merge fill g.connect(merge_rdl.o('design_merged.gds'), merge_fill.i('design.gds')) g.connect(fill.o('fill.gds'), merge_fill.i('child.gds')) # Run DRC on merged and filled gds g.connect_by_name(merge_fill, drc) g.connect_by_name(merge_fill, antenna_drc) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) g.connect_by_name(pre_route, route) g.connect_by_name(sealring, signoff) g.connect_by_name(netlist_fixing, signoff) # Post-Power DRC g.connect(power.o('design-merged.gds'), power_drc.i('design_merged.gds')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- # Allow user to override parms with env in a limited sort of way parameters = sr_override_parms(parameters) print(f'parameters["hold_target_slack"]={parameters["hold_target_slack"]}') g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # DC needs these param to set the NO_CGRA macro synth.update_params({'soc_only': parameters['soc_only']}, True) # DC needs these params to set macros in soc rtl synth.update_params( {'TLX_FWD_DATA_LO_WIDTH': parameters['TLX_FWD_DATA_LO_WIDTH']}, True) synth.update_params( {'TLX_REV_DATA_LO_WIDTH': parameters['TLX_REV_DATA_LO_WIDTH']}, True) init.update_params({'soc_only': parameters['soc_only']}, True) init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'alignment-cells.tcl', 'analog-bumps/route-phy-bumps.tcl', 'analog-bumps/bump-connect.tcl', 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'place-macros.tcl', 'dont-touch.tcl' ] }) # glb_top parameters update glb_top.update_params({'array_width': parameters['array_width']}, True) glb_top.update_params( {'glb_tile_mem_size': parameters['glb_tile_mem_size']}, True) glb_top.update_params({'num_glb_tiles': parameters['num_glb_tiles']}, True) # App test parameters update cgra_rtl_sim_compile.update_params( {'array_width': parameters['array_width']}, True) cgra_rtl_sim_compile.update_params( {'array_height': parameters['array_height']}, True) cgra_rtl_sim_compile.update_params( {'clock_period': parameters['clock_period']}, True) cgra_rtl_sim_compile.update_params( {'glb_tile_mem_size': parameters['glb_tile_mem_size']}, True) cgra_rtl_sim_run.update_params({'cgra_apps': parameters['cgra_apps']}, True) # Power node order manipulation order = power.get_param('order') # Move endcap/welltap insertion to end of power step to improve runtime order.append('add-endcaps-welltaps.tcl') # Stream out post-power GDS so that we can run DRC here order.append('innovus-foundation-flow/custom-scripts/stream-out.tcl') order.append('attach-results-to-outputs.tcl') power.update_params({'order': order}) # Add pre-route plugin to insert skip_routing commands order = route.get_param('order') order.insert(0, 'pre-route.tcl') route.update_params({'order': order}) # Signoff order additions order = signoff.get_param('order') # Add sealring at beginning of signoff, so it's in before we stream out GDS if parameters['include_sealring'] == True: order.insert(0, 'add-sealring.tcl') # Add netlist-fixing script before we save new netlist index = order.index('generate-results.tcl') order.insert(index, 'netlist-fixing.tcl') signoff.update_params({'order': order}) merge_rdl.update_params({ 'coord_x': parameters['dragonphy_rdl_x'], 'coord_y': parameters['dragonphy_rdl_y'], 'flatten_child': True, 'design_top_cell': parameters['design_name'], 'child_top_cell': 'dragonphy_RDL' }) merge_fill.update_params({ 'design_top_cell': parameters['design_name'], 'child_top_cell': f"{parameters['design_name']}_F16a" }) # Antenna DRC node needs to use antenna rule deck antenna_drc.update_params( {'drc_rule_deck': parameters['antenna_drc_rule_deck']}) # Power DRC node should use block level rule deck to improve runtimes and not report false errors power_drc.update_params( {'drc_rule_deck': parameters['power_drc_rule_deck']}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'pad_frame', 'clock_period': 20.0, 'adk': adk_name, 'adk_view': adk_view, # # Synthesis 'flatten_effort': 3, 'topographical': False, # # drc # drc_rule_deck: /sim/steveri/runsets/ruleset_icovl # NO GOOD instead do: # cd ../adks/tsmc16-adk/stdview; ln -s /sim/steveri/runsets/ruleset_icovl 'drc_rule_deck': 'ruleset_icovl', } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') init_fullchip = Step(this_dir + '/../common/init-fullchip') # # More custom steps: custom power step (unused) # custom_power = Step( this_dir + '/../common/custom-power-leaf' ) # Some kinda primetime thingy maybe - not using it # genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' ) # Default steps info = Step('info', default=True) # constraints= Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) # power = Step( 'cadence-innovus-power', default=True ) # place = Step( 'cadence-innovus-place', default=True ) # cts = Step( 'cadence-innovus-cts', default=True ) # postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) # route = Step( 'cadence-innovus-route', default=True ) # postroute = Step( 'cadence-innovus-postroute', default=True ) # signoff = Step( 'cadence-innovus-signoff', default=True ) # pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) # genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) else: drc = Step('cadence-pegasus-drc', default=True) # lvs = Step( 'mentor-calibre-lvs', default=True ) # debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Send in the clones # "init" now builds a gds file for its own drc check "drc_icovl"; # so need a gdsmerge step between the two init_gdsmerge = gdsmerge.clone() init_gdsmerge.set_name('init-gdsmerge') # icovl design-rule check runs after 'init' step drc_icovl = drc.clone() drc_icovl.set_name('drc-icovl') #----------------------------------------------------------------------- # Add extra input edges to innovus steps that need custom tweaks #----------------------------------------------------------------------- # "init" (cadence-innovus-init) inputs are "init_fullchip" outputs init.extend_inputs(init_fullchip.all_outputs()) # Also: 'init' now produces a gds file # for intermediate drc check 'drc-icovl' # by way of intermediate gdsmerge step "init-gdsmerge" init.extend_outputs(["design.gds.gz"]) # # "power" inputs are "custom_power" outputs # power.extend_inputs( custom_power.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) # pre_flowsetup => iflow # g.add_step( pre_flowsetup ) g.add_step(iflow) g.add_step(init_fullchip) g.add_step(init) # init => init_gdsmerge => drc_icovl g.add_step(init_gdsmerge) g.add_step(drc_icovl) # g.add_step( power ) # g.add_step( custom_power ) # g.add_step( place ) # g.add_step( cts ) # g.add_step( postcts_hold ) # g.add_step( route ) # g.add_step( postroute ) # g.add_step( signoff ) # g.add_step( pt_signoff ) # # g.add_step( genlibdb_constraints ) # g.add_step( genlibdb ) # g.add_step( gdsmerge ) # g.add_step( drc ) # g.add_step( lvs ) # g.add_step( debugcalibre ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) # g.connect_by_name( adk, pre_flowsetup ) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, init_gdsmerge) g.connect_by_name(adk, drc_icovl) # g.connect_by_name( adk, power ) # g.connect_by_name( adk, place ) # g.connect_by_name( adk, cts ) # g.connect_by_name( adk, postcts_hold ) # g.connect_by_name( adk, route ) # g.connect_by_name( adk, postroute ) # g.connect_by_name( adk, signoff ) # g.connect_by_name( adk, gdsmerge ) # g.connect_by_name( adk, drc ) # g.connect_by_name( adk, lvs ) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) # sr02.2020 b/c now init_fullchip needs io_file from rtl g.connect_by_name(rtl, init_fullchip) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) # g.connect_by_name( dc, power ) # g.connect_by_name( dc, place ) # g.connect_by_name( dc, cts ) # Maybe don't need this no more... # # g.connect_by_name( pre_flowsetup, iflow ) # # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff # for step in pre_flowsetup_followers: # g.connect_by_name( pre_flowsetup, step) g.connect_by_name(iflow, init) # g.connect_by_name( iflow, power ) # g.connect_by_name( iflow, place ) # g.connect_by_name( iflow, cts ) # g.connect_by_name( iflow, postcts_hold ) # g.connect_by_name( iflow, route ) # g.connect_by_name( iflow, postroute ) # g.connect_by_name( iflow, signoff ) # # for step in iflow_followers: # # g.connect_by_name( iflow, step) g.connect_by_name(init_fullchip, init) # g.connect_by_name( custom_power, power ) # init => init_gdsmerge => drc_icovl g.connect_by_name(init, init_gdsmerge) g.connect_by_name(init_gdsmerge, drc_icovl) # g.connect_by_name( init, power ) # g.connect_by_name( power, place ) # g.connect_by_name( place, cts ) # g.connect_by_name( cts, postcts_hold ) # g.connect_by_name( postcts_hold, route ) # g.connect_by_name( route, postroute ) # g.connect_by_name( postroute, signoff ) # g.connect_by_name( signoff, gdsmerge ) # g.connect_by_name( signoff, drc ) # g.connect_by_name( signoff, lvs ) # g.connect_by_name( gdsmerge, drc ) # g.connect_by_name( gdsmerge, lvs ) # g.connect_by_name( signoff, genlibdb ) # g.connect_by_name( adk, genlibdb ) # # g.connect_by_name( genlibdb_constraints, genlibdb ) # g.connect_by_name( adk, pt_signoff ) # g.connect_by_name( signoff, pt_signoff ) # # g.connect_by_name( adk, debugcalibre ) # g.connect_by_name( dc, debugcalibre ) # g.connect_by_name( iflow, debugcalibre ) # g.connect_by_name( signoff, debugcalibre ) # g.connect_by_name( drc, debugcalibre ) # g.connect_by_name( lvs, debugcalibre ) # yes? no? # g.connect_by_name( drc_icovl, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Default order can be found in e.g. # mflowgen/steps/cadence-innovus-init/configure.yml # - main.tcl # - quality-of-life.tcl # - floorplan.tcl # - pin-assignments.tcl # - make-path-groups.tcl # - reporting.tcl # I copied this from someone else, maybe glb_top or something # Looks like this order deletes pin assignments and adds endcaps/welltaps # then maybe get clean(er) post-floorplan drc # # 3/4 swapped order of streamout/align so to get gds *before* icovl init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'alignment-cells.tcl', # Let's try it without the bump routing maybe? # 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'gen-bumps.tcl', 'sealring.tcl', 'innovus-foundation-flow/custom-scripts/stream-out.tcl', 'attach-results-to-outputs.tcl', ] }) # Not sure what this is or why it was commented out... # # Adding new input for genlibdb node to run # genlibdb.update_params( # {'order': "\"read_design.tcl genlibdb-constraints.tcl extract_model.tcl\""} # ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'GarnetSOC_pad_frame', 'clock_period': 20.0, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': False, 'express_flow': False, 'skip_verify_connectivity': True, 'lvs_hcells_file': 'inputs/adk/hcells.inc', 'lvs_connect_names': '"VDD VSS VDDPST"' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') init_fullchip = Step(this_dir + '/../common/init-fullchip') netlist_fixing = Step(this_dir + '/../common/fc-netlist-fixing') # Custom step 'pre-flowsetup' # To get new lef cells e.g. 'icovl-cells.lef' into iflow, we gotta: # - create new step 'pre_flowsetup' whose outputs are icovl cells # -- link via "commands" group in pre-iflow/configure.yml # - connect pre-flowsetup step to flowsetup (iflow) step # - extend iflow inputs to include icovl cells # - iflow "setup.tcl" automatically includes "inputs/*.lef" pre_flowsetup = Step(this_dir + '/pre-flowsetup') # More custom steps custom_power = Step(this_dir + '/../common/custom-power-chip') # It's not plugged in yet! # custom_power = Step( this_dir + '/custom-power' ) # Some kinda primetime thingy maybe # genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' ) # Default steps info = Step('info', default=True) # constraints= Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) route = Step('cadence-innovus-route', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) init_fill = Step('mentor-calibre-fill', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Die if unconnected bumps (why was this deleted?) init.extend_postconditions( ["assert 'STILL UNCONNECTED: bump' not in File( 'mflowgen-run.log' )"]) # Send in the clones # 'init' step now gets its own design-rule check init_drc = drc.clone() init_drc.set_name('init-drc') # "init" now builds a gds file for its own drc check "init_drc"; # so need a gdsmerge step between the two init_gdsmerge = gdsmerge.clone() init_gdsmerge.set_name('init-gdsmerge') #----------------------------------------------------------------------- # Add extra input edges to innovus steps that need custom tweaks #----------------------------------------------------------------------- # "init" (cadence-innovus-init) inputs are "init_fullchip" outputs init.extend_inputs(init_fullchip.all_outputs()) # Also: 'init' now produces a gds file # for intermediate drc check 'init-drc' # by way of intermediate gdsmerge step "init-gdsmerge" init.extend_outputs(["design.gds.gz"]) # "power" inputs are "custom_power" outputs power.extend_inputs(custom_power.all_outputs()) signoff.extend_inputs(netlist_fixing.all_outputs()) # Your comment here. # FIXME what about gds??? # iflow (flowsetup) setup.tcl includes all files inputs/*.lef maybe # iflow.extend_inputs( [ "icovl-cells.lef" , "dtcd-cells.lef" ] ) # genlibdb.extend_inputs( genlibdb_constraints.all_outputs() ) # Ouch. iflow and everyone that connects to iflow must also include # the icovl/dtcd lefs I guess? pre_flowsetup_followers = [ # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff iflow, init # can we get away with this? ] for step in pre_flowsetup_followers: step.extend_inputs( ["icovl-cells.lef", "dtcd-cells.lef", "bumpcells.lef"]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) # pre_flowsetup => iflow g.add_step(pre_flowsetup) g.add_step(iflow) g.add_step(init_fullchip) g.add_step(init) # init => init_gdsmerge => init_drc g.add_step(init_gdsmerge) g.add_step(init_fill) g.add_step(init_drc) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(route) g.add_step(netlist_fixing) g.add_step(signoff) g.add_step(pt_signoff) # g.add_step( genlibdb_constraints ) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(debugcalibre) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, pre_flowsetup) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, init_gdsmerge) g.connect_by_name(adk, init_fill) g.connect_by_name(adk, init_drc) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, route) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) # sr02.2020 b/c now init_fullchip needs io_file from rtl g.connect_by_name(rtl, init_fullchip) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) # g.connect_by_name( pre_flowsetup, iflow ) # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff for step in pre_flowsetup_followers: g.connect_by_name(pre_flowsetup, step) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, route) g.connect_by_name(iflow, signoff) # for step in iflow_followers: # g.connect_by_name( iflow, step) g.connect_by_name(init_fullchip, init) g.connect_by_name(custom_power, power) # init => init_gdsmerge => init_drc g.connect_by_name(init, init_gdsmerge) g.connect_by_name(init_gdsmerge, init_drc) g.connect(init_gdsmerge.o('design_merged.gds'), init_fill.i('design.gds')) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, route) g.connect_by_name(route, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) # g.connect_by_name( genlibdb_constraints, genlibdb ) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Netlist fixing should be run during signoff g.connect_by_name(netlist_fixing, signoff) # yes? no? # g.connect_by_name( init_drc, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Default order can be found in e.g. # mflowgen/steps/cadence-innovus-init/configure.yml # - main.tcl # - quality-of-life.tcl # - floorplan.tcl # - pin-assignments.tcl # - make-path-groups.tcl # - reporting.tcl # I copied this from someone else, maybe glb_top or something # Looks like this order deletes pin assignments and adds endcaps/welltaps # then maybe get clean(er) post-floorplan drc # # ?? moved stream-out to *before* alignment-cells so to get pre-icovl gds # FIXME does this mean we're not checking bump-route DRC? # Note "route-phy-bumps" explicitly sources a file "analog-bumps/build-phy-nets.tcl" # 5/2020 moved stream-out to *after* bump routing init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'attach-results-to-outputs.tcl', 'alignment-cells.tcl', 'analog-bumps/route-phy-bumps.tcl', 'analog-bumps/bump-connect.tcl', 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'innovus-foundation-flow/custom-scripts/stream-out.tcl', ] }) order = power.get_param('order') order.append('add-endcaps-welltaps.tcl') power.update_params({'order': order}) # Signoff Order order = signoff.get_param('order') index = order.index( 'generate-results.tcl') # Fix netlist before streaming out netlist order.insert(index, 'netlist-fixing.tcl') signoff.update_params({'order': order}) # Not sure what this is or why it was commented out... # # Adding new input for genlibdb node to run # genlibdb.update_params( # {'order': "\"read_design.tcl genlibdb-constraints.tcl extract_model.tcl\""} # ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multivt' parameters = { 'construct_path': __file__, 'design_name': 'Interconnect', 'clock_period': 1.1, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # RTL Generation 'array_width': 32, 'array_height': 16, 'interconnect_only': False, # Power Domains 'PWR_AWARE': True, # Useful Skew (CTS) 'useful_skew': False, # hold target slack 'hold_target_slack': 0.015, # Pipeline stage insertion 'pipeline_config_interval': 8, 'pipeline_stage_height': 30, # Testing 'testbench_name': 'Interconnect_tb', # I am defaulting to True because nothing is worse than finishing # a sim and needing the wave but not having it... 'waves': True, } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') Tile_MemCore = Step(this_dir + '/Tile_MemCore') Tile_PE = Step(this_dir + '/Tile_PE') constraints = Step(this_dir + '/constraints') dc_postcompile = Step(this_dir + '/custom-dc-postcompile') custom_init = Step(this_dir + '/custom-init') custom_power = Step(this_dir + '/../common/custom-power-hierarchical') custom_cts = Step(this_dir + '/custom-cts-overrides') custom_lvs = Step(this_dir + '/custom-lvs-rules') gls_args = Step(this_dir + '/gls_args') testbench = Step(this_dir + '/testbench') lib2db = Step(this_dir + '/../common/synopsys-dc-lib2db') # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) #dc = Step( 'synopsys-dc-synthesis', default=True ) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) #genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) genlib = Step('cadence-genus-genlib', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) vcs_sim = Step('synopsys-vcs-sim', default=True) # Add cgra tile macro inputs to downstream nodes #dc.extend_inputs( ['Tile_PE.db'] ) synth.extend_inputs(['Tile_PE_tt.lib']) #dc.extend_inputs( ['Tile_MemCore.db'] ) synth.extend_inputs(['Tile_MemCore_tt.lib']) pt_signoff.extend_inputs(['Tile_PE_tt.db']) pt_signoff.extend_inputs(['Tile_MemCore_tt.db']) #genlibdb.extend_inputs( ['Tile_PE.db'] ) genlib.extend_inputs(['Tile_PE_tt.lib']) #genlibdb.extend_inputs( ['Tile_MemCore.db'] ) genlib.extend_inputs(['Tile_MemCore_tt.lib']) e2e_apps = [ "tests/conv_3_3", "apps/cascade", "apps/harris_auto", "apps/resnet_i1_o1_mem", "apps/resnet_i1_o1_pond" ] # Only use these steps with power domains off and no flattening... use_e2e = True e2e_tb_nodes = {} e2e_sim_nodes = {} e2e_power_nodes = {} if use_e2e: for app in e2e_apps: e2e_testbench = Step(this_dir + '/e2e_testbench') e2e_xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim') e2e_ptpx_gl = Step(this_dir + '/../common/synopsys-ptpx-gl') # Simple rename app_name = app.split("/")[1] e2e_testbench.set_name(f"e2e_testbench_{app_name}") e2e_xcelium_sim.set_name(f"e2e_xcelium_sim_{app_name}") e2e_ptpx_gl.set_name(f"e2e_ptpx_gl_{app_name}") e2e_tb_nodes[app] = e2e_testbench e2e_sim_nodes[app] = e2e_xcelium_sim e2e_power_nodes[app] = e2e_ptpx_gl # override app_to_run param of the testbench gen e2e_testbench.set_param("app_to_run", app) # Send all the relevant post-pnr files to sim e2e_xcelium_sim.extend_inputs(Tile_MemCore.all_outputs()) e2e_xcelium_sim.extend_inputs(Tile_PE.all_outputs()) e2e_xcelium_sim.extend_inputs(['design.vcs.pg.v']) e2e_xcelium_sim.extend_inputs(['input.raw']) # Configure the ptpx step a little differently... e2e_ptpx_gl.set_param("strip_path", "Interconnect_tb/dut") e2e_ptpx_gl.extend_inputs(e2e_testbench.all_outputs()) e2e_ptpx_gl.extend_inputs(Tile_MemCore.all_outputs()) e2e_ptpx_gl.extend_inputs(Tile_PE.all_outputs()) # These steps need timing info for cgra tiles tile_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff ] for step in tile_steps: step.extend_inputs(['Tile_PE_tt.lib', 'Tile_PE.lef']) step.extend_inputs(['Tile_MemCore_tt.lib', 'Tile_MemCore.lef']) # Need the netlist and SDF files for gate-level sim vcs_sim.extend_inputs(['Tile_PE.vcs.v', 'Tile_PE.sdf']) vcs_sim.extend_inputs(['Tile_MemCore.vcs.v', 'Tile_MemCore.sdf']) # Need the cgra tile gds's to merge into the final layout signoff.extend_inputs(['Tile_PE.gds']) signoff.extend_inputs(['Tile_MemCore.gds']) # Need LVS verilog files for both tile types to do LVS lvs.extend_inputs(['Tile_PE.lvs.v']) lvs.extend_inputs(['Tile_MemCore.lvs.v']) # Need sram spice file for LVS lvs.extend_inputs(['sram.spi']) # Extra dc inputs #dc.extend_inputs( dc_postcompile.all_outputs() ) #synth.extend_inputs( dc_postcompile.all_outputs() ) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) cts.extend_inputs(custom_cts.all_outputs()) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(Tile_MemCore) g.add_step(Tile_PE) g.add_step(constraints) g.add_step(dc_postcompile) g.add_step(synth) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(custom_cts) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlib) g.add_step(lib2db) g.add_step(drc) g.add_step(custom_lvs) g.add_step(lvs) g.add_step(debugcalibre) g.add_step(gls_args) g.add_step(testbench) g.add_step(vcs_sim) if use_e2e: for app in e2e_apps: g.add_step(e2e_tb_nodes[app]) g.add_step(e2e_sim_nodes[app]) g.add_step(e2e_power_nodes[app]) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) if use_e2e: for app in e2e_apps: g.connect_by_name(adk, e2e_sim_nodes[app]) g.connect_by_name(Tile_MemCore, e2e_sim_nodes[app]) g.connect_by_name(Tile_PE, e2e_sim_nodes[app]) g.connect_by_name(e2e_tb_nodes[app], e2e_sim_nodes[app]) g.connect_by_name(signoff, e2e_sim_nodes[app]) g.connect_by_name(adk, e2e_power_nodes[app]) g.connect_by_name(Tile_MemCore, e2e_power_nodes[app]) g.connect_by_name(Tile_PE, e2e_power_nodes[app]) g.connect_by_name(signoff, e2e_power_nodes[app]) g.connect_by_name(e2e_tb_nodes[app], e2e_power_nodes[app]) g.connect_by_name(e2e_sim_nodes[app], e2e_power_nodes[app]) # In our CGRA, the tile pattern is: # PE PE PE Mem PE PE PE Mem ... # Thus, if there are < 4 columns, the the array won't contain any # memory tiles. If this is the case, we don't need to run the # memory tile flow. if parameters['array_width'] > 3: # inputs to Tile_MemCore g.connect_by_name(rtl, Tile_MemCore) # outputs from Tile_MemCore #g.connect_by_name( Tile_MemCore, dc ) g.connect_by_name(Tile_MemCore, synth) g.connect_by_name(Tile_MemCore, iflow) g.connect_by_name(Tile_MemCore, init) g.connect_by_name(Tile_MemCore, power) g.connect_by_name(Tile_MemCore, place) g.connect_by_name(Tile_MemCore, cts) g.connect_by_name(Tile_MemCore, postcts_hold) g.connect_by_name(Tile_MemCore, route) g.connect_by_name(Tile_MemCore, postroute) g.connect_by_name(Tile_MemCore, postroute_hold) g.connect_by_name(Tile_MemCore, signoff) g.connect_by_name(Tile_MemCore, pt_signoff) #g.connect_by_name( Tile_MemCore, genlibdb ) g.connect_by_name(Tile_MemCore, genlib) g.connect_by_name(Tile_MemCore, drc) g.connect_by_name(Tile_MemCore, lvs) # These rules LVS BOX the SRAM macro, so they should # only be used if memory tile is present g.connect_by_name(custom_lvs, lvs) g.connect_by_name(Tile_MemCore, vcs_sim) # inputs to Tile_PE g.connect_by_name(rtl, Tile_PE) # outputs from Tile_PE #g.connect_by_name( Tile_PE, dc ) g.connect_by_name(Tile_PE, synth) g.connect_by_name(Tile_PE, iflow) g.connect_by_name(Tile_PE, init) g.connect_by_name(Tile_PE, power) g.connect_by_name(Tile_PE, place) g.connect_by_name(Tile_PE, cts) g.connect_by_name(Tile_PE, postcts_hold) g.connect_by_name(Tile_PE, route) g.connect_by_name(Tile_PE, postroute) g.connect_by_name(Tile_PE, postroute_hold) g.connect_by_name(Tile_PE, signoff) g.connect_by_name(Tile_PE, pt_signoff) #g.connect_by_name( Tile_PE, genlibdb ) g.connect_by_name(Tile_PE, genlib) g.connect_by_name(Tile_PE, drc) g.connect_by_name(Tile_PE, lvs) #g.connect_by_name( rtl, dc ) #g.connect_by_name( constraints, dc ) #g.connect_by_name( dc_postcompile, dc ) #g.connect_by_name( dc, iflow ) #g.connect_by_name( dc, init ) #g.connect_by_name( dc, power ) #g.connect_by_name( dc, place ) #g.connect_by_name( dc, cts ) g.connect_by_name(rtl, synth) g.connect_by_name(rtl, synth) g.connect_by_name(constraints, synth) #g.connect_by_name( dc_postcompile, synth ) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_cts, cts) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) #g.connect_by_name( adk, genlibdb ) g.connect_by_name(adk, genlib) #g.connect_by_name( signoff, genlibdb ) g.connect_by_name(signoff, genlib) g.connect_by_name(genlib, lib2db) g.connect_by_name(adk, debugcalibre) #g.connect_by_name( dc, debugcalibre ) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) g.connect_by_name(adk, vcs_sim) g.connect_by_name(testbench, vcs_sim) g.connect_by_name(gls_args, vcs_sim) g.connect_by_name(signoff, vcs_sim) g.connect_by_name(Tile_PE, vcs_sim) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Init needs pipeline params for floorplanning init.update_params( {'pipeline_config_interval': parameters['pipeline_config_interval']}, True) init.update_params( {'pipeline_stage_height': parameters['pipeline_stage_height']}, True) # CTS uses height/width param to do CTS endpoint overrides properly cts.update_params({'array_width': parameters['array_width']}, True) cts.update_params({'array_height': parameters['array_height']}, True) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. #order = synth.get_param('order') #compile_idx = order.index( 'compile.tcl' ) #order.insert ( compile_idx + 1, 'custom-dc-postcompile.tcl' ) #dc.update_params( { 'order': order } ) #synth.update_params( { 'order': order } ) # genlibdb -- Remove 'report-interface-timing.tcl' beacuse it takes # very long and is not necessary #order = genlibdb.get_param('order') #order.remove( 'write-interface-timing.tcl' ) #genlibdb.update_params( { 'order': order } ) # init -- Add 'dont-touch.tcl' before reporting order = init.get_param('order') # get the default script run order reporting_idx = order.index('reporting.tcl') # find reporting.tcl # Add dont-touch before reporting order.insert(reporting_idx, 'dont-touch.tcl') init.update_params({'order': order}) # We are overriding certain pin types for CTS, so we need to # add the script that does that to the CTS order order = cts.get_param('order') main_idx = order.index('main.tcl') order.insert(main_idx, 'cts-overrides.tcl') cts.update_params({'order': order}) # Remove #dc_postconditions = dc.get_postconditions() #for postcon in dc_postconditions: # if 'percent_clock_gated' in postcon: # dc_postconditions.remove(postcon) #dc.set_postconditions( dc_postconditions ) synth_postconditions = synth.get_postconditions() for postcon in synth_postconditions: if 'percent_clock_gated' in postcon: synth_postconditions.remove(postcon) synth.set_postconditions(synth_postconditions) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'freepdk-45nm' adk_view = 'view-standard' parameters = { 'construct_path' : __file__, 'design_name' : 'GcdUnit', 'clock_period' : 2.0, 'adk' : adk_name, 'adk_view' : adk_view, 'topographical' : True, 'saif_instance' : 'GcdUnitTb/GcdUnit_inst' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/rtl' ) testbench = Step( this_dir + '/testbench') # Default steps info = Step( 'info', default=True ) constraints = Step( 'constraints', default=True ) dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) postroute_hold = Step( 'cadence-innovus-postroute_hold', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) vcs_sim = Step( 'synopsys-vcs-sim', default=True ) power_est = Step( 'synopsys-pt-power', default=True ) formal_verif = Step( 'synopsys-formality-verification', default=True ) #----------------------------------------------------------------------- # Modify Nodes #----------------------------------------------------------------------- vcs_sim.extend_inputs(['test_vectors.txt']) vcs_sim.update_params(testbench.params()) verif_post_synth = formal_verif.clone() verif_post_synth.set_name('verif_post_synth') verif_post_layout = formal_verif.clone() verif_post_layout.set_name('verif_post_layout') #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( init ) g.add_step( power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( postroute_hold ) g.add_step( signoff ) g.add_step( genlibdb ) g.add_step( gdsmerge ) g.add_step( drc ) g.add_step( lvs ) g.add_step( debugcalibre ) g.add_step( testbench ) g.add_step( vcs_sim ) g.add_step( power_est ) g.add_step( verif_post_synth ) g.add_step( verif_post_layout ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, postroute_hold ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, gdsmerge ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( rtl, dc ) g.connect_by_name( constraints, dc ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( dc, power ) g.connect_by_name( dc, place ) g.connect_by_name( dc, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, postroute_hold ) g.connect_by_name( iflow, signoff ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, postroute_hold ) g.connect_by_name( postroute_hold, signoff ) g.connect_by_name( signoff, genlibdb ) g.connect_by_name( adk, genlibdb ) g.connect_by_name( signoff, gdsmerge ) g.connect_by_name( signoff, drc ) g.connect_by_name( gdsmerge, drc ) g.connect_by_name( signoff, lvs ) g.connect_by_name( gdsmerge, lvs ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( dc, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) g.connect_by_name( adk, vcs_sim ) g.connect_by_name( signoff, vcs_sim ) g.connect_by_name( testbench, vcs_sim ) g.connect_by_name( adk, power_est ) g.connect_by_name( signoff, power_est ) g.connect_by_name( vcs_sim, power_est ) g.connect_by_name( adk, verif_post_synth ) g.connect_by_name( dc, verif_post_synth ) g.connect( rtl.o('design.v'), verif_post_synth.i('design.ref.v') ) g.connect( dc.o('design.v'), verif_post_synth.i('design.impl.v') ) g.connect_by_name( adk, verif_post_layout ) g.connect_by_name( dc, verif_post_layout ) g.connect( dc.o('design.v'), verif_post_layout.i('design.ref.v') ) g.connect( signoff.o('design.lvs.v'), verif_post_layout.i('design.impl.v') ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multicorner-multivt' pwr_aware = True flatten = 3 os_flatten = os.environ.get('FLATTEN') if os_flatten: flatten = os_flatten # RTL power estimation rtl_power = False if os.environ.get('RTL_POWER') == 'True': pwr_aware = False rtl_power = True # DC power estimation synth_power = False if os.environ.get('SYNTH_POWER') == 'True': synth_power = True pwr_aware = False parameters = { 'construct_path': __file__, 'design_name': 'Tile_PE', 'clock_period': 4, # Change to 250 MHz to match Mem. 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': flatten, 'topographical': True, # RTL Generation 'interconnect_only': True, # Power Domains 'PWR_AWARE': pwr_aware, 'core_density_target': 0.63, 'saif_instance': 'TilePETb/Tile_PE_inst', 'testbench_name': 'TilePETb', 'strip_path': 'TilePETb/Tile_PE_inst' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_genus_scripts = Step(this_dir + '/custom-genus-scripts') custom_flowgen_setup = Step(this_dir + '/custom-flowgen-setup') custom_power = Step(this_dir + '/../common/custom-power-leaf') genlibdb_constraints = Step(this_dir + '/../common/custom-genlibdb-constraints') custom_timing_assert = Step(this_dir + '/../common/custom-timing-assert') custom_dc_scripts = Step(this_dir + '/custom-dc-scripts') testbench = Step(this_dir + '/testbench') xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim') if rtl_power: rtl_sim = xcelium_sim.clone() rtl_sim.set_name('rtl-sim') pt_power_rtl = Step(this_dir + '/../common/synopsys-ptpx-rtl') rtl_sim.extend_inputs(testbench.all_outputs()) gl_sim = xcelium_sim.clone() gl_sim.set_name('gl-sim') gl_sim.extend_inputs(testbench.all_outputs()) pt_power_gl = Step(this_dir + '/../common/synopsys-ptpx-gl') parse_power_gl = Step(this_dir + '/parse-power-gl') if synth_power: synth_sim = xcelium_sim.clone() synth_sim.set_name('synth-sim') synth_sim.extend_inputs(testbench.all_outputs()) synth_sim.extend_inputs(['design.v']) pt_power_synth = Step(this_dir + '/../common/synopsys-ptpx-synth') # Power aware setup power_domains = None pwr_aware_gls = None if pwr_aware: power_domains = Step(this_dir + '/../common/power-domains') pwr_aware_gls = Step(this_dir + '/../common/pwr-aware-gls') # Default steps info = Step('info', default=True) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) if synth_power: synth.extend_outputs(['design.spef.gz']) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('cadence-genus-genlib', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add custom timing scripts custom_timing_steps = [synth, postcts_hold, signoff] # connects to these for c_step in custom_timing_steps: c_step.extend_inputs(custom_timing_assert.all_outputs()) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) genlibdb.extend_inputs(genlibdb_constraints.all_outputs()) synth.extend_inputs(custom_genus_scripts.all_outputs()) iflow.extend_inputs(custom_flowgen_setup.all_outputs()) # Extra input to DC for constraints synth.extend_inputs([ "common.tcl", "reporting.tcl", "generate-results.tcl", "scenarios.tcl", "report_alu.py", "parse_alu.py" ]) # Extra outputs from DC synth.extend_outputs(["sdc"]) iflow.extend_inputs(["scenarios.tcl", "sdc"]) init.extend_inputs(["sdc"]) power.extend_inputs(["sdc"]) place.extend_inputs(["sdc"]) cts.extend_inputs(["sdc"]) order = synth.get_param('order') order.append('copy_sdc.tcl') synth.set_param('order', order) # Power aware setup if pwr_aware: synth.extend_inputs([ 'designer-interface.tcl', 'upf_Tile_PE.tcl', 'pe-constraints.tcl', 'pe-constraints-2.tcl', 'dc-dont-use-constraints.tcl' ]) init.extend_inputs([ 'upf_Tile_PE.tcl', 'pe-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-pe-floorplan.tcl', 'pe-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'pe-power-switches-setup.tcl', 'add-power-switches.tcl', 'check-clamp-logic-structure.tcl' ]) place.extend_inputs([ 'place-dont-use-constraints.tcl', 'check-clamp-logic-structure.tcl' ]) power.extend_inputs(['pd-globalnetconnect.tcl']) cts.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) postcts_hold.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) route.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) postroute.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) signoff.extend_inputs([ 'conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl', 'check-clamp-logic-structure.tcl' ]) pwr_aware_gls.extend_inputs(['design.vcs.pg.v']) gl_sim.extend_inputs(["design.vcs.pg.v"]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(testbench) g.add_step(constraints) g.add_step(custom_dc_scripts) g.add_step(synth) g.add_step(custom_timing_assert) g.add_step(custom_genus_scripts) g.add_step(iflow) g.add_step(custom_flowgen_setup) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb_constraints) g.add_step(genlibdb) g.add_step(drc) g.add_step(lvs) g.add_step(debugcalibre) if rtl_power: g.add_step(rtl_sim) g.add_step(pt_power_rtl) g.add_step(gl_sim) g.add_step(pt_power_gl) g.add_step(parse_power_gl) if synth_power: g.add_step(synth_sim) g.add_step(pt_power_synth) # Power aware step if pwr_aware: g.add_step(power_domains) g.add_step(pwr_aware_gls) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges # Connect by name g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(adk, pt_power_gl) if rtl_power: rtl_sim.extend_inputs(['design.v']) g.connect_by_name(adk, rtl_sim) g.connect_by_name(adk, pt_power_rtl) # To generate namemap g.connect_by_name(rtl_sim, dc) # run.saif g.connect_by_name(rtl, rtl_sim) # design.v g.connect_by_name(testbench, rtl_sim) # testbench.sv g.connect_by_name(dc, pt_power_rtl) # design.namemap g.connect_by_name( signoff, pt_power_rtl) # design.vcs.v, design.spef.gz, design.pt.sdc g.connect_by_name(rtl_sim, pt_power_rtl) # run.saif g.connect_by_name(rtl, synth) g.connect_by_name(constraints, synth) g.connect_by_name(custom_genus_scripts, synth) g.connect_by_name(constraints, iflow) g.connect_by_name(custom_dc_scripts, iflow) for c_step in custom_timing_steps: g.connect_by_name(custom_timing_assert, c_step) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(synth, custom_flowgen_setup) g.connect_by_name(custom_flowgen_setup, iflow) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(genlibdb_constraints, genlibdb) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(signoff, pt_power_gl) g.connect_by_name(gl_sim, pt_power_gl) # run.saif g.connect_by_name(adk, gl_sim) g.connect_by_name(signoff, gl_sim) # design.vcs.v, design.spef.gz, design.pt.sdc g.connect_by_name(pt_signoff, gl_sim) # design.sdf g.connect_by_name(testbench, gl_sim) # testbench.sv g.connect_by_name(pt_power_gl, parse_power_gl) # power.hier if synth_power: g.connect_by_name(adk, pt_power_synth) g.connect_by_name(synth, pt_power_synth) g.connect_by_name(synth_sim, pt_power_synth) g.connect_by_name(adk, synth_sim) g.connect_by_name(synth, synth_sim) g.connect_by_name(testbench, synth_sim) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Pwr aware steps: if pwr_aware: g.connect_by_name(power_domains, synth) g.connect_by_name(power_domains, init) g.connect_by_name(power_domains, power) g.connect_by_name(power_domains, place) g.connect_by_name(power_domains, cts) g.connect_by_name(power_domains, postcts_hold) g.connect_by_name(power_domains, route) g.connect_by_name(power_domains, postroute) g.connect_by_name(power_domains, signoff) g.connect_by_name(adk, pwr_aware_gls) g.connect_by_name(signoff, pwr_aware_gls) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Add custom timing scripts for c_step in custom_timing_steps: order = c_step.get_param('order') order.append('report-special-timing.tcl') c_step.set_param('order', order) c_step.extend_postconditions([{'pytest': 'inputs/test_timing.py'}]) # Update PWR_AWARE variable synth.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) if pwr_aware: init.update_params({'flatten_effort': parameters['flatten_effort']}, True) pwr_aware_gls.update_params({'design_name': parameters['design_name']}, True) init.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) place.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) cts.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postcts_hold.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) route.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postroute.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) signoff.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. init.update_params( {'core_density_target': parameters['core_density_target']}, True) # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' # and 'additional-path-groups' after 'make_path_groups' order = init.get_param('order') # get the default script run order path_group_idx = order.index('make-path-groups.tcl') order.insert(path_group_idx + 1, 'additional-path-groups.tcl') pin_idx = order.index('pin-assignments.tcl') # find pin-assignments.tcl order.insert(pin_idx + 1, 'edge-blockages.tcl') # add here init.update_params({'order': order}) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index('read_design.tcl') # find read_design.tcl order.insert(read_idx + 1, 'genlibdb-constraints.tcl') # add here genlibdb.update_params({'order': order}) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index('floorplan.tcl') # find floorplan.tcl order.insert(read_idx + 1, 'pe-load-upf.tcl') # add here order.insert(read_idx + 2, 'pd-pe-floorplan.tcl') # add here order.insert(read_idx + 3, 'pe-add-endcaps-welltaps-setup.tcl') # add here order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl') # add here order.insert(read_idx + 5, 'pe-power-switches-setup.tcl') # add here order.insert(read_idx + 6, 'add-power-switches.tcl') # add here order.remove('add-endcaps-welltaps.tcl') order.append('check-clamp-logic-structure.tcl') init.update_params({'order': order}) # power node order = power.get_param('order') order.insert(0, 'pd-globalnetconnect.tcl') # add here order.remove('globalnetconnect.tcl') power.update_params({'order': order}) # place node order = place.get_param('order') read_idx = order.index('main.tcl') # find main.tcl order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') order.append('check-clamp-logic-structure.tcl') place.update_params({'order': order}) # cts node order = cts.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') cts.update_params({'order': order}) # postcts_hold node order = postcts_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postcts_hold.update_params({'order': order}) # route node order = route.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') route.update_params({'order': order}) # postroute node order = postroute.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postroute.update_params({'order': order}) # signoff node order = signoff.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here read_idx = order.index( 'generate-results.tcl') # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') order.append('check-clamp-logic-structure.tcl') signoff.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path' : __file__, 'design_name' : 'glb_tile', 'clock_period' : 1.0, 'adk' : adk_name, 'adk_view' : adk_view, # Synthesis 'flatten_effort' : 3, 'topographical' : True, # Floorplan 'bank_height' : 8, # SRAM macros 'num_words' : 2048, 'word_size' : 64, 'mux_size' : 8, 'corner' : "tt0p8v25c", 'partial_write' : True, # Power Domains 'PWR_AWARE' : False, # hold target slack 'hold_target_slack' : 0.053 } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/rtl' ) constraints = Step( this_dir + '/constraints' ) gen_sram = Step( this_dir + '/../common/gen_sram_macro' ) custom_init = Step( this_dir + '/custom-init' ) custom_power = Step( this_dir + '/../common/custom-power-leaf' ) custom_lvs = Step( this_dir + '/custom-lvs-rules' ) # Default steps info = Step( 'info', default=True ) # constraints = Step( 'constraints', default=True ) synth = Step( 'cadence-genus-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) postroute_hold = Step( 'cadence-innovus-postroute_hold',default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) genlib = Step( 'cadence-genus-genlib', default=True ) if which("calibre") is not None: drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) else: drc = Step( 'cadence-pegasus-drc', default=True ) lvs = Step( 'cadence-pegasus-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Add (dummy) parameters to the default innovus init step init.update_params( { 'core_width' : 0, 'core_height' : 0 }, allow_new=True ) # Add sram macro inputs to downstream nodes pt_signoff.extend_inputs( ['sram_tt.db'] ) # These steps need timing and lef info for srams sram_steps = \ [synth, iflow, init, power, place, cts, postcts_hold, \ route, postroute, postroute_hold, signoff, genlib] for step in sram_steps: step.extend_inputs( ['sram_tt.lib', 'sram.lef'] ) # Need the sram gds to merge into the final layout signoff.extend_inputs( ['sram.gds'] ) # Need SRAM spice file for LVS lvs.extend_inputs( ['sram.spi'] ) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs( custom_init.all_outputs() ) power.extend_inputs( custom_power.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( gen_sram ) g.add_step( constraints ) g.add_step( synth ) g.add_step( iflow ) g.add_step( init ) g.add_step( custom_init ) g.add_step( power ) g.add_step( custom_power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( postroute_hold ) g.add_step( signoff ) g.add_step( pt_signoff ) g.add_step( genlib ) g.add_step( drc ) g.add_step( lvs ) g.add_step( custom_lvs ) g.add_step( debugcalibre ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, gen_sram ) g.connect_by_name( adk, synth ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, postroute_hold ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( gen_sram, synth ) g.connect_by_name( gen_sram, iflow ) g.connect_by_name( gen_sram, init ) g.connect_by_name( gen_sram, power ) g.connect_by_name( gen_sram, place ) g.connect_by_name( gen_sram, cts ) g.connect_by_name( gen_sram, postcts_hold ) g.connect_by_name( gen_sram, route ) g.connect_by_name( gen_sram, postroute ) g.connect_by_name( gen_sram, postroute_hold ) g.connect_by_name( gen_sram, signoff ) g.connect_by_name( gen_sram, genlib ) g.connect_by_name( gen_sram, pt_signoff ) g.connect_by_name( gen_sram, drc ) g.connect_by_name( gen_sram, lvs ) g.connect_by_name( rtl, synth ) g.connect_by_name( constraints, synth ) g.connect_by_name( synth, iflow ) g.connect_by_name( synth, init ) g.connect_by_name( synth, power ) g.connect_by_name( synth, place ) g.connect_by_name( synth, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute_hold ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, signoff ) g.connect_by_name( custom_init, init ) g.connect_by_name( custom_power, power ) g.connect_by_name( custom_lvs, lvs ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, postroute_hold ) g.connect_by_name( postroute_hold, signoff ) g.connect_by_name( signoff, drc ) g.connect_by_name( signoff, lvs ) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name( signoff, genlib ) g.connect_by_name( adk, genlib ) g.connect_by_name( adk, pt_signoff ) g.connect_by_name( signoff, pt_signoff ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( synth, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) # Add bank height param to init init.update_params( { 'bank_height': parameters['bank_height'] }, True ) # Change nthreads synth.update_params( { 'nthreads': 4 } ) iflow.update_params( { 'nthreads': 8 } ) # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' order = init.get_param('order') # get the default script run order pin_idx = order.index( 'pin-assignments.tcl' ) # find pin-assignments.tcl order.insert( pin_idx + 1, 'edge-blockages.tcl' ) # add here init.update_params( { 'order': order } ) # Disable pwr aware flow init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) # Increase hold slack on postroute_hold step postroute_hold.update_params( { 'hold_target_slack': parameters['hold_target_slack'] }, allow_new=True ) # useful_skew cts.update_params( { 'useful_skew': False }, allow_new=True ) # cts.update_params( { 'useful_skew_ccopt_effort': 'extreme' }, allow_new=True ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' pwr_aware = True parameters = { 'construct_path': __file__, 'design_name': 'Tile_MemCore', 'clock_period': 1.1, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # SRAM macros 'num_words': 512, 'word_size': 32, 'mux_size': 4, 'corner': "tt0p8v25c", 'partial_write': False, # Utilization target 'core_density_target': 0.70, # RTL Generation 'interconnect_only': True, # Power Domains 'PWR_AWARE': pwr_aware } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') genlibdb_constraints = Step(this_dir + '/../common/custom-genlibdb-constraints') constraints = Step(this_dir + '/constraints') gen_sram = Step(this_dir + '/../common/gen_sram_macro') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-leaf') # Power aware setup if pwr_aware: power_domains = Step(this_dir + '/../common/power-domains') # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Extra DC input dc.extend_inputs(["common.tcl"]) # Add sram macro inputs to downstream nodes dc.extend_inputs(['sram_tt.db']) pt_signoff.extend_inputs(['sram_tt.db']) genlibdb.extend_inputs(['sram_tt.db']) # These steps need timing and lef info for srams sram_steps = \ [iflow, init, power, place, cts, postcts_hold, route, postroute, postroute_hold, signoff] for step in sram_steps: step.extend_inputs(['sram_tt.lib', 'sram.lef']) # Need the sram gds to merge into the final layout gdsmerge.extend_inputs(['sram.gds']) # Need SRAM spice file for LVS lvs.extend_inputs(['sram.spi']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) # Add extra input edges to genlibdb for loop-breaking constraints genlibdb.extend_inputs(genlibdb_constraints.all_outputs()) # Power aware setup if pwr_aware: dc.extend_inputs([ 'designer-interface.tcl', 'upf_Tile_MemCore.tcl', 'mem-constraints.tcl', 'mem-constraints-2.tcl', 'dc-dont-use-constraints.tcl' ]) init.extend_inputs([ 'upf_Tile_MemCore.tcl', 'mem-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-mem-floorplan.tcl', 'mem-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'mem-power-switches-setup.tcl', 'add-power-switches.tcl' ]) place.extend_inputs(['place-dont-use-constraints.tcl']) power.extend_inputs(['pd-globalnetconnect.tcl']) cts.extend_inputs(['conn-aon-cells-vdd.tcl']) postcts_hold.extend_inputs(['conn-aon-cells-vdd.tcl']) route.extend_inputs(['conn-aon-cells-vdd.tcl']) postroute.extend_inputs(['conn-aon-cells-vdd.tcl']) postroute_hold.extend_inputs(['conn-aon-cells-vdd.tcl']) signoff.extend_inputs( ['conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl']) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(gen_sram) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb_constraints) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) # Power aware step if pwr_aware: g.add_step(power_domains) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(gen_sram, dc) g.connect_by_name(gen_sram, iflow) g.connect_by_name(gen_sram, init) g.connect_by_name(gen_sram, power) g.connect_by_name(gen_sram, place) g.connect_by_name(gen_sram, cts) g.connect_by_name(gen_sram, postcts_hold) g.connect_by_name(gen_sram, route) g.connect_by_name(gen_sram, postroute) g.connect_by_name(gen_sram, postroute_hold) g.connect_by_name(gen_sram, signoff) g.connect_by_name(gen_sram, genlibdb) g.connect_by_name(gen_sram, pt_signoff) g.connect_by_name(gen_sram, gdsmerge) g.connect_by_name(gen_sram, drc) g.connect_by_name(gen_sram, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(genlibdb_constraints, genlibdb) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Pwr aware steps: if pwr_aware: g.connect_by_name(power_domains, dc) g.connect_by_name(power_domains, init) g.connect_by_name(power_domains, power) g.connect_by_name(power_domains, place) g.connect_by_name(power_domains, cts) g.connect_by_name(power_domains, postcts_hold) g.connect_by_name(power_domains, route) g.connect_by_name(power_domains, postroute) g.connect_by_name(power_domains, postroute_hold) g.connect_by_name(power_domains, signoff) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Update PWR_AWARE variable dc.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) # Core density target param init.update_params( {'core_density_target': parameters['core_density_target']}, True) # Disable pwr aware flow #init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) #power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' order = init.get_param('order') # get the default script run order pin_idx = order.index('pin-assignments.tcl') # find pin-assignments.tcl order.insert(pin_idx + 1, 'edge-blockages.tcl') # add here init.update_params({'order': order}) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index('read_design.tcl') # find read_design.tcl order.insert(read_idx + 1, 'genlibdb-constraints.tcl') # add here genlibdb.update_params({'order': order}) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index('floorplan.tcl') # find floorplan.tcl order.insert(read_idx + 1, 'mem-load-upf.tcl') # add here order.insert(read_idx + 2, 'pd-mem-floorplan.tcl') # add here order.insert(read_idx + 3, 'mem-add-endcaps-welltaps-setup.tcl') # add here order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl') # add here order.insert(read_idx + 5, 'mem-power-switches-setup.tcl') # add here order.insert(read_idx + 6, 'add-power-switches.tcl') # add here order.remove('add-endcaps-welltaps.tcl') init.update_params({'order': order}) # power node order = power.get_param('order') order.insert(0, 'pd-globalnetconnect.tcl') # add here order.remove('globalnetconnect.tcl') power.update_params({'order': order}) # place node order = place.get_param('order') read_idx = order.index('main.tcl') # find main.tcl order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') place.update_params({'order': order}) # cts node order = cts.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here cts.update_params({'order': order}) # postcts_hold node order = postcts_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postcts_hold.update_params({'order': order}) # route node order = route.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here route.update_params({'order': order}) # postroute node order = postroute.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postroute.update_params({'order': order}) # postroute-hold node order = postroute_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postroute_hold.update_params({'order': order}) # signoff node order = signoff.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here read_idx = order.index( 'generate-results.tcl') # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') signoff.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multicorner-multivt' pwr_aware = True flatten = 3 if os.environ.get('FLATTEN'): flatten = os.environ.get('FLATTEN') synth_power = False if os.environ.get('SYNTH_POWER') == 'True': synth_power = True # power domains do not work with post-synth power if synth_power: pwr_aware = False parameters = { 'construct_path' : __file__, 'design_name' : 'Tile_PE', 'clock_period' : 1.1, 'adk' : adk_name, 'adk_view' : adk_view, # Synthesis 'flatten_effort' : flatten, 'topographical' : True, # RTL Generation 'interconnect_only' : True, # Power Domains 'PWR_AWARE' : pwr_aware, 'core_density_target': 0.63, # Power analysis "use_sdf" : False, # uses sdf but not the way it is in xrun node 'app_to_run' : 'tests/conv_3_3', 'saif_instance' : 'testbench/dut', 'testbench_name' : 'testbench', 'strip_path' : 'testbench/dut' } # steveri 2101: Hoping this is temporary. # But for now, 1.1ns pe tile is too big and full-chip CI test FAILS if (os.getenv('USER') == "buildkite-agent"): parameters['clock_period'] = 4.0; # 4ns = 250 MHz # User-level option to change clock frequency # E.g. 'export clock_period_PE="4.0"' to target 250MHz # Optionally could restrict to bk only: if (os.getenv('USER') == "buildkite-agent") cp=os.getenv('clock_period_PE') if (cp != None): print("@file_info: WARNING found env var 'clock_period_PE'") print("@file_info: WARNING setting PE clock period to '%s'" % cp) parameters['clock_period'] = cp; #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/../common/rtl' ) constraints = Step( this_dir + '/constraints' ) custom_init = Step( this_dir + '/custom-init' ) custom_genus_scripts = Step( this_dir + '/custom-genus-scripts' ) custom_flowgen_setup = Step( this_dir + '/custom-flowgen-setup' ) custom_power = Step( this_dir + '/../common/custom-power-leaf' ) short_fix = Step( this_dir + '/../common/custom-short-fix' ) genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' ) custom_timing_assert = Step( this_dir + '/../common/custom-timing-assert' ) custom_dc_scripts = Step( this_dir + '/custom-dc-scripts' ) testbench = Step( this_dir + '/../common/testbench' ) application = Step( this_dir + '/../common/application' ) lib2db = Step( this_dir + '/../common/synopsys-dc-lib2db' ) if synth_power: post_synth_power = Step( this_dir + '/../common/tile-post-synth-power' ) post_pnr_power = Step( this_dir + '/../common/tile-post-pnr-power' ) # Power aware setup power_domains = None pwr_aware_gls = None if pwr_aware: power_domains = Step( this_dir + '/../common/power-domains' ) pwr_aware_gls = Step( this_dir + '/../common/pwr-aware-gls' ) # Default steps info = Step( 'info', default=True ) synth = Step( 'cadence-genus-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) genlibdb = Step( 'cadence-genus-genlib', default=True ) if which("calibre") is not None: drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) else: drc = Step( 'cadence-pegasus-drc', default=True ) lvs = Step( 'cadence-pegasus-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Add custom timing scripts custom_timing_steps = [ synth, postcts_hold, signoff ] # connects to these for c_step in custom_timing_steps: c_step.extend_inputs( custom_timing_assert.all_outputs() ) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs( custom_init.all_outputs() ) power.extend_inputs( custom_power.all_outputs() ) genlibdb.extend_inputs( genlibdb_constraints.all_outputs() ) synth.extend_inputs( custom_genus_scripts.all_outputs() ) iflow.extend_inputs( custom_flowgen_setup.all_outputs() ) # Extra input to DC for constraints synth.extend_inputs( ["common.tcl", "reporting.tcl", "generate-results.tcl", "scenarios.tcl", "report_alu.py", "parse_alu.py"] ) # Extra outputs from DC synth.extend_outputs( ["sdc"] ) iflow.extend_inputs( ["scenarios.tcl", "sdc"] ) init.extend_inputs( ["sdc"] ) power.extend_inputs( ["sdc"] ) place.extend_inputs( ["sdc"] ) cts.extend_inputs( ["sdc"] ) order = synth.get_param( 'order' ) order.append( 'copy_sdc.tcl' ) synth.set_param( 'order', order ) # Power aware setup if pwr_aware: synth.extend_inputs(['designer-interface.tcl', 'upf_Tile_PE.tcl', 'pe-constraints.tcl', 'pe-constraints-2.tcl', 'dc-dont-use-constraints.tcl']) init.extend_inputs(['upf_Tile_PE.tcl', 'pe-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-pe-floorplan.tcl', 'pe-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'pe-power-switches-setup.tcl', 'add-power-switches.tcl', 'check-clamp-logic-structure.tcl']) power.extend_inputs(['pd-globalnetconnect.tcl'] ) place.extend_inputs(['place-dont-use-constraints.tcl', 'check-clamp-logic-structure.tcl', 'add-aon-tie-cells.tcl']) cts.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) postcts_hold.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] ) route.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] ) postroute.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] ) signoff.extend_inputs(['conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl', 'check-clamp-logic-structure.tcl'] ) pwr_aware_gls.extend_inputs(['design.vcs.pg.v']) # Add short_fix script(s) to list of available postroute scripts postroute.extend_inputs( short_fix.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( constraints ) g.add_step( custom_dc_scripts ) g.add_step( synth ) g.add_step( custom_timing_assert ) g.add_step( custom_genus_scripts ) g.add_step( iflow ) g.add_step( custom_flowgen_setup ) g.add_step( init ) g.add_step( custom_init ) g.add_step( power ) g.add_step( custom_power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( short_fix ) g.add_step( signoff ) g.add_step( pt_signoff ) g.add_step( genlibdb_constraints ) g.add_step( genlibdb ) g.add_step( lib2db ) g.add_step( drc ) g.add_step( lvs ) g.add_step( debugcalibre ) g.add_step( application ) g.add_step( testbench ) if synth_power: g.add_step( post_synth_power ) g.add_step( post_pnr_power ) # Power aware step if pwr_aware: g.add_step( power_domains ) g.add_step( pwr_aware_gls ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges # Connect by name g.connect_by_name( adk, synth ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( rtl, synth ) g.connect_by_name( constraints, synth ) g.connect_by_name( custom_genus_scripts, synth ) g.connect_by_name( constraints, iflow ) g.connect_by_name( custom_dc_scripts, iflow ) for c_step in custom_timing_steps: g.connect_by_name( custom_timing_assert, c_step ) g.connect_by_name( synth, iflow ) g.connect_by_name( synth, init ) g.connect_by_name( synth, power ) g.connect_by_name( synth, place ) g.connect_by_name( synth, cts ) g.connect_by_name( synth, custom_flowgen_setup ) g.connect_by_name( custom_flowgen_setup, iflow ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, signoff ) g.connect_by_name( custom_init, init ) g.connect_by_name( custom_power, power ) # Fetch short-fix script in prep for eventual use by postroute g.connect_by_name( short_fix, postroute ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, signoff ) g.connect_by_name( signoff, drc ) g.connect_by_name( signoff, lvs ) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name( signoff, genlibdb ) g.connect_by_name( adk, genlibdb ) g.connect_by_name( genlibdb_constraints, genlibdb ) g.connect_by_name( genlibdb, lib2db ) g.connect_by_name( adk, pt_signoff ) g.connect_by_name( signoff, pt_signoff ) g.connect_by_name( application, testbench ) if synth_power: g.connect_by_name( application, post_synth_power ) g.connect_by_name( synth, post_synth_power ) g.connect_by_name( testbench, post_synth_power ) g.connect_by_name( application, post_pnr_power ) g.connect_by_name( signoff, post_pnr_power ) g.connect_by_name( pt_signoff, post_pnr_power ) g.connect_by_name( testbench, post_pnr_power ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( synth, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) # Pwr aware steps: if pwr_aware: g.connect_by_name( power_domains, synth ) g.connect_by_name( power_domains, init ) g.connect_by_name( power_domains, power ) g.connect_by_name( power_domains, place ) g.connect_by_name( power_domains, cts ) g.connect_by_name( power_domains, postcts_hold ) g.connect_by_name( power_domains, route ) g.connect_by_name( power_domains, postroute ) g.connect_by_name( power_domains, signoff ) g.connect_by_name( adk, pwr_aware_gls) g.connect_by_name( signoff, pwr_aware_gls) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) # Add custom timing scripts for c_step in custom_timing_steps: order = c_step.get_param( 'order' ) order.append( 'report-special-timing.tcl' ) c_step.set_param( 'order', order ) c_step.extend_postconditions( [{ 'pytest': 'inputs/test_timing.py' }] ) # Update PWR_AWARE variable synth.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True ) init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True ) power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True ) if pwr_aware: init.update_params( { 'flatten_effort': parameters['flatten_effort'] }, True ) pwr_aware_gls.update_params( { 'design_name': parameters['design_name'] }, True ) init.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) place.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) cts.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) postcts_hold.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) route.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) postroute.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) signoff.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. init.update_params( { 'core_density_target': parameters['core_density_target'] }, True ) # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' # and 'additional-path-groups' after 'make_path_groups' order = init.get_param('order') # get the default script run order path_group_idx = order.index( 'make-path-groups.tcl' ) order.insert( path_group_idx + 1, 'additional-path-groups.tcl' ) pin_idx = order.index( 'pin-assignments.tcl' ) # find pin-assignments.tcl order.insert( pin_idx + 1, 'edge-blockages.tcl' ) # add here init.update_params( { 'order': order } ) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index( 'read_design.tcl' ) # find read_design.tcl order.insert( read_idx + 1, 'genlibdb-constraints.tcl' ) # add here genlibdb.update_params( { 'order': order } ) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index( 'floorplan.tcl' ) # find floorplan.tcl order.insert( read_idx + 1, 'pe-load-upf.tcl' ) # add here order.insert( read_idx + 2, 'pd-pe-floorplan.tcl' ) # add here order.insert( read_idx + 3, 'pe-add-endcaps-welltaps-setup.tcl' ) # add here order.insert( read_idx + 4, 'pd-add-endcaps-welltaps.tcl' ) # add here order.insert( read_idx + 5, 'pe-power-switches-setup.tcl') # add here order.insert( read_idx + 6, 'add-power-switches.tcl' ) # add here order.remove('add-endcaps-welltaps.tcl') order.append('check-clamp-logic-structure.tcl') init.update_params( { 'order': order } ) # power node order = power.get_param('order') order.insert( 0, 'pd-globalnetconnect.tcl' ) # add here order.remove('globalnetconnect.tcl') power.update_params( { 'order': order } ) # place node order = place.get_param('order') read_idx = order.index( 'main.tcl' ) # find main.tcl order.insert(read_idx + 1, 'add-aon-tie-cells.tcl') order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') order.append('check-clamp-logic-structure.tcl') place.update_params( { 'order': order } ) # cts node order = cts.get_param('order') order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here order.append('check-clamp-logic-structure.tcl') cts.update_params( { 'order': order } ) # postcts_hold node order = postcts_hold.get_param('order') order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here order.append('check-clamp-logic-structure.tcl') postcts_hold.update_params( { 'order': order } ) # route node order = route.get_param('order') order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here order.append('check-clamp-logic-structure.tcl') route.update_params( { 'order': order } ) # postroute node order = postroute.get_param('order') order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here order.append('check-clamp-logic-structure.tcl') postroute.update_params( { 'order': order } ) # Add fix-shorts as the last thing to do in postroute order = postroute.get_param('order') ; # get the default script run order order.append('fix-shorts.tcl' ) ; # Add fix-shorts at the end postroute.update_params( { 'order': order } ) ; # Update # signoff node order = signoff.get_param('order') order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here read_idx = order.index( 'generate-results.tcl' ) # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') order.append('check-clamp-logic-structure.tcl') signoff.update_params( { 'order': order } ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path' : __file__, 'design_name' : 'Top', 'clock_period' : 2.0, 'adk' : adk_name, 'adk_view' : adk_view, # Synthesis 'flatten_effort' : 1, 'topographical' : False, # RTL Generation 'array_width' : 32, 'array_height' : 16, 'interconnect_only' : False, # Don't touch this parameter 'soc_only' : False, # SRAM macros 'num_words' : 2048, 'word_size' : 64, 'mux_size' : 8, 'corner' : "tt0p8v25c", 'partial_write' : True, # Low Effort flow 'express_flow' : False, 'nthreads' : 8 } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps constraints = Step( this_dir + '/constraints' ) dc = Step( this_dir + '/custom-dc-synthesis' ) custom_init = Step( this_dir + '/custom-init' ) # Default steps info = Step( 'info', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) init.extend_inputs( custom_init.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( custom_init ) g.add_step( init ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( constraints, dc ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( iflow, init ) g.connect_by_name( custom_init, init ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multivt' pwr_aware = False parameters = { 'construct_path': __file__, 'design_name': os.environ.get('design_name'), 'clock_period': float(os.environ.get('clock_period')), 'adk': adk_name, 'adk_view': adk_view, 'PWR_AWARE': os.environ.get('PWR_AWARE'), 'testbench_name': os.environ.get('testbench_name'), 'strip_path': os.environ.get('strip_path'), 'waves': os.environ.get('waves'), 'use_sdf': os.environ.get('use_sdf'), 'tile_id': os.environ.get('tile_id') } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps garnet_home = os.environ.get('GARNET_HOME') setup = Step(garnet_home + '/mflowgen/common/tile-post-pnr-power/setup') gl_sim = Step(garnet_home + '/mflowgen/common/cadence-xcelium-sim') pt_power_gl = Step(garnet_home + '/mflowgen/common/synopsys-ptpx-gl') gl_sim.extend_inputs(['test_vectors.txt', 'test_outputs.txt', 'design.v']) if os.environ.get('PWR_AWARE') == 'True': gl_sim.extend_inputs(["design.vcs.pg.v"]) design = os.environ.get('design_name') if design == 'Tile_MemCore': if os.environ.get('PWR_AWARE') == 'True': gl_sim.extend_inputs(['sram-pwr.v']) else: gl_sim.extend_inputs(['sram.v']) pt_power_gl.extend_inputs(['sram_tt.db']) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(setup) g.add_step(gl_sim) g.add_step(pt_power_gl) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- g.connect_by_name(adk, gl_sim) g.connect_by_name(adk, pt_power_gl) g.connect_by_name(setup, gl_sim) g.connect_by_name(setup, pt_power_gl) g.connect_by_name(gl_sim, pt_power_gl) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'global_buffer', 'clock_period': 1.0, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # hold target slack 'hold_target_slack': 0.045, } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') glb_tile = Step(this_dir + '/glb_tile') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-hierarchical') # Default steps info = Step('info', default=True) # constraints = Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add (dummy) parameters to the default innovus init step init.update_params({'core_width': 0, 'core_height': 0}, allow_new=True) # Add glb_tile macro inputs to downstream nodes dc.extend_inputs(['glb_tile.db']) pt_signoff.extend_inputs(['glb_tile.db']) genlibdb.extend_inputs(['glb_tile.db']) # These steps need timing info for glb_tiles tile_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, postroute_hold, signoff, gdsmerge ] for step in tile_steps: step.extend_inputs(['glb_tile_tt.lib', 'glb_tile.lef']) # Need the glb_tile gds to merge into the final layout gdsmerge.extend_inputs(['glb_tile.gds']) # Need glb_tile lvs.v file for LVS lvs.extend_inputs(['glb_tile.lvs.v']) # Need sram spice file for LVS lvs.extend_inputs(['sram.spi']) xlist = dc.get_postconditions() xlist = \ [ _ for _ in xlist if 'percent_clock_gated' not in _ ] xlist = dc.set_postconditions(xlist) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(glb_tile) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(glb_tile, dc) g.connect_by_name(glb_tile, iflow) g.connect_by_name(glb_tile, init) g.connect_by_name(glb_tile, power) g.connect_by_name(glb_tile, place) g.connect_by_name(glb_tile, cts) g.connect_by_name(glb_tile, postcts_hold) g.connect_by_name(glb_tile, route) g.connect_by_name(glb_tile, postroute) g.connect_by_name(glb_tile, postroute_hold) g.connect_by_name(glb_tile, signoff) g.connect_by_name(glb_tile, pt_signoff) g.connect_by_name(glb_tile, genlibdb) g.connect_by_name(glb_tile, gdsmerge) g.connect_by_name(glb_tile, drc) g.connect_by_name(glb_tile, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, genlibdb) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # Change nthreads dc.update_params({'nthreads': 4}) iflow.update_params({'nthreads': 4}) order = init.get_param('order') # get the default script run order reporting_idx = order.index('reporting.tcl') # find reporting.tcl # Add dont-touch before reporting order.insert(reporting_idx, 'dont-touch.tcl') init.update_params({'order': order}) # Increase hold slack on postroute_hold step postroute_hold.update_params( {'hold_target_slack': parameters['hold_target_slack']}, allow_new=True) # useful_skew cts.update_params({'useful_skew': False}, allow_new=True) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path' : __file__, 'design_name' : 'AhaGarnetSoC', 'clock_period' : 2.0, 'adk' : adk_name, 'adk_view' : adk_view, # Synthesis 'flatten_effort' : 3, 'topographical' : True, # RTL Generation 'array_width' : 32, 'array_height' : 16, 'interconnect_only' : False, # Don't touch this parameter 'soc_only' : True, # SRAM macros 'num_words' : 2048, 'word_size' : 64, 'mux_size' : 8, 'corner' : "tt0p8v25c", 'partial_write' : True, # Low Effort flow 'express_flow' : False, # TLX Ports Partitions 'TLX_FWD_DATA_LO_WIDTH': 16, 'TLX_REV_DATA_LO_WIDTH': 45 } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/../common/rtl' ) soc_rtl = Step( this_dir + '/../common/soc-rtl-v2' ) gen_sram = Step( this_dir + '/../common/gen_sram_macro' ) constraints = Step( this_dir + '/constraints' ) custom_lvs = Step( this_dir + '/custom-lvs-rules' ) custom_power = Step( this_dir + '/../common/custom-power-hierarchical' ) dc = Step( this_dir + '/custom-dc-synthesis' ) # Default steps info = Step( 'info', default=True ) #constraints = Step( 'constraints', default=True ) #dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Add cgra tile macro inputs to downstream nodes dc.extend_inputs( ['sram_tt.db'] ) pt_signoff.extend_inputs( ['sram_tt.db'] ) # These steps need timing info for cgra tiles hier_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff] for step in hier_steps: step.extend_inputs( ['sram_tt.lib', 'sram.lef'] ) # Need the cgra tile gds's to merge into the final layout gdsmerge_nodes = [gdsmerge] for node in gdsmerge_nodes: node.extend_inputs( ['sram.gds'] ) # Need extracted spice files for both tile types to do LVS lvs.extend_inputs( ['sram.spi'] ) # Add extra input edges to innovus steps that need custom tweaks power.extend_inputs( custom_power.all_outputs() ) dc.extend_inputs( soc_rtl.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( soc_rtl ) g.add_step( gen_sram ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( init ) g.add_step( power ) g.add_step( custom_power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( signoff ) g.add_step( pt_signoff ) g.add_step( gdsmerge ) g.add_step( drc ) g.add_step( lvs ) g.add_step( custom_lvs ) g.add_step( debugcalibre ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, gdsmerge ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( rtl, dc ) g.connect_by_name( soc_rtl, dc ) g.connect_by_name( constraints, dc ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( dc, power ) g.connect_by_name( dc, place ) g.connect_by_name( dc, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, signoff ) g.connect_by_name( custom_lvs, lvs ) g.connect_by_name( custom_power, power ) # SRAM macro g.connect_by_name( gen_sram, dc ) g.connect_by_name( gen_sram, iflow ) g.connect_by_name( gen_sram, init ) g.connect_by_name( gen_sram, power ) g.connect_by_name( gen_sram, place ) g.connect_by_name( gen_sram, cts ) g.connect_by_name( gen_sram, postcts_hold ) g.connect_by_name( gen_sram, route ) g.connect_by_name( gen_sram, postroute ) g.connect_by_name( gen_sram, signoff ) g.connect_by_name( gen_sram, pt_signoff ) g.connect_by_name( gen_sram, gdsmerge ) g.connect_by_name( gen_sram, drc ) g.connect_by_name( gen_sram, lvs ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, signoff ) g.connect_by_name( signoff, gdsmerge ) g.connect_by_name( signoff, drc ) g.connect_by_name( signoff, lvs ) g.connect_by_name( gdsmerge, drc ) g.connect_by_name( gdsmerge, lvs ) g.connect_by_name( adk, pt_signoff ) g.connect_by_name( signoff, pt_signoff ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( dc, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # DC needs these param to set the NO_CGRA macro dc.update_params({'soc_only': parameters['soc_only']}, True) init.update_params({'soc_only': parameters['soc_only']}, True) return g
def construct(): # Get the name of the process to be used from the environment if 'DRAGONPHY_PROCESS' in os.environ: DRAGONPHY_PROCESS = os.environ['DRAGONPHY_PROCESS'] else: DRAGONPHY_PROCESS = 'TSMC16' g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- parameters = { 'construct_path': __file__, 'design_name': 'dragonphy_top', 'topographical': True, 'hold_target_slack': 0.05 } if DRAGONPHY_PROCESS == 'FREEPDK45': parameters['adk_name'] = 'freepdk-45nm' parameters['adk_view'] = 'view-standard' parameters['qtm_tech_lib'] = 'NangateOpenCellLibrary' # override default scale factors for an older, slower process parameters['constr_time_scale'] = 10.0 parameters['constr_cap_scale'] = 10.0 * 1e3 elif DRAGONPHY_PROCESS == 'TSMC16': parameters['adk_name'] = 'tsmc16' parameters['adk_view'] = 'stdview' else: raise Exception(f'Unknown process: {DRAGONPHY_PROCESS}') #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(parameters['adk_name']) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') # genlibdb_constraints = Step(this_dir + '/custom-genlibdb-constraints') constraints = Step(this_dir + '/constraints') if DRAGONPHY_PROCESS == 'FREEPDK45': gen_sram = Step(this_dir + '/openram-gen-sram') gen_sram_small = Step(this_dir + '/openram-gen-sram-small') elif DRAGONPHY_PROCESS == 'TSMC16': gen_sram = Step(this_dir + '/mc-gen-sram') gen_sram_small = Step(this_dir + '/mc-gen-sram-small') else: raise Exception(f'Unknown process: {DRAGONPHY_PROCESS}') custom_init = Step(this_dir + '/custom-init') # custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/custom-power') custom_geom = Step(this_dir + '/custom-geom') # custom_route = Step(this_dir + '/custom-route') dc = Step(this_dir + '/synopsys-dc-synthesis') dt = Step(this_dir + '/inject_dont_touch') qtm = Step(this_dir + '/qtm') # Block-level designs (only work in TSMC16) blocks = [] print(DRAGONPHY_PROCESS) if DRAGONPHY_PROCESS == 'TSMC16': blocks += [ Step(this_dir + '/analog_core'), Step(this_dir + '/input_buffer'), Step(this_dir + '/output_buffer'), Step(this_dir + '/input_divider'), Step(this_dir + '/phase_interpolator'), Step(this_dir + '/termination'), Step(this_dir + '/mdll_r1') ] init = Step(this_dir + '/cadence-innovus-init') cts = Step(this_dir + '/cadence-innovus-cts') prelvs = Step(this_dir + '/prelvs_fix') lvs = Step(this_dir + '/mentor-calibre-lvs') gdsmerge = Step(this_dir + '/mentor-calibre-gdsmerge') fill = Step(this_dir + '/mentor-calibre-fill') # Default steps info = Step('info', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) #init = Step( 'cadence-innovus-init', default=True ) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) #cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) # gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) merge_fill = Step('mentor-calibre-gdsmerge-child', default=True) # fill = Step( 'mentor-calibre-fill', default=True ) drc = Step('mentor-calibre-drc', default=True) #lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) init.extend_inputs(custom_geom.all_outputs()) power.extend_inputs(custom_power.all_outputs()) power.extend_inputs(custom_geom.all_outputs()) #route.extend_inputs(custom_route.all_outputs()) # Add *.db files for macros to downstream nodes dbs = [ 'analog_core_lib.db', 'input_buffer_lib.db', 'output_buffer_lib.db', 'input_divider_lib.db', 'phase_interpolator_lib.db', 'termination_lib.db', 'mdll_r1_top_lib.db', 'sram_tt.db', 'sram_small_tt.db' ] dc.extend_inputs(dbs) pt_signoff.extend_inputs(dbs) genlibdb.extend_inputs(dbs) # These steps need timing and lef info for black boxes libs = [ 'analog_core.lib', 'mdll_r1_top.lib', 'input_buffer.lib', 'output_buffer.lib', 'input_divider.lib', 'phase_interpolator.lib', 'termination.lib', 'sram_tt.lib', 'sram_small_tt.lib' ] lefs = [ 'analog_core.lef', 'input_buffer.lef', 'output_buffer.lef', 'input_divider.lef', 'phase_interpolator.lef', 'termination.lef', 'mdll_r1_top.lef', 'sram.lef', 'sram_small.lef' ] lib_lef_steps = \ [iflow, init, power, place, cts, postcts_hold, route, postroute, signoff] for step in lib_lef_steps: step.extend_inputs(libs + lefs) # Add GDS files for black boxes to GDS merge step gds_list = [ 'analog_core.gds', 'input_buffer.gds', 'output_buffer.gds', 'input_divider.gds', 'phase_interpolator.gds', 'termination.gds', 'mdll_r1_top.gds', 'sram.gds', 'sram_small.gds' ] gdsmerge.extend_inputs(gds_list) # Need Spice or Verilog netlists files for black boxes for LVS spi_list = [ 'analog_core.spi', 'mdll_r1_top_macro.cdl', 'input_buffer.spi', 'input_divider.spi', 'phase_interpolator.spi', 'termination.spi', 'output_buffer.lvs.v', 'mdll_r1_top.lvs.v', 'sram.spi', 'sram_small.spi' ] lvs.extend_inputs(spi_list) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(gen_sram) g.add_step(gen_sram_small) g.add_step(constraints) g.add_step(dc) g.add_step(dt) g.add_step(iflow) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) #g.add_step( custom_route ) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) # g.add_step( genlibdb_constraints ) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(fill) g.add_step(merge_fill) g.add_step(prelvs) g.add_step(lvs) # g.add_step( custom_lvs ) g.add_step(debugcalibre) # blocks like analog_core, input_buffer, etc. for block in blocks: g.add_step(block) # *.lib and *.db files for some blocks g.add_step(qtm) # variables related to the design geometry g.add_step(custom_geom) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, fill) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(adk, qtm) # Connect up blocks like analog_core, input_buffer, etc. # The QTM step is also included here because it provides # *.lib and *.db files for some of the blocks for block in blocks + [gen_sram, gen_sram_small, qtm]: g.connect_by_name(block, dc) g.connect_by_name(block, iflow) g.connect_by_name(block, init) g.connect_by_name(block, power) g.connect_by_name(block, place) g.connect_by_name(block, cts) g.connect_by_name(block, postcts_hold) g.connect_by_name(block, route) g.connect_by_name(block, postroute) g.connect_by_name(block, signoff) g.connect_by_name(block, genlibdb) g.connect_by_name(block, pt_signoff) g.connect_by_name(block, gdsmerge) g.connect_by_name(block, drc) g.connect_by_name(block, fill) g.connect_by_name(block, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, dt) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(dt, iflow) g.connect_by_name(dt, init) g.connect_by_name(dt, power) g.connect_by_name(dt, place) g.connect_by_name(dt, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_geom, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_geom, power) # g.connect_by_name( custom_lvs, lvs ) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) # g.connect_by_name( custom_route, route ) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, prelvs) g.connect_by_name(prelvs, lvs) g.connect_by_name(gdsmerge, fill) g.connect_by_name(fill, merge_fill) g.connect_by_name(gdsmerge, merge_fill) g.connect_by_name(merge_fill, lvs) g.connect_by_name(merge_fill, drc) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) # g.connect_by_name( genlibdb_constraints, genlibdb ) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dt, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(prelvs, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) #### # modify script order for init #### order = init.get_param('order') # get the default script run order # Add 'set-geom-vars.tcl' at the beginning order.insert(0, 'set-geom-vars.tcl') init.update_params({'order': order}) #### # modify script order for power #### order = power.get_param('order') # get the default script run order # Add 'set-geom-vars.tcl' at the beginning order.insert(0, 'set-geom-vars.tcl') power.update_params({'order': order}) #order = route.get_param('order') #order.insert(0, 'route-settings.tcl') power.update_params({'order': order}) postroute_hold.update_params( {'hold_target_slack': parameters['hold_target_slack']}, allow_new=True) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multicorner-multivt' pwr_aware = True parameters = { 'construct_path': __file__, 'design_name': 'Tile_MemCore', # 'clock_period' : 1.1, # 900MHz never finishes AFAICT # 'clock_period' : 1.25, # 800MHz requires > ten hours 'clock_period': 4.0, # 250MHz finishes in three hours 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # SRAM macros 'num_words': 512, 'word_size': 32, 'mux_size': 4, 'corner': "tt0p8v25c", 'bc_corner': "ffg0p88v125c", 'partial_write': False, # Utilization target 'core_density_target': 0.74, # RTL Generation 'interconnect_only': True, # Power Domains 'PWR_AWARE': pwr_aware, 'testbench_name': 'Interconnect_tb', 'gl_strip_path': 'Interconnect_tb/dut' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') genlibdb_constraints = Step(this_dir + '/../common/custom-genlibdb-constraints') constraints = Step(this_dir + '/constraints') gen_sram = Step(this_dir + '/../common/gen_sram_macro') custom_init = Step(this_dir + '/custom-init') custom_genus_scripts = Step(this_dir + '/custom-genus-scripts') custom_flowgen_setup = Step(this_dir + '/custom-flowgen-setup') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-leaf') gen_testbench = Step(this_dir + '/gen_testbench') gl_sim = Step(this_dir + '/custom-vcs-sim') gl_power = Step(this_dir + '/../common/synopsys-ptpx-gl') xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim') # Power aware setup if pwr_aware: power_domains = Step(this_dir + '/../common/power-domains') pwr_aware_gls = Step(this_dir + '/../common/pwr-aware-gls') # Default steps info = Step('info', default=True) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('cadence-genus-genlib', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Extra DC input synth.extend_inputs(["common.tcl"]) synth.extend_inputs(["simple_common.tcl"]) # Add sram macro inputs to downstream nodes synth.extend_inputs(['sram_tt.lib', 'sram.lef']) #pt_signoff.extend_inputs( ['sram_tt.db'] ) genlibdb.extend_inputs(['sram_tt.lib']) # These steps need timing and lef info for srams sram_steps = \ [iflow, init, power, place, cts, postcts_hold, route, postroute, postroute_hold, signoff] for step in sram_steps: step.extend_inputs(['sram_tt.lib', 'sram_ff.lib', 'sram.lef']) # Need the sram gds to merge into the final layout signoff.extend_inputs(['sram.gds']) # Need SRAM spice file for LVS lvs.extend_inputs(['sram.spi']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) # Add extra input edges to genlibdb for loop-breaking constraints genlibdb.extend_inputs(genlibdb_constraints.all_outputs()) synth.extend_inputs(custom_genus_scripts.all_outputs()) iflow.extend_inputs(custom_flowgen_setup.all_outputs()) synth.extend_outputs(["sdc"]) iflow.extend_inputs(["sdc"]) init.extend_inputs(["sdc"]) power.extend_inputs(["sdc"]) place.extend_inputs(["sdc"]) cts.extend_inputs(["sdc"]) xcelium_sim.extend_inputs( ["array_rtl.v", "CW_fp_mult.v", "CW_fp_add.v", "sram.v"]) order = synth.get_param('order') order.append('copy_sdc.tcl') synth.set_param('order', order) # Power aware setup if pwr_aware: synth.extend_inputs([ 'designer-interface.tcl', 'upf_Tile_MemCore.tcl', 'mem-constraints.tcl', 'mem-constraints-2.tcl', 'dc-dont-use-constraints.tcl' ]) init.extend_inputs([ 'check-clamp-logic-structure.tcl', 'upf_Tile_MemCore.tcl', 'mem-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-mem-floorplan.tcl', 'mem-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'mem-power-switches-setup.tcl', 'add-power-switches.tcl' ]) place.extend_inputs([ 'check-clamp-logic-structure.tcl', 'place-dont-use-constraints.tcl' ]) power.extend_inputs(['pd-globalnetconnect.tcl']) cts.extend_inputs( ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl']) postcts_hold.extend_inputs( ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl']) route.extend_inputs( ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl']) postroute.extend_inputs( ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl']) postroute_hold.extend_inputs(['conn-aon-cells-vdd.tcl']) signoff.extend_inputs([ 'check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl' ]) pwr_aware_gls.extend_inputs(['design.vcs.pg.v', 'sram_pwr.v']) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(gen_sram) g.add_step(constraints) g.add_step(synth) g.add_step(custom_genus_scripts) g.add_step(iflow) g.add_step(custom_flowgen_setup) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb_constraints) g.add_step(genlibdb) g.add_step(drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) g.add_step(gen_testbench) g.add_step(gl_sim) g.add_step(gl_power) g.add_step(xcelium_sim) # Power aware step if pwr_aware: g.add_step(power_domains) g.add_step(pwr_aware_gls) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, gen_sram) g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(gen_sram, synth) g.connect_by_name(gen_sram, iflow) g.connect_by_name(gen_sram, init) g.connect_by_name(gen_sram, power) g.connect_by_name(gen_sram, place) g.connect_by_name(gen_sram, cts) g.connect_by_name(gen_sram, postcts_hold) g.connect_by_name(gen_sram, route) g.connect_by_name(gen_sram, postroute) g.connect_by_name(gen_sram, postroute_hold) g.connect_by_name(gen_sram, signoff) g.connect_by_name(gen_sram, genlibdb) g.connect_by_name(gen_sram, pt_signoff) g.connect_by_name(gen_sram, drc) g.connect_by_name(gen_sram, lvs) g.connect_by_name(rtl, synth) g.connect_by_name(constraints, synth) g.connect_by_name(custom_genus_scripts, synth) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(custom_flowgen_setup, iflow) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(genlibdb_constraints, genlibdb) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Gl sim just needs tb, adk, and outputs from signoff... g.connect_by_name(gen_testbench, gl_sim) g.connect_by_name(adk, gl_sim) g.connect_by_name(signoff, gl_sim) # xcelium sim just needs tb, adk, and outputs from signoff... g.connect_by_name(gen_testbench, xcelium_sim) g.connect_by_name(adk, xcelium_sim) g.connect_by_name(signoff, xcelium_sim) g.connect_by_name(gen_sram, xcelium_sim) # Now hand off the rest of everything to ptpx-gl g.connect_by_name(adk, gl_power) g.connect_by_name(signoff, gl_power) g.connect_by_name(xcelium_sim, gl_power) # Pwr aware steps: if pwr_aware: g.connect_by_name(power_domains, synth) g.connect_by_name(power_domains, init) g.connect_by_name(power_domains, power) g.connect_by_name(power_domains, place) g.connect_by_name(power_domains, cts) g.connect_by_name(power_domains, postcts_hold) g.connect_by_name(power_domains, route) g.connect_by_name(power_domains, postroute) g.connect_by_name(power_domains, postroute_hold) g.connect_by_name(power_domains, signoff) g.connect_by_name(adk, pwr_aware_gls) g.connect_by_name(gen_sram, pwr_aware_gls) g.connect_by_name(signoff, pwr_aware_gls) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Update PWR_AWARE variable synth.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) gl_power.update_params({'strip_path': parameters['gl_strip_path']}, True) if pwr_aware: pwr_aware_gls.update_params({'design_name': parameters['design_name']}, True) init.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) place.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) cts.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postcts_hold.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) route.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postroute.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) signoff.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) # Core density target param init.update_params( {'core_density_target': parameters['core_density_target']}, True) # Disable pwr aware flow #init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) #power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True ) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' order = init.get_param('order') # get the default script run order path_group_idx = order.index('make-path-groups.tcl') order.insert(path_group_idx + 1, 'additional-path-groups.tcl') pin_idx = order.index('pin-assignments.tcl') # find pin-assignments.tcl order.insert(pin_idx + 1, 'edge-blockages.tcl') # add here init.update_params({'order': order}) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index('read_design.tcl') # find read_design.tcl order.insert(read_idx + 1, 'genlibdb-constraints.tcl') # add here genlibdb.update_params({'order': order}) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index('floorplan.tcl') # find floorplan.tcl order.insert(read_idx + 1, 'mem-load-upf.tcl') # add here order.insert(read_idx + 2, 'pd-mem-floorplan.tcl') # add here order.insert(read_idx + 3, 'mem-add-endcaps-welltaps-setup.tcl') # add here order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl') # add here order.insert(read_idx + 5, 'mem-power-switches-setup.tcl') # add here order.insert(read_idx + 6, 'add-power-switches.tcl') # add here order.remove('add-endcaps-welltaps.tcl') order.append('check-clamp-logic-structure.tcl') init.update_params({'order': order}) # power node order = power.get_param('order') order.insert(0, 'pd-globalnetconnect.tcl') # add here order.remove('globalnetconnect.tcl') power.update_params({'order': order}) # place node order = place.get_param('order') read_idx = order.index('main.tcl') # find main.tcl order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') order.append('check-clamp-logic-structure.tcl') place.update_params({'order': order}) # cts node order = cts.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') cts.update_params({'order': order}) # postcts_hold node order = postcts_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postcts_hold.update_params({'order': order}) # route node order = route.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') route.update_params({'order': order}) # postroute node order = postroute.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postroute.update_params({'order': order}) # postroute-hold node order = postroute_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here postroute_hold.update_params({'order': order}) # signoff node order = signoff.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') read_idx = order.index( 'generate-results.tcl') # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') signoff.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'GarnetSOC_pad_frame', 'clock_period': 100.0, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': True, # RTL Generation 'array_width': 32, 'array_height': 16, 'interconnect_only': False, # Include Garnet? 'soc_only': False, # SRAM macros 'num_words': 2048, 'word_size': 64, 'mux_size': 8, 'corner': "tt0p8v25c", 'partial_write': True, # Low Effort flow 'express_flow': False, 'skip_verify_connectivity': True, 'lvs_hcells_file': 'inputs/adk/hcells.inc', 'lvs_connect_names': '"VDD VSS VDDPST"', # DRC rule deck 'drc_rule_deck': 'calibre-drc-chip.rule', 'antenna_drc_rule_deck': 'calibre-drc-antenna.rule' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') soc_rtl = Step(this_dir + '/../common/soc-rtl') gen_sram = Step(this_dir + '/../common/gen_sram_macro') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-chip') dc = Step(this_dir + '/custom-dc-synthesis') init_fc = Step(this_dir + '/../common/init-fullchip') io_file = Step(this_dir + '/io_file') pre_route = Step(this_dir + '/pre-route') sealring = Step(this_dir + '/sealring') netlist_fixing = Step(this_dir + '/../common/fc-netlist-fixing') # Block-level designs tile_array = Step(this_dir + '/tile_array') glb_top = Step(this_dir + '/glb_top') global_controller = Step(this_dir + '/global_controller') # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) #dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) fill = Step('mentor-calibre-fill', default=True) # Send in the clones # 'power' step now gets its own design-rule check power_drc = drc.clone() power_drc.set_name('power-drc') # "power" now builds a gds file for its own drc check "power_drc"; # so need a gdsmerge step between the two power_gdsmerge = gdsmerge.clone() power_gdsmerge.set_name('power-gdsmerge') # Antenna DRC Check antenna_drc = drc.clone() antenna_drc.set_name('antenna-drc') # Add cgra tile macro inputs to downstream nodes dc.extend_inputs(['tile_array.db']) dc.extend_inputs(['glb_top.db']) dc.extend_inputs(['global_controller.db']) dc.extend_inputs(['sram_tt.db']) pt_signoff.extend_inputs(['tile_array.db']) pt_signoff.extend_inputs(['glb_top.db']) pt_signoff.extend_inputs(['global_controller.db']) pt_signoff.extend_inputs(['sram_tt.db']) route.extend_inputs(['pre-route.tcl']) signoff.extend_inputs(sealring.all_outputs()) signoff.extend_inputs(netlist_fixing.all_outputs()) # These steps need timing info for cgra tiles hier_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff] for step in hier_steps: step.extend_inputs(['tile_array_tt.lib', 'tile_array.lef']) step.extend_inputs(['glb_top_tt.lib', 'glb_top.lef']) step.extend_inputs( ['global_controller_tt.lib', 'global_controller.lef']) step.extend_inputs(['sram_tt.lib', 'sram.lef']) # Need the cgra tile gds's to merge into the final layout gdsmerge_nodes = [gdsmerge, power_gdsmerge] for node in gdsmerge_nodes: node.extend_inputs(['tile_array.gds']) node.extend_inputs(['glb_top.gds']) node.extend_inputs(['global_controller.gds']) node.extend_inputs(['sram.gds']) # Need extracted spice files for both tile types to do LVS lvs.extend_inputs(['tile_array.lvs.v']) lvs.extend_inputs(['tile_array.sram.spi']) lvs.extend_inputs(['glb_top.lvs.v']) lvs.extend_inputs(['glb_top.sram.spi']) lvs.extend_inputs(['global_controller.lvs.v']) lvs.extend_inputs(['sram.spi']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) init.extend_inputs(init_fc.all_outputs()) power.extend_inputs(custom_power.all_outputs()) dc.extend_inputs(soc_rtl.all_outputs()) power.extend_outputs(["design.gds.gz"]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(soc_rtl) g.add_step(gen_sram) g.add_step(tile_array) g.add_step(glb_top) g.add_step(global_controller) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(init_fc) g.add_step(io_file) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(pre_route) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(sealring) g.add_step(netlist_fixing) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(gdsmerge) g.add_step(fill) g.add_step(drc) g.add_step(antenna_drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) # Post-Power DRC check g.add_step(power_drc) g.add_step(power_gdsmerge) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, fill) g.connect_by_name(adk, drc) g.connect_by_name(adk, antenna_drc) g.connect_by_name(adk, lvs) # Post-Power DRC check g.connect_by_name(adk, power_gdsmerge) g.connect_by_name(adk, power_drc) # All of the blocks within this hierarchical design # Skip these if we're doing soc_only if parameters['soc_only'] == False: blocks = [tile_array, glb_top, global_controller] for block in blocks: g.connect_by_name(block, dc) g.connect_by_name(block, iflow) g.connect_by_name(block, init) g.connect_by_name(block, power) g.connect_by_name(block, place) g.connect_by_name(block, cts) g.connect_by_name(block, postcts_hold) g.connect_by_name(block, route) g.connect_by_name(block, postroute) g.connect_by_name(block, postroute_hold) g.connect_by_name(block, signoff) g.connect_by_name(block, pt_signoff) g.connect_by_name(block, gdsmerge) g.connect_by_name(block, power_gdsmerge) g.connect_by_name(block, drc) g.connect_by_name(block, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(soc_rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(custom_power, power) # SRAM macro g.connect_by_name(gen_sram, dc) g.connect_by_name(gen_sram, iflow) g.connect_by_name(gen_sram, init) g.connect_by_name(gen_sram, power) g.connect_by_name(gen_sram, place) g.connect_by_name(gen_sram, cts) g.connect_by_name(gen_sram, postcts_hold) g.connect_by_name(gen_sram, route) g.connect_by_name(gen_sram, postroute) g.connect_by_name(gen_sram, postroute_hold) g.connect_by_name(gen_sram, signoff) g.connect_by_name(gen_sram, pt_signoff) g.connect_by_name(gen_sram, gdsmerge) g.connect_by_name(gen_sram, power_gdsmerge) g.connect_by_name(gen_sram, drc) g.connect_by_name(gen_sram, lvs) # Full chip floorplan stuff g.connect_by_name(io_file, init_fc) g.connect_by_name(init_fc, init) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, lvs) # Doing DRC on post-fill GDS instead #g.connect_by_name( gdsmerge, drc ) g.connect_by_name(gdsmerge, lvs) # Run Fill on merged GDS g.connect(gdsmerge.o('design_merged.gds'), fill.i('design.gds')) # Run DRC on merged and filled gds g.connect(fill.o('design.gds'), drc.i('design_merged.gds')) g.connect(fill.o('design.gds'), antenna_drc.i('design_merged.gds')) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) g.connect_by_name(pre_route, route) g.connect_by_name(sealring, signoff) g.connect_by_name(netlist_fixing, signoff) # Post-Power DRC g.connect_by_name(power, power_gdsmerge) g.connect_by_name(power_gdsmerge, power_drc) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # DC needs these param to set the NO_CGRA macro dc.update_params({'soc_only': parameters['soc_only']}, True) init.update_params({'soc_only': parameters['soc_only']}, True) init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'alignment-cells.tcl', 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'place-macros.tcl', 'dont-touch.tcl' ] }) # Power node order manipulation order = power.get_param('order') # Move endcap/welltap insertion to end of power step to improve runtime order.append('add-endcaps-welltaps.tcl') # Stream out post-power GDS so that we can run DRC here order.append('innovus-foundation-flow/custom-scripts/stream-out.tcl') order.append('attach-results-to-outputs.tcl') power.update_params({'order': order}) # Add pre-route plugin to insert skip_routing commands order = route.get_param('order') order.insert(0, 'pre-route.tcl') route.update_params({'order': order}) # Add sealring at beginning of signoff, so it's in before we stream out GDS order = signoff.get_param('order') order.insert(0, 'add-sealring.tcl') # Add netlist-fixing script before we save new netlist index = order.index('generate-results.tcl') order.insert(index, 'netlist-fixing.tcl') signoff.update_params({'order': order}) # Fill adds _filled to end of design_name drc.update_params({'design_name': parameters['design_name'] + "_filled"}) antenna_drc.update_params( {'design_name': parameters['design_name'] + "_filled"}) # Antenna DRC node needs to use antenna rule deck antenna_drc.update_params( {'drc_rule_deck': parameters['antenna_drc_rule_deck']}) return g