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 = '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 = '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 = '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 = '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