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' : '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 = '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' parameters = { 'construct_path': __file__, 'design_name': 'global_controller', 'clock_period': 1.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, # hold target slack 'hold_target_slack': 0.030, # Utilization target 'core_density_target': 0.50 } #----------------------------------------------------------------------- # 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') lib2db = Step(this_dir + '/../common/synopsys-dc-lib2db') # 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 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(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(debugcalibre) #----------------------------------------------------------------------- # 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(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) 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(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(genlib, lib2db) 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) # 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}) # Add density target parameter init.update_params( {'core_density_target': parameters['core_density_target']}, True) # Increase hold slack on postroute_hold step postroute_hold.update_params( {'hold_target_slack': parameters['hold_target_slack']}, allow_new=True) # 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 = '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, # Pipeline stage insertion 'pipeline_config_interval': 8, 'pipeline_stage_height': 30, # 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') 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') # 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) 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.db'] ) #pt_signoff.extend_inputs( ['Tile_MemCore.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']) # 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( dc ) 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(signoff) #g.add_step( pt_signoff ) #g.add_step( genlibdb ) g.add_step(genlib) 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, 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) # 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, 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, 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, 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, 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(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' 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(): # Four steps to make a peanut butter and jelly sandwich this_dir = os.path.dirname(os.path.abspath(__file__)) bread = Step(this_dir + '/extra-steps/bread') peanut_butter = Step(this_dir + '/extra-steps/peanut_butter') jelly = Step(this_dir + '/extra-steps/jelly') sandwich = Step(this_dir + '/extra-steps/sandwich') # Create the graph # # +-------+ # | bread | # +-------+ # / \ # slice 1 / \ slice 2 # / \ # +-------+ +---------------+ # | jelly | | peanut butter | # +-------+ +---------------+ # \ / # jelly \ / peanut butter # slice \ / slice # \ / # +----------+ # | sandwich | # +----------+ # g = Graph() g.add_step(bread) g.add_step(peanut_butter) g.add_step(jelly) g.add_step(sandwich) # Add edges -- bread slice 1 -> jelly g.connect( bread.o('slice1.txt'), jelly.i('slice_of_bread.txt'), ) # Add edges -- bread slice 2 -> peanut butter g.connect( bread.o('slice2.txt'), peanut_butter.i('slice_of_bread.txt'), ) # Add edges -- jelly slice -> sandwich g.connect( jelly.o('jelly_on_bread.txt'), sandwich.i('half_1.txt'), ) # Add edges -- peanut butter slice -> sandwich g.connect( peanut_butter.o('peanut_butter_on_bread.txt'), sandwich.i('half_2.txt'), ) 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') read_design = Step(this_dir + '/../common/fc-custom-read-design') 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) 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) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-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 = [signoff] 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()) dc.extend_inputs(read_design.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(read_design) 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(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, 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, 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(read_design, 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, 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, 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, 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 this param to set the NO_CGRA macro dc.update_params({'soc_only': parameters['soc_only']}, True) # DC needs these params to set macros in soc rtl dc.update_params( {'TLX_FWD_DATA_LO_WIDTH': parameters['TLX_FWD_DATA_LO_WIDTH']}, True) dc.update_params( {'TLX_REV_DATA_LO_WIDTH': parameters['TLX_REV_DATA_LO_WIDTH']}, True) init.update_params({'soc_only': parameters['soc_only']}, True) 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 = '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': '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') sim = Step(this_dir + '/sim') glb_tile = Step(this_dir + '/glb_tile') glb_tile_rtl = Step(this_dir + '/glb_tile_rtl') glb_tile_syn = Step(this_dir + '/glb_tile_syn') 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) 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 glb_tile macro inputs to downstream nodes pt_signoff.extend_inputs(['glb_tile.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()) sim.extend_inputs(['design.v']) sim.extend_inputs(['glb_tile.v']) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(sim) g.add_step(glb_tile) g.add_step(glb_tile_rtl) g.add_step(glb_tile_syn) 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, 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) g.connect_by_name(glb_tile_rtl, sim) 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(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. # 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() #----------------------------------------------------------------------- # 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() #----------------------------------------------------------------------- # 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
def construct(): g = Graph() this_dir = os.path.dirname(os.path.abspath(__file__)) #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'freepdk-45nm' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'sim_path': f"{this_dir}/../../sim", 'design_path': f"{this_dir}/../../sim/lab2_xcel", 'design_name': 'SramMinionRTL', 'clock_period': 1.2, 'clk_port': 'clk', 'reset_port': 'reset', 'adk': adk_name, 'adk_view': adk_view, 'pad_ring': False, # Floorplan Aspect Ratio 'aspect_ratio': 0.6, # make floorplan twice as wide as it is tall # Provide SRAM source files directory 'extra_link_lib_dir': f"{this_dir}/../../asic/openram-mc", # Detail SRAM placement location and other info 'sram_name': "v/sram/genblk1_sram", 'sram_x_pos': '60', 'sram_y_pos': '50', 'sram_orientation': 'R0', 'sram_top_layer': '4', # check 'halo_size_um': '2', 'routing_blk_size_um': '2', # Power 'macro': 'True', # VCS-sim 'test_design_name': 'SramMinionRTL', 'input_delay': 0.05, 'output_delay': 0.05, # Synthesis 'gate_clock': True, 'topographical': False, # PT Power 'saif_instance': 'SramMinionRTL_tb/DUT', } #----------------------------------------------------------------------- # Truncate design name at first instance of '__' to run the right tests #----------------------------------------------------------------------- trunc_design_name = parameters['design_name'] trunc_design_name = trunc_design_name.split("__", 1)[0] parameters['trunc_design_name'] = trunc_design_name #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps info = Step('info', default=True) gather = Step('brgtc5-block-gather', default=True) vcsSim = Step('brg-synopsys-vcs-sim', default=True) synth = Step('brg-synopsys-dc-synthesis', default=True) init = Step('brg-cadence-innovus-init', default=True) floorplan = Step('brg-cadence-innovus-blocksetup-floorplan', default=True) powergrid = Step('brg-cadence-innovus-blocksetup-power', default=True) pnr = Step('brg-cadence-innovus-pnr', default=True) signoff = Step('brg-cadence-innovus-signoff', default=True) power = Step('brg-synopsys-pt-power', default=True) summary = Step('brg-flow-summary', default=True) # Clone vcsSim rtlsim = vcsSim.clone() glFFsim = vcsSim.clone() # glBAsim = vcsSim.clone() # Clone pt-power synthpower = power.clone() # pnrpower = power.clone() # Give clones new names rtlsim.set_name('brg-rtl-4-state-vcssim') glFFsim.set_name('post-synth-gate-level-simulation') # glBAsim.set_name('post-pnr-gate-level-simulation') synthpower.set_name('post-synth-power-analysis') # pnrpower.set_name("post-pnr-power-analysis") info.set_name('build-info') #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(gather) g.add_step(rtlsim) g.add_step(synth) g.add_step(glFFsim) g.add_step(init) g.add_step(floorplan) g.add_step(powergrid) g.add_step(pnr) g.add_step(signoff) # g.add_step( glBAsim ) g.add_step(synthpower) # g.add_step( pnrpower ) g.add_step(summary) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, synth) g.connect_by_name(adk, glFFsim) g.connect_by_name(adk, init) g.connect_by_name(adk, floorplan) g.connect_by_name(adk, powergrid) g.connect_by_name(adk, pnr) g.connect_by_name(adk, signoff) # g.connect_by_name( adk, glBAsim ) g.connect_by_name(adk, synthpower) # g.connect_by_name( adk, pnrpower ) g.connect_by_name(gather, synth) g.connect_by_name(gather, rtlsim) g.connect_by_name(gather, glFFsim) # g.connect_by_name( gather, glBAsim ) g.connect_by_name(synth, glFFsim) # design.vcs.v g.connect_by_name(synth, init) g.connect_by_name(synth, floorplan) g.connect_by_name(synth, powergrid) g.connect_by_name(synth, pnr) g.connect_by_name(synth, signoff) g.connect(synth.o('design.sdc'), synthpower.i('design.sdc')) #design.sdc g.connect(synth.o('design.vcs.v'), synthpower.i('design.vcs.v')) #design.vcs.v g.connect(synth.o('design.spef.gz'), synthpower.i('design.spef.gz')) #design.spef.gz # g.connect( synth.o( 'design.sdc'), pnrpower.i('design.sdc')) #design.sdc g.connect_by_name(init, floorplan) g.connect_by_name(floorplan, powergrid) g.connect_by_name(powergrid, pnr) g.connect_by_name(pnr, signoff) # g.connect_by_name( signoff, glBAsim ) # design.vcs.v, design.sdf # g.connect_by_name( signoff, pnrpower ) # design.vcs.v, design.spef.gz g.connect_by_name(signoff, summary) g.connect_by_name(glFFsim, synthpower) # saif, vcd # g.connect_by_name( glBAsim, pnrpower ) # saif, vcd g.connect(rtlsim.o('sim.summary.txt'), summary.i('4state.summary.txt')) g.connect(glFFsim.o('sim.summary.txt'), summary.i('ff.summary.txt')) # g.connect( glBAsim.o('sim.summary.txt'), summary.i('ba.summary.txt')) g.connect(synthpower.o('power.summary.txt'), summary.i('powerFF.summary.txt')) # g.connect( pnrpower.o('power.summary.txt'), summary.i('powerBA.summary.txt')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) rtlsim.update_params({'simtype': 'rtl'}, False) glFFsim.update_params({'simtype': 'gate-level'}, False) # glBAsim.update_params({'simtype': 'gate-level'}, False) synthpower.update_params({'zero_delay_simulation': True}, False) return g