def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'skywater-130nm-adk' adk_view = 'view-standard' parameters = { 'construct_path': __file__, 'design_name': 'user_proj_example', 'clock_period': 62.5, 'adk': adk_name, 'adk_view': adk_view, 'topographical': True, 'strip_path': 'user_proj_example', 'saif_instance': 'user_proj_example' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') pin_placement = Step(this_dir + '/pin-placement') floorplan = Step(this_dir + '/floorplan') # Power node is custom because power and gnd pins are named differently in # the standard cells compared to the default node, and the layer numbering is # different because of li layer, the default assumes metal 1 is the lowest # layer power = Step(this_dir + '/cadence-innovus-power') # Signoff is custom because it has to output def that the default step does # not do. This is because we use the def instead of gds for generating spice # from layout for LVS signoff = Step(this_dir + '/cadence-innovus-signoff') pt_power_rtl = Step(this_dir + '/synopsys-ptpx-rtl') magic_drc = Step(this_dir + '/open-magic-drc') magic_def2spice = Step(this_dir + '/open-magic-def2spice') magic_gds2spice = Step(this_dir + '/open-magic-gds2spice') netgen_lvs = Step(this_dir + '/open-netgen-lvs') magic_antenna = Step(this_dir + '/open-magic-antenna') calibre_lvs = Step(this_dir + '/mentor-calibre-comparison') pt_timing = Step(this_dir + '/synopsys-pt-timing-signoff') export = Step(this_dir + '/export-to-openlane') dc = Step( this_dir + '/synopsys-dc-synthesis') # NEW DC with netname case sensitivity fix genlibdb = Step(this_dir + '/synopsys-ptpx-genlibdb') # Default steps info = Step('info', default=True) # Need to use clone if you want to instantiate the same node more than once # in your graph but configure it differently, for example, RTL simulation and # gate-level simulation use the same VCS node # cocotb based simulation steps rtl_sim = Step(this_dir + '/rtl-sim') iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) # pt_timing = Step( 'synopsys-pt-timing-signoff', default=True ) gen_saif = Step('synopsys-vcd2saif-convert', default=True) gen_saif_rtl = gen_saif.clone() # gen_saif_gl = gen_saif.clone() gen_saif_rtl.set_name('gen-saif-rtl') # gen_saif_gl.set_name( 'gen-saif-gl' ) netgen_lvs_def = netgen_lvs.clone() netgen_lvs_def.set_name('netgen-lvs-def') netgen_lvs_gds = netgen_lvs.clone() netgen_lvs_gds.set_name('netgen-lvs-gds') # pt_power_gl = Step( 'synopsys-ptpx-gl', default=True ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(rtl_sim) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(pin_placement) g.add_step(floorplan) g.add_step(init) g.add_step(power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(gdsmerge) g.add_step(export) g.add_step(pt_timing) g.add_step(gen_saif_rtl) g.add_step(pt_power_rtl) g.add_step(genlibdb) # g.add_step( gl_sim ) # g.add_step( gen_saif_gl ) # g.add_step( pt_power_gl ) g.add_step(magic_drc) g.add_step(magic_antenna) g.add_step(magic_def2spice) g.add_step(netgen_lvs_def) g.add_step(magic_gds2spice) g.add_step(netgen_lvs_gds) g.add_step(calibre_lvs) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges init.extend_inputs(['floorplan.tcl', 'pin-assignments.tcl']) # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, magic_drc) g.connect_by_name(adk, magic_antenna) g.connect_by_name(adk, magic_def2spice) g.connect_by_name(adk, magic_gds2spice) g.connect_by_name(adk, netgen_lvs_def) g.connect_by_name(adk, netgen_lvs_gds) g.connect_by_name(adk, calibre_lvs) g.connect_by_name(adk, pt_timing) g.connect_by_name(adk, pt_power_rtl) g.connect_by_name(adk, genlibdb) # g.connect_by_name( adk, pt_power_gl ) # g.connect_by_name( pt_timing, genlibdb ) g.connect_by_name(signoff, genlibdb) g.connect_by_name(rtl_sim, gen_saif_rtl) # run.vcd # g.connect_by_name( gl_sim, gen_saif_gl ) # run.vcd g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(gen_saif_rtl, dc) # run.saif g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(dc, pt_power_rtl) # design.namemap g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) # Core place and route flow g.connect_by_name(floorplan, init) g.connect_by_name(pin_placement, init) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, gdsmerge) # Openlane export g.connect_by_name(signoff, export) g.connect_by_name(gdsmerge, export) # DRC, LVS, timing signoff and power signoff g.connect_by_name(gdsmerge, magic_drc) g.connect_by_name(signoff, magic_antenna) # LVS using DEF g.connect_by_name(signoff, magic_def2spice) g.connect_by_name(signoff, netgen_lvs_def) g.connect_by_name(magic_def2spice, netgen_lvs_def) # LVS using GDS g.connect_by_name(gdsmerge, magic_gds2spice) g.connect_by_name(signoff, netgen_lvs_gds) g.connect_by_name(magic_gds2spice, netgen_lvs_gds) # LVS comparision using Calibre g.connect_by_name(signoff, calibre_lvs) g.connect_by_name(magic_gds2spice, calibre_lvs) g.connect_by_name(signoff, pt_timing) g.connect_by_name(signoff, pt_power_rtl) g.connect_by_name(gen_saif_rtl, pt_power_rtl) # run.saif # g.connect_by_name( signoff, pt_power_gl ) # g.connect_by_name( gen_saif_gl, pt_power_gl ) # run.saif # Gate level simulation # g.connect_by_name( adk, gl_sim ) # g.connect( signoff.o( 'design.vcs.pg.v' ), gl_sim.i( 'design.v' ) ) # g.connect( pt_timing.o( 'design.sdf' ), gl_sim.i( 'design.sdf' ) ) # g.connect( testbench.o( 'testbench.sv' ), gl_sim.i( 'testbench.sv' ) ) # g.connect( testbench.o( 'design.args.gls' ), gl_sim.i( 'design.args' ) ) # g.connect( testbench.o( 'test_vectors.txt' ), gl_sim.i( 'test_vectors.txt' ) ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'view-standard' if which("calibre") is not None: drc_rule_deck = 'calibre-drc-chip.rule' antenna_drc_rule_deck = 'calibre-drc-antenna.rule' power_drc_rule_deck = 'calibre-drc-block.rule' else: drc_rule_deck = 'pegasus-drc-chip.rule' antenna_drc_rule_deck = 'pegasus-drc-antenna.rule' power_drc_rule_deck = 'pegasus-drc-block.rule' parameters = { 'construct_path': __file__, 'design_name': 'GarnetSOC_pad_frame', 'clock_period': 1.3, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 0, 'topographical': True, # RTL Generation 'array_width': 32, 'array_height': 16, 'num_glb_tiles': 16, 'interconnect_only': False, # glb tile memory size (unit: KB) # 'glb_tile_mem_size' : 64, # 64x16 => 1M global buffer 'glb_tile_mem_size': 256, # 256*16 => 4M global buffer # Power Domains 'PWR_AWARE': True, # Include Garnet? 'soc_only': False, # Include SoC core? (use 0 for false, 1 for true) 'include_core': 1, # Include sealring? 'include_sealring': True, # SRAM macros 'num_words': 2048, 'word_size': 64, 'mux_size': 8, 'corner': "tt0p8v25c", 'partial_write': True, # Dragonphy 'dragonphy_rdl_x': '613.565u', 'dragonphy_rdl_y': '3901.872u', # Low Effort flow 'express_flow': False, 'skip_verify_connectivity': True, # Hold fixing 'signoff_engine': True, 'hold_target_slack': 0.060, # LVS # - need lvs2 because dragonphy uses LVT cells 'lvs_extra_spice_include': 'inputs/adk_lvs2/*.cdl', 'lvs_hcells_file': 'inputs/adk/hcells.inc', 'lvs_connect_names': '"VDD VSS VDDPST"', 'lvs_verify_netlist': 0, # TSMC16 support for LVS - need lvs2 because dragonphy uses LVT cells 'adk_view_lvs2': 'multivt', # TLX Ports Partitions 'TLX_FWD_DATA_LO_WIDTH': 16, 'TLX_REV_DATA_LO_WIDTH': 45, # DRC rule deck 'drc_rule_deck': drc_rule_deck, 'antenna_drc_rule_deck': antenna_drc_rule_deck, 'power_drc_rule_deck': power_drc_rule_deck, 'nthreads': 16, # Testbench 'cgra_apps': ["tests/conv_1_2", "tests/conv_2_1"] } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') soc_rtl = Step(this_dir + '/../common/soc-rtl-v2') gen_sram = Step(this_dir + '/../common/gen_sram_macro') constraints = Step(this_dir + '/constraints') read_design = Step(this_dir + '/../common/fc-custom-read-design') custom_init = Step(this_dir + '/custom-init') custom_lvs = Step(this_dir + '/custom-lvs-rules') custom_power = Step(this_dir + '/../common/custom-power-chip') init_fc = Step(this_dir + '/../common/init-fullchip') io_file = Step(this_dir + '/io_file') pre_route = Step(this_dir + '/pre-route') sealring = Step(this_dir + '/sealring') netlist_fixing = Step(this_dir + '/../common/fc-netlist-fixing') # Block-level designs tile_array = Step(this_dir + '/tile_array') glb_top = Step(this_dir + '/glb_top') global_controller = Step(this_dir + '/global_controller') dragonphy = Step(this_dir + '/dragonphy') # CGRA simulation cgra_rtl_sim_compile = Step(this_dir + '/cgra_rtl_sim_compile') cgra_rtl_sim_run = Step(this_dir + '/cgra_rtl_sim_run') cgra_sim_build = Step(this_dir + '/cgra_sim_build') # cgra_gl_sim_compile = Step( this_dir + '/cgra_gl_sim_compile' ) # cgra_gl_sim_run = Step( this_dir + '/cgra_gl_sim_run' ) # cgra_gl_ptpx = Step( this_dir + '/cgra_gl_ptpx' ) # cgra_rtl_sim_verdict = Step( this_dir + '/cgra_rtl_sim_verdict' ) # cgra_gl_sim_verdict = Step( this_dir + '/cgra_gl_sim_verdict' ) # Default steps info = Step('info', default=True) #constraints = Step( 'constraints', default=True ) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) postroute_hold = Step('cadence-innovus-postroute_hold', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) merge_rdl = Step('mentor-calibre-gdsmerge-child', default=True) fill = Step('mentor-calibre-fill', default=True) merge_fill = Step('mentor-calibre-gdsmerge-child', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) merge_rdl = Step('cadence-pegasus-gdsmerge-child', default=True) fill = Step('cadence-pegasus-fill', default=True) merge_fill = Step('cadence-pegasus-gdsmerge-child', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) merge_rdl.set_name('gdsmerge-dragonphy-rdl') merge_fill.set_name('gdsmerge-fill') # Send in the clones # 'power' step now gets its own design-rule check power_drc = drc.clone() power_drc.set_name('power-drc') # Antenna DRC Check antenna_drc = drc.clone() antenna_drc.set_name('antenna-drc') # Add cgra tile macro inputs to downstream nodes synth.extend_inputs(['tile_array_tt.lib', 'tile_array.lef']) synth.extend_inputs(['glb_top_tt.lib', 'glb_top.lef']) synth.extend_inputs(['global_controller_tt.lib', 'global_controller.lef']) synth.extend_inputs(['sram_tt.lib', 'sram.lef']) synth.extend_inputs(['dragonphy_top.lef']) # Exclude dragonphy_top from synth inputs to prevent floating # dragonphy inputs from being tied to 0 pt_signoff.extend_inputs(['tile_array_tt.db']) pt_signoff.extend_inputs(['glb_top_tt.db']) pt_signoff.extend_inputs(['global_controller_tt.db']) pt_signoff.extend_inputs(['sram_tt.db']) pt_signoff.extend_inputs(['dragonphy_top_tt.db']) route.extend_inputs(['pre-route.tcl']) signoff.extend_inputs(sealring.all_outputs()) signoff.extend_inputs(netlist_fixing.all_outputs()) # These steps need timing info for cgra tiles hier_steps = \ [ iflow, init, power, place, cts, postcts_hold, route, postroute, signoff] for step in hier_steps: step.extend_inputs(['tile_array_tt.lib', 'tile_array.lef']) step.extend_inputs(['glb_top_tt.lib', 'glb_top.lef']) step.extend_inputs( ['global_controller_tt.lib', 'global_controller.lef']) step.extend_inputs(['sram_tt.lib', 'sram.lef']) step.extend_inputs(['dragonphy_top_tt.lib', 'dragonphy_top.lef']) step.extend_inputs(['dragonphy_RDL.lef']) # Need all block gds's to merge into the final layout gdsmerge_nodes = [signoff, power] for node in gdsmerge_nodes: node.extend_inputs(['tile_array.gds']) node.extend_inputs(['glb_top.gds']) node.extend_inputs(['global_controller.gds']) node.extend_inputs(['sram.gds']) node.extend_inputs(['dragonphy_top.gds']) node.extend_inputs(['dragonphy_RDL.gds']) # Need extracted spice files for both tile types to do LVS lvs.extend_inputs(['tile_array.lvs.v']) lvs.extend_inputs(['tile_array.sram.spi']) lvs.extend_inputs(['glb_top.lvs.v']) lvs.extend_inputs(['glb_top.sram.spi']) lvs.extend_inputs(['global_controller.lvs.v']) lvs.extend_inputs(['sram.spi']) lvs.extend_inputs(['dragonphy_top.spi']) lvs.extend_inputs(['adk_lvs2']) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) init.extend_inputs(init_fc.all_outputs()) power.extend_inputs(custom_power.all_outputs()) synth.extend_inputs(soc_rtl.all_outputs()) synth.extend_inputs(read_design.all_outputs()) synth.extend_inputs(["cons_scripts"]) power.extend_outputs(["design-merged.gds"]) if parameters['interconnect_only'] is False: rtl.extend_outputs(['header']) rtl.extend_postconditions(["assert File( 'outputs/header' ) "]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(soc_rtl) g.add_step(gen_sram) g.add_step(tile_array) g.add_step(glb_top) g.add_step(global_controller) g.add_step(dragonphy) g.add_step(constraints) g.add_step(read_design) g.add_step(synth) g.add_step(iflow) g.add_step(init) g.add_step(init_fc) g.add_step(io_file) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(pre_route) g.add_step(route) g.add_step(postroute) g.add_step(postroute_hold) g.add_step(sealring) g.add_step(netlist_fixing) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(merge_rdl) g.add_step(fill) g.add_step(merge_fill) g.add_step(drc) g.add_step(antenna_drc) g.add_step(lvs) g.add_step(custom_lvs) g.add_step(debugcalibre) # Post-Power DRC check g.add_step(power_drc) # App test nodes g.add_step(cgra_rtl_sim_compile) g.add_step(cgra_sim_build) g.add_step(cgra_rtl_sim_run) # g.add_step( cgra_gl_sim_compile ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, gen_sram) g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, postroute_hold) g.connect_by_name(adk, signoff) g.connect_by_name(adk, merge_rdl) g.connect_by_name(adk, fill) g.connect_by_name(adk, merge_fill) g.connect_by_name(adk, drc) g.connect_by_name(adk, antenna_drc) g.connect_by_name(adk, lvs) # Post-Power DRC check g.connect_by_name(adk, power_drc) # Connect RTL verification nodes g.connect_by_name(rtl, cgra_rtl_sim_compile) g.connect_by_name(cgra_sim_build, cgra_rtl_sim_run) g.connect_by_name(cgra_rtl_sim_compile, cgra_rtl_sim_run) # Connect GL verification nodes # g.connect_by_name( signoff, cgra_gl_sim_compile ) # All of the blocks within this hierarchical design # Skip these if we're doing soc_only if parameters['soc_only'] == False: blocks = [tile_array, glb_top, global_controller, dragonphy] for block in blocks: g.connect_by_name(block, synth) g.connect_by_name(block, iflow) g.connect_by_name(block, init) g.connect_by_name(block, power) g.connect_by_name(block, place) g.connect_by_name(block, cts) g.connect_by_name(block, postcts_hold) g.connect_by_name(block, route) g.connect_by_name(block, postroute) g.connect_by_name(block, postroute_hold) g.connect_by_name(block, signoff) g.connect_by_name(block, pt_signoff) g.connect_by_name(block, drc) g.connect_by_name(block, lvs) # Tile_array can use rtl from rtl node g.connect_by_name(rtl, tile_array) # glb_top can use rtl from rtl node g.connect_by_name(rtl, glb_top) # global_controller can use rtl from rtl node g.connect_by_name(rtl, global_controller) g.connect_by_name(rtl, synth) g.connect_by_name(soc_rtl, synth) g.connect_by_name(constraints, synth) g.connect_by_name(read_design, synth) g.connect_by_name(soc_rtl, io_file) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, postroute_hold) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_lvs, lvs) g.connect_by_name(custom_power, power) # SRAM macro g.connect_by_name(gen_sram, synth) g.connect_by_name(gen_sram, iflow) g.connect_by_name(gen_sram, init) g.connect_by_name(gen_sram, power) g.connect_by_name(gen_sram, place) g.connect_by_name(gen_sram, cts) g.connect_by_name(gen_sram, postcts_hold) g.connect_by_name(gen_sram, route) g.connect_by_name(gen_sram, postroute) g.connect_by_name(gen_sram, postroute_hold) g.connect_by_name(gen_sram, signoff) g.connect_by_name(gen_sram, pt_signoff) g.connect_by_name(gen_sram, drc) g.connect_by_name(gen_sram, lvs) # Full chip floorplan stuff g.connect_by_name(io_file, init_fc) g.connect_by_name(init_fc, init) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, postroute_hold) g.connect_by_name(postroute_hold, signoff) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) # Skipping g.connect(signoff.o('design-merged.gds'), merge_rdl.i('design.gds')) g.connect(dragonphy.o('dragonphy_RDL.gds'), merge_rdl.i('child.gds')) g.connect_by_name(merge_rdl, lvs) # Run Fill on merged GDS g.connect(merge_rdl.o('design_merged.gds'), fill.i('design.gds')) # Merge fill g.connect(merge_rdl.o('design_merged.gds'), merge_fill.i('design.gds')) g.connect(fill.o('fill.gds'), merge_fill.i('child.gds')) # Run DRC on merged and filled gds g.connect_by_name(merge_fill, drc) g.connect_by_name(merge_fill, antenna_drc) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) g.connect_by_name(pre_route, route) g.connect_by_name(sealring, signoff) g.connect_by_name(netlist_fixing, signoff) # Post-Power DRC g.connect(power.o('design-merged.gds'), power_drc.i('design_merged.gds')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- # Allow user to override parms with env in a limited sort of way parameters = sr_override_parms(parameters) print(f'parameters["hold_target_slack"]={parameters["hold_target_slack"]}') g.update_params(parameters) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. # DC needs these param to set the NO_CGRA macro synth.update_params({'soc_only': parameters['soc_only']}, True) # DC needs these params to set macros in soc rtl synth.update_params( {'TLX_FWD_DATA_LO_WIDTH': parameters['TLX_FWD_DATA_LO_WIDTH']}, True) synth.update_params( {'TLX_REV_DATA_LO_WIDTH': parameters['TLX_REV_DATA_LO_WIDTH']}, True) init.update_params({'soc_only': parameters['soc_only']}, True) init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'alignment-cells.tcl', 'analog-bumps/route-phy-bumps.tcl', 'analog-bumps/bump-connect.tcl', 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'place-macros.tcl', 'dont-touch.tcl' ] }) # glb_top parameters update glb_top.update_params({'array_width': parameters['array_width']}, True) glb_top.update_params( {'glb_tile_mem_size': parameters['glb_tile_mem_size']}, True) glb_top.update_params({'num_glb_tiles': parameters['num_glb_tiles']}, True) # App test parameters update cgra_rtl_sim_compile.update_params( {'array_width': parameters['array_width']}, True) cgra_rtl_sim_compile.update_params( {'array_height': parameters['array_height']}, True) cgra_rtl_sim_compile.update_params( {'clock_period': parameters['clock_period']}, True) cgra_rtl_sim_compile.update_params( {'glb_tile_mem_size': parameters['glb_tile_mem_size']}, True) cgra_rtl_sim_run.update_params({'cgra_apps': parameters['cgra_apps']}, True) # Power node order manipulation order = power.get_param('order') # Move endcap/welltap insertion to end of power step to improve runtime order.append('add-endcaps-welltaps.tcl') # Stream out post-power GDS so that we can run DRC here order.append('innovus-foundation-flow/custom-scripts/stream-out.tcl') order.append('attach-results-to-outputs.tcl') power.update_params({'order': order}) # Add pre-route plugin to insert skip_routing commands order = route.get_param('order') order.insert(0, 'pre-route.tcl') route.update_params({'order': order}) # Signoff order additions order = signoff.get_param('order') # Add sealring at beginning of signoff, so it's in before we stream out GDS if parameters['include_sealring'] == True: order.insert(0, 'add-sealring.tcl') # Add netlist-fixing script before we save new netlist index = order.index('generate-results.tcl') order.insert(index, 'netlist-fixing.tcl') signoff.update_params({'order': order}) merge_rdl.update_params({ 'coord_x': parameters['dragonphy_rdl_x'], 'coord_y': parameters['dragonphy_rdl_y'], 'flatten_child': True, 'design_top_cell': parameters['design_name'], 'child_top_cell': 'dragonphy_RDL' }) merge_fill.update_params({ 'design_top_cell': parameters['design_name'], 'child_top_cell': f"{parameters['design_name']}_F16a" }) # Antenna DRC node needs to use antenna rule deck antenna_drc.update_params( {'drc_rule_deck': parameters['antenna_drc_rule_deck']}) # Power DRC node should use block level rule deck to improve runtimes and not report false errors power_drc.update_params( {'drc_rule_deck': parameters['power_drc_rule_deck']}) return g
def construct(): g = Graph() # ------------------------------------------------------------------------- # Supported tests # ------------------------------------------------------------------------- test_names = [ # CPU Tests #'apb_mux_test', #'hello_test', #'memory_test', #'dma_single_channel', #'default_slaves_test', #'interrupts_test', #'tlx_test', #'cgra_test', #'master_clock_test', 'app_test', 'harris_test', #'app_test_two_images', #'app_test_reconfig', #'app_test_reconfig_pipeline', #'app_test_2_kernels_1_cgra', # 'cascade_test', #'resnet_test', #'resnet_test_i4_o3', #'demosaic_complex', #'demosaic_complex_twice', #'demosaic_complex_harris', #'resnet_pond', # CXDT Tests 'discovery', ] # ------------------------------------------------------------------------- # Parameters # ------------------------------------------------------------------------- parameters = { 'construct_file': __file__, 'design_name': 'test-soc', 'soc_only': False, 'interconnect_only': False, 'array_width': 32, 'array_height': 16, 'clock_period': 1.0, 'ARM_IP_DIR': '/home/kkoul/aham3soc_armip', 'AHA_IP_DIR': '/sim/kkoul/AhaM3SoC', 'GATE_LEVEL_DIR': '/home/kkoul/gate_level_199', 'GARNET_DIR': '/sim/kkoul/garnet', 'TLX_FWD_DATA_LO_WIDTH': 16, 'TLX_REV_DATA_LO_WIDTH': 45, } # ------------------------------------------------------------------------- # Custom steps # ------------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) garnet_rtl = Step(parameters['GARNET_DIR'] + '/mflowgen/common/rtl') compile_design = Step(this_dir + '/compile_design') compile_design_gls = Step(this_dir + '/compile_design_gls') build_test = Step(this_dir + '/build_test') run_test = Step(this_dir + '/run_test') run_test_gls = Step(this_dir + '/run_test_gls') verdict = Step(this_dir + '/verdict') test_gen = Step(this_dir + '/test_gen') ptpx = Step(this_dir + '/ptpx') # ------------------------------------------------------------------------- # Parallelize test build and run # ------------------------------------------------------------------------- test_count = len(test_names) build_steps = list(map((lambda _: build_test.clone()), range(test_count))) run_steps = list(map((lambda _: run_test.clone()), range(test_count))) run_gls_steps = list( map((lambda _: run_test_gls.clone()), range(test_count))) ptpx_steps = list(map((lambda _: ptpx.clone()), range(test_count))) for step, name in zip(build_steps, test_names): step.set_name('build_' + name) for step, name in zip(run_steps, test_names): step.set_name('run_' + name) for step, name in zip(run_gls_steps, test_names): step.set_name('run_gls_' + name) for step, name in zip(ptpx_steps, test_names): step.set_name('ptpx_' + name) # ------------------------------------------------------------------------- # Input/output dependencies # ------------------------------------------------------------------------- # 'compile_design' step produces a simulation executable and its accompanying collateral compile_design.extend_outputs(['xcelium.d']) compile_design.extend_inputs(['design.v']) compile_design_gls.extend_outputs(['simv']) compile_design_gls.extend_outputs(['simv.daidir']) # 'build_test' produces final images for both the CXDT and CPU for step in build_steps: step.extend_outputs(['CXDT.bin']) # 'run_tests' takes CXDT.bin, CPU.bin, and xcelium.d to produce a log for step, test in zip(run_steps, test_names): step.extend_inputs(['CXDT.bin', 'xcelium.d']) step.extend_outputs(['xrun_run_' + test + '.log']) # 'run_gls_tests' takes CXDT.bin, CPU.bin, and simv and simv.daidir to produce a log for step, test in zip(run_gls_steps, test_names): step.extend_inputs(['CXDT.bin', 'simv', 'simv.daidir']) step.extend_outputs(['run.saif']) # 'ptpx' takes run.saif to produce power reports for step, test in zip(run_gls_steps, test_names): step.extend_inputs(['run.saif']) # 'verdict' consumes the run logs run_logs = list(map((lambda test: 'xrun_run_' + test + '.log'), test_names)) verdict.extend_inputs(run_logs) # ------------------------------------------------------------------------- # Graph -- Add nodes # ------------------------------------------------------------------------- g.add_step(garnet_rtl) g.add_step(compile_design) g.add_step(compile_design_gls) g.add_step(test_gen) for s in build_steps: g.add_step(s) for s in run_steps: g.add_step(s) for s in run_gls_steps: g.add_step(s) for s in ptpx_steps: g.add_step(s) g.add_step(verdict) # ------------------------------------------------------------------------- # Graph -- Add edges # ------------------------------------------------------------------------- g.connect_by_name(garnet_rtl, compile_design) for r, b in zip(run_steps, build_steps): g.connect_by_name(b, r) g.connect_by_name(compile_design, r) g.connect_by_name(r, verdict) for r, b in zip(run_gls_steps, build_steps): g.connect_by_name(b, r) g.connect_by_name(compile_design_gls, r) for p, r in zip(ptpx_steps, run_gls_steps): g.connect_by_name(r, p) # ------------------------------------------------------------------------- # Set general parameters # ------------------------------------------------------------------------- g.update_params(parameters) # ------------------------------------------------------------------------- # Set node-specific parameters # ------------------------------------------------------------------------- # Turn off power domain to improve the speed garnet_rtl.update_params({'PWR_AWARE': False}) garnet_rtl.update_params({'array_width': parameters['array_width']}) garnet_rtl.update_params({'array_height': parameters['array_height']}) for step, test in zip(build_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(run_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(run_gls_steps, test_names): step.update_params({'TEST_NAME': test}) for step, test in zip(ptpx_steps, test_names): step.update_params({'TEST_NAME': test}) compile_design.update_params({'CGRA_RD_WS': 4}) # ------------------------------------------------------------------------- # Pre-conditions # ------------------------------------------------------------------------- # 'verdict' requires all tests to have passed verdict.extend_preconditions([ "assert 'TEST PASSED' in File('inputs/" + run_log + "', enable_case_sensitive = True)" for run_log in run_logs ]) # ------------------------------------------------------------------------- # Post-conditions # ------------------------------------------------------------------------- # 'compile_tbench' must be successful compile_design.extend_postconditions([ "assert 'Error' not in File('xrun_compile.log', enable_case_sensitive = True)", "assert File('outputs/xcelium.d')", ]) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'pad_frame', 'clock_period': 20.0, 'adk': adk_name, 'adk_view': adk_view, # # Synthesis 'flatten_effort': 3, 'topographical': False, # # drc # drc_rule_deck: /sim/steveri/runsets/ruleset_icovl # NO GOOD instead do: # cd ../adks/tsmc16-adk/stdview; ln -s /sim/steveri/runsets/ruleset_icovl 'drc_rule_deck': 'ruleset_icovl', } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') init_fullchip = Step(this_dir + '/../common/init-fullchip') # # More custom steps: custom power step (unused) # custom_power = Step( this_dir + '/../common/custom-power-leaf' ) # Some kinda primetime thingy maybe - not using it # genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' ) # Default steps info = Step('info', default=True) # constraints= Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) # power = Step( 'cadence-innovus-power', default=True ) # place = Step( 'cadence-innovus-place', default=True ) # cts = Step( 'cadence-innovus-cts', default=True ) # postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) # route = Step( 'cadence-innovus-route', default=True ) # postroute = Step( 'cadence-innovus-postroute', default=True ) # signoff = Step( 'cadence-innovus-signoff', default=True ) # pt_signoff = Step( 'synopsys-pt-timing-signoff', default=True ) # genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) else: drc = Step('cadence-pegasus-drc', default=True) # lvs = Step( 'mentor-calibre-lvs', default=True ) # debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) # Send in the clones # "init" now builds a gds file for its own drc check "drc_icovl"; # so need a gdsmerge step between the two init_gdsmerge = gdsmerge.clone() init_gdsmerge.set_name('init-gdsmerge') # icovl design-rule check runs after 'init' step drc_icovl = drc.clone() drc_icovl.set_name('drc-icovl') #----------------------------------------------------------------------- # Add extra input edges to innovus steps that need custom tweaks #----------------------------------------------------------------------- # "init" (cadence-innovus-init) inputs are "init_fullchip" outputs init.extend_inputs(init_fullchip.all_outputs()) # Also: 'init' now produces a gds file # for intermediate drc check 'drc-icovl' # by way of intermediate gdsmerge step "init-gdsmerge" init.extend_outputs(["design.gds.gz"]) # # "power" inputs are "custom_power" outputs # power.extend_inputs( custom_power.all_outputs() ) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) # pre_flowsetup => iflow # g.add_step( pre_flowsetup ) g.add_step(iflow) g.add_step(init_fullchip) g.add_step(init) # init => init_gdsmerge => drc_icovl g.add_step(init_gdsmerge) g.add_step(drc_icovl) # g.add_step( power ) # g.add_step( custom_power ) # g.add_step( place ) # g.add_step( cts ) # g.add_step( postcts_hold ) # g.add_step( route ) # g.add_step( postroute ) # g.add_step( signoff ) # g.add_step( pt_signoff ) # # g.add_step( genlibdb_constraints ) # g.add_step( genlibdb ) # g.add_step( gdsmerge ) # g.add_step( drc ) # g.add_step( lvs ) # g.add_step( debugcalibre ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) # g.connect_by_name( adk, pre_flowsetup ) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, init_gdsmerge) g.connect_by_name(adk, drc_icovl) # g.connect_by_name( adk, power ) # g.connect_by_name( adk, place ) # g.connect_by_name( adk, cts ) # g.connect_by_name( adk, postcts_hold ) # g.connect_by_name( adk, route ) # g.connect_by_name( adk, postroute ) # g.connect_by_name( adk, signoff ) # g.connect_by_name( adk, gdsmerge ) # g.connect_by_name( adk, drc ) # g.connect_by_name( adk, lvs ) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) # sr02.2020 b/c now init_fullchip needs io_file from rtl g.connect_by_name(rtl, init_fullchip) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) # g.connect_by_name( dc, power ) # g.connect_by_name( dc, place ) # g.connect_by_name( dc, cts ) # Maybe don't need this no more... # # g.connect_by_name( pre_flowsetup, iflow ) # # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff # for step in pre_flowsetup_followers: # g.connect_by_name( pre_flowsetup, step) g.connect_by_name(iflow, init) # g.connect_by_name( iflow, power ) # g.connect_by_name( iflow, place ) # g.connect_by_name( iflow, cts ) # g.connect_by_name( iflow, postcts_hold ) # g.connect_by_name( iflow, route ) # g.connect_by_name( iflow, postroute ) # g.connect_by_name( iflow, signoff ) # # for step in iflow_followers: # # g.connect_by_name( iflow, step) g.connect_by_name(init_fullchip, init) # g.connect_by_name( custom_power, power ) # init => init_gdsmerge => drc_icovl g.connect_by_name(init, init_gdsmerge) g.connect_by_name(init_gdsmerge, drc_icovl) # g.connect_by_name( init, power ) # g.connect_by_name( power, place ) # g.connect_by_name( place, cts ) # g.connect_by_name( cts, postcts_hold ) # g.connect_by_name( postcts_hold, route ) # g.connect_by_name( route, postroute ) # g.connect_by_name( postroute, signoff ) # g.connect_by_name( signoff, gdsmerge ) # g.connect_by_name( signoff, drc ) # g.connect_by_name( signoff, lvs ) # g.connect_by_name( gdsmerge, drc ) # g.connect_by_name( gdsmerge, lvs ) # g.connect_by_name( signoff, genlibdb ) # g.connect_by_name( adk, genlibdb ) # # g.connect_by_name( genlibdb_constraints, genlibdb ) # g.connect_by_name( adk, pt_signoff ) # g.connect_by_name( signoff, pt_signoff ) # # g.connect_by_name( adk, debugcalibre ) # g.connect_by_name( dc, debugcalibre ) # g.connect_by_name( iflow, debugcalibre ) # g.connect_by_name( signoff, debugcalibre ) # g.connect_by_name( drc, debugcalibre ) # g.connect_by_name( lvs, debugcalibre ) # yes? no? # g.connect_by_name( drc_icovl, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Default order can be found in e.g. # mflowgen/steps/cadence-innovus-init/configure.yml # - main.tcl # - quality-of-life.tcl # - floorplan.tcl # - pin-assignments.tcl # - make-path-groups.tcl # - reporting.tcl # I copied this from someone else, maybe glb_top or something # Looks like this order deletes pin assignments and adds endcaps/welltaps # then maybe get clean(er) post-floorplan drc # # 3/4 swapped order of streamout/align so to get gds *before* icovl init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'alignment-cells.tcl', # Let's try it without the bump routing maybe? # 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'gen-bumps.tcl', 'sealring.tcl', 'innovus-foundation-flow/custom-scripts/stream-out.tcl', 'attach-results-to-outputs.tcl', ] }) # Not sure what this is or why it was commented out... # # Adding new input for genlibdb node to run # genlibdb.update_params( # {'order': "\"read_design.tcl genlibdb-constraints.tcl extract_model.tcl\""} # ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'stdview' parameters = { 'construct_path': __file__, 'design_name': 'GarnetSOC_pad_frame', 'clock_period': 20.0, 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': 3, 'topographical': False, 'express_flow': False, 'skip_verify_connectivity': True, 'lvs_hcells_file': 'inputs/adk/hcells.inc', 'lvs_connect_names': '"VDD VSS VDDPST"' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/rtl') constraints = Step(this_dir + '/constraints') init_fullchip = Step(this_dir + '/../common/init-fullchip') netlist_fixing = Step(this_dir + '/../common/fc-netlist-fixing') # Custom step 'pre-flowsetup' # To get new lef cells e.g. 'icovl-cells.lef' into iflow, we gotta: # - create new step 'pre_flowsetup' whose outputs are icovl cells # -- link via "commands" group in pre-iflow/configure.yml # - connect pre-flowsetup step to flowsetup (iflow) step # - extend iflow inputs to include icovl cells # - iflow "setup.tcl" automatically includes "inputs/*.lef" pre_flowsetup = Step(this_dir + '/pre-flowsetup') # More custom steps custom_power = Step(this_dir + '/../common/custom-power-chip') # It's not plugged in yet! # custom_power = Step( this_dir + '/custom-power' ) # Some kinda primetime thingy maybe # genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' ) # Default steps info = Step('info', default=True) # constraints= Step( 'constraints', default=True ) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) route = Step('cadence-innovus-route', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) drc = Step('mentor-calibre-drc', default=True) init_fill = Step('mentor-calibre-fill', default=True) lvs = Step('mentor-calibre-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Die if unconnected bumps (why was this deleted?) init.extend_postconditions( ["assert 'STILL UNCONNECTED: bump' not in File( 'mflowgen-run.log' )"]) # Send in the clones # 'init' step now gets its own design-rule check init_drc = drc.clone() init_drc.set_name('init-drc') # "init" now builds a gds file for its own drc check "init_drc"; # so need a gdsmerge step between the two init_gdsmerge = gdsmerge.clone() init_gdsmerge.set_name('init-gdsmerge') #----------------------------------------------------------------------- # Add extra input edges to innovus steps that need custom tweaks #----------------------------------------------------------------------- # "init" (cadence-innovus-init) inputs are "init_fullchip" outputs init.extend_inputs(init_fullchip.all_outputs()) # Also: 'init' now produces a gds file # for intermediate drc check 'init-drc' # by way of intermediate gdsmerge step "init-gdsmerge" init.extend_outputs(["design.gds.gz"]) # "power" inputs are "custom_power" outputs power.extend_inputs(custom_power.all_outputs()) signoff.extend_inputs(netlist_fixing.all_outputs()) # Your comment here. # FIXME what about gds??? # iflow (flowsetup) setup.tcl includes all files inputs/*.lef maybe # iflow.extend_inputs( [ "icovl-cells.lef" , "dtcd-cells.lef" ] ) # genlibdb.extend_inputs( genlibdb_constraints.all_outputs() ) # Ouch. iflow and everyone that connects to iflow must also include # the icovl/dtcd lefs I guess? pre_flowsetup_followers = [ # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff iflow, init # can we get away with this? ] for step in pre_flowsetup_followers: step.extend_inputs( ["icovl-cells.lef", "dtcd-cells.lef", "bumpcells.lef"]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(constraints) g.add_step(dc) # pre_flowsetup => iflow g.add_step(pre_flowsetup) g.add_step(iflow) g.add_step(init_fullchip) g.add_step(init) # init => init_gdsmerge => init_drc g.add_step(init_gdsmerge) g.add_step(init_fill) g.add_step(init_drc) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(route) g.add_step(netlist_fixing) g.add_step(signoff) g.add_step(pt_signoff) # g.add_step( genlibdb_constraints ) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(debugcalibre) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, pre_flowsetup) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, init_gdsmerge) g.connect_by_name(adk, init_fill) g.connect_by_name(adk, init_drc) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, route) g.connect_by_name(adk, signoff) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) # sr02.2020 b/c now init_fullchip needs io_file from rtl g.connect_by_name(rtl, init_fullchip) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) # g.connect_by_name( pre_flowsetup, iflow ) # iflow, init, power, place, cts, postcts_hold, route, postroute, signoff for step in pre_flowsetup_followers: g.connect_by_name(pre_flowsetup, step) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, route) g.connect_by_name(iflow, signoff) # for step in iflow_followers: # g.connect_by_name( iflow, step) g.connect_by_name(init_fullchip, init) g.connect_by_name(custom_power, power) # init => init_gdsmerge => init_drc g.connect_by_name(init, init_gdsmerge) g.connect_by_name(init_gdsmerge, init_drc) g.connect(init_gdsmerge.o('design_merged.gds'), init_fill.i('design.gds')) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, route) g.connect_by_name(route, signoff) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, drc) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) # g.connect_by_name( genlibdb_constraints, genlibdb ) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(adk, debugcalibre) g.connect_by_name(dc, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Netlist fixing should be run during signoff g.connect_by_name(netlist_fixing, signoff) # yes? no? # g.connect_by_name( init_drc, debugcalibre ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Default order can be found in e.g. # mflowgen/steps/cadence-innovus-init/configure.yml # - main.tcl # - quality-of-life.tcl # - floorplan.tcl # - pin-assignments.tcl # - make-path-groups.tcl # - reporting.tcl # I copied this from someone else, maybe glb_top or something # Looks like this order deletes pin assignments and adds endcaps/welltaps # then maybe get clean(er) post-floorplan drc # # ?? moved stream-out to *before* alignment-cells so to get pre-icovl gds # FIXME does this mean we're not checking bump-route DRC? # Note "route-phy-bumps" explicitly sources a file "analog-bumps/build-phy-nets.tcl" # 5/2020 moved stream-out to *after* bump routing init.update_params({ 'order': [ 'main.tcl', 'quality-of-life.tcl', 'stylus-compatibility-procs.tcl', 'floorplan.tcl', 'io-fillers.tcl', 'attach-results-to-outputs.tcl', 'alignment-cells.tcl', 'analog-bumps/route-phy-bumps.tcl', 'analog-bumps/bump-connect.tcl', 'gen-bumps.tcl', 'check-bumps.tcl', 'route-bumps.tcl', 'innovus-foundation-flow/custom-scripts/stream-out.tcl', ] }) order = power.get_param('order') order.append('add-endcaps-welltaps.tcl') power.update_params({'order': order}) # Signoff Order order = signoff.get_param('order') index = order.index( 'generate-results.tcl') # Fix netlist before streaming out netlist order.insert(index, 'netlist-fixing.tcl') signoff.update_params({'order': order}) # Not sure what this is or why it was commented out... # # Adding new input for genlibdb node to run # genlibdb.update_params( # {'order': "\"read_design.tcl genlibdb-constraints.tcl extract_model.tcl\""} # ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'freepdk-45nm' adk_view = 'view-standard' parameters = { 'construct_path' : __file__, 'design_name' : 'GcdUnit', 'clock_period' : 2.0, 'adk' : adk_name, 'adk_view' : adk_view, 'topographical' : True, 'saif_instance' : 'GcdUnitTb/GcdUnit_inst' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname( os.path.abspath( __file__ ) ) # ADK step g.set_adk( adk_name ) adk = g.get_adk_step() # Custom steps rtl = Step( this_dir + '/rtl' ) testbench = Step( this_dir + '/testbench') # Default steps info = Step( 'info', default=True ) constraints = Step( 'constraints', default=True ) dc = Step( 'synopsys-dc-synthesis', default=True ) iflow = Step( 'cadence-innovus-flowsetup', default=True ) init = Step( 'cadence-innovus-init', default=True ) power = Step( 'cadence-innovus-power', default=True ) place = Step( 'cadence-innovus-place', default=True ) cts = Step( 'cadence-innovus-cts', default=True ) postcts_hold = Step( 'cadence-innovus-postcts_hold', default=True ) route = Step( 'cadence-innovus-route', default=True ) postroute = Step( 'cadence-innovus-postroute', default=True ) postroute_hold = Step( 'cadence-innovus-postroute_hold', default=True ) signoff = Step( 'cadence-innovus-signoff', default=True ) genlibdb = Step( 'synopsys-ptpx-genlibdb', default=True ) gdsmerge = Step( 'mentor-calibre-gdsmerge', default=True ) drc = Step( 'mentor-calibre-drc', default=True ) lvs = Step( 'mentor-calibre-lvs', default=True ) debugcalibre = Step( 'cadence-innovus-debug-calibre', default=True ) vcs_sim = Step( 'synopsys-vcs-sim', default=True ) power_est = Step( 'synopsys-pt-power', default=True ) formal_verif = Step( 'synopsys-formality-verification', default=True ) #----------------------------------------------------------------------- # Modify Nodes #----------------------------------------------------------------------- vcs_sim.extend_inputs(['test_vectors.txt']) vcs_sim.update_params(testbench.params()) verif_post_synth = formal_verif.clone() verif_post_synth.set_name('verif_post_synth') verif_post_layout = formal_verif.clone() verif_post_layout.set_name('verif_post_layout') #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step( info ) g.add_step( rtl ) g.add_step( constraints ) g.add_step( dc ) g.add_step( iflow ) g.add_step( init ) g.add_step( power ) g.add_step( place ) g.add_step( cts ) g.add_step( postcts_hold ) g.add_step( route ) g.add_step( postroute ) g.add_step( postroute_hold ) g.add_step( signoff ) g.add_step( genlibdb ) g.add_step( gdsmerge ) g.add_step( drc ) g.add_step( lvs ) g.add_step( debugcalibre ) g.add_step( testbench ) g.add_step( vcs_sim ) g.add_step( power_est ) g.add_step( verif_post_synth ) g.add_step( verif_post_layout ) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Connect by name g.connect_by_name( adk, dc ) g.connect_by_name( adk, iflow ) g.connect_by_name( adk, init ) g.connect_by_name( adk, power ) g.connect_by_name( adk, place ) g.connect_by_name( adk, cts ) g.connect_by_name( adk, postcts_hold ) g.connect_by_name( adk, route ) g.connect_by_name( adk, postroute ) g.connect_by_name( adk, postroute_hold ) g.connect_by_name( adk, signoff ) g.connect_by_name( adk, gdsmerge ) g.connect_by_name( adk, drc ) g.connect_by_name( adk, lvs ) g.connect_by_name( rtl, dc ) g.connect_by_name( constraints, dc ) g.connect_by_name( dc, iflow ) g.connect_by_name( dc, init ) g.connect_by_name( dc, power ) g.connect_by_name( dc, place ) g.connect_by_name( dc, cts ) g.connect_by_name( iflow, init ) g.connect_by_name( iflow, power ) g.connect_by_name( iflow, place ) g.connect_by_name( iflow, cts ) g.connect_by_name( iflow, postcts_hold ) g.connect_by_name( iflow, route ) g.connect_by_name( iflow, postroute ) g.connect_by_name( iflow, postroute_hold ) g.connect_by_name( iflow, signoff ) g.connect_by_name( init, power ) g.connect_by_name( power, place ) g.connect_by_name( place, cts ) g.connect_by_name( cts, postcts_hold ) g.connect_by_name( postcts_hold, route ) g.connect_by_name( route, postroute ) g.connect_by_name( postroute, postroute_hold ) g.connect_by_name( postroute_hold, signoff ) g.connect_by_name( signoff, genlibdb ) g.connect_by_name( adk, genlibdb ) g.connect_by_name( signoff, gdsmerge ) g.connect_by_name( signoff, drc ) g.connect_by_name( gdsmerge, drc ) g.connect_by_name( signoff, lvs ) g.connect_by_name( gdsmerge, lvs ) g.connect_by_name( adk, debugcalibre ) g.connect_by_name( dc, debugcalibre ) g.connect_by_name( iflow, debugcalibre ) g.connect_by_name( signoff, debugcalibre ) g.connect_by_name( drc, debugcalibre ) g.connect_by_name( lvs, debugcalibre ) g.connect_by_name( adk, vcs_sim ) g.connect_by_name( signoff, vcs_sim ) g.connect_by_name( testbench, vcs_sim ) g.connect_by_name( adk, power_est ) g.connect_by_name( signoff, power_est ) g.connect_by_name( vcs_sim, power_est ) g.connect_by_name( adk, verif_post_synth ) g.connect_by_name( dc, verif_post_synth ) g.connect( rtl.o('design.v'), verif_post_synth.i('design.ref.v') ) g.connect( dc.o('design.v'), verif_post_synth.i('design.impl.v') ) g.connect_by_name( adk, verif_post_layout ) g.connect_by_name( dc, verif_post_layout ) g.connect( dc.o('design.v'), verif_post_layout.i('design.ref.v') ) g.connect( signoff.o('design.lvs.v'), verif_post_layout.i('design.impl.v') ) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params( parameters ) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'tsmc16' adk_view = 'multicorner-multivt' pwr_aware = True flatten = 3 os_flatten = os.environ.get('FLATTEN') if os_flatten: flatten = os_flatten # RTL power estimation rtl_power = False if os.environ.get('RTL_POWER') == 'True': pwr_aware = False rtl_power = True # DC power estimation synth_power = False if os.environ.get('SYNTH_POWER') == 'True': synth_power = True pwr_aware = False parameters = { 'construct_path': __file__, 'design_name': 'Tile_PE', 'clock_period': 4, # Change to 250 MHz to match Mem. 'adk': adk_name, 'adk_view': adk_view, # Synthesis 'flatten_effort': flatten, 'topographical': True, # RTL Generation 'interconnect_only': True, # Power Domains 'PWR_AWARE': pwr_aware, 'core_density_target': 0.63, 'saif_instance': 'TilePETb/Tile_PE_inst', 'testbench_name': 'TilePETb', 'strip_path': 'TilePETb/Tile_PE_inst' } #----------------------------------------------------------------------- # Create nodes #----------------------------------------------------------------------- this_dir = os.path.dirname(os.path.abspath(__file__)) # ADK step g.set_adk(adk_name) adk = g.get_adk_step() # Custom steps rtl = Step(this_dir + '/../common/rtl') constraints = Step(this_dir + '/constraints') custom_init = Step(this_dir + '/custom-init') custom_genus_scripts = Step(this_dir + '/custom-genus-scripts') custom_flowgen_setup = Step(this_dir + '/custom-flowgen-setup') custom_power = Step(this_dir + '/../common/custom-power-leaf') genlibdb_constraints = Step(this_dir + '/../common/custom-genlibdb-constraints') custom_timing_assert = Step(this_dir + '/../common/custom-timing-assert') custom_dc_scripts = Step(this_dir + '/custom-dc-scripts') testbench = Step(this_dir + '/testbench') xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim') if rtl_power: rtl_sim = xcelium_sim.clone() rtl_sim.set_name('rtl-sim') pt_power_rtl = Step(this_dir + '/../common/synopsys-ptpx-rtl') rtl_sim.extend_inputs(testbench.all_outputs()) gl_sim = xcelium_sim.clone() gl_sim.set_name('gl-sim') gl_sim.extend_inputs(testbench.all_outputs()) pt_power_gl = Step(this_dir + '/../common/synopsys-ptpx-gl') parse_power_gl = Step(this_dir + '/parse-power-gl') if synth_power: synth_sim = xcelium_sim.clone() synth_sim.set_name('synth-sim') synth_sim.extend_inputs(testbench.all_outputs()) synth_sim.extend_inputs(['design.v']) pt_power_synth = Step(this_dir + '/../common/synopsys-ptpx-synth') # Power aware setup power_domains = None pwr_aware_gls = None if pwr_aware: power_domains = Step(this_dir + '/../common/power-domains') pwr_aware_gls = Step(this_dir + '/../common/pwr-aware-gls') # Default steps info = Step('info', default=True) synth = Step('cadence-genus-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) if synth_power: synth.extend_outputs(['design.spef.gz']) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) signoff = Step('cadence-innovus-signoff', default=True) pt_signoff = Step('synopsys-pt-timing-signoff', default=True) genlibdb = Step('cadence-genus-genlib', default=True) if which("calibre") is not None: drc = Step('mentor-calibre-drc', default=True) lvs = Step('mentor-calibre-lvs', default=True) else: drc = Step('cadence-pegasus-drc', default=True) lvs = Step('cadence-pegasus-lvs', default=True) debugcalibre = Step('cadence-innovus-debug-calibre', default=True) # Add custom timing scripts custom_timing_steps = [synth, postcts_hold, signoff] # connects to these for c_step in custom_timing_steps: c_step.extend_inputs(custom_timing_assert.all_outputs()) # Add extra input edges to innovus steps that need custom tweaks init.extend_inputs(custom_init.all_outputs()) power.extend_inputs(custom_power.all_outputs()) genlibdb.extend_inputs(genlibdb_constraints.all_outputs()) synth.extend_inputs(custom_genus_scripts.all_outputs()) iflow.extend_inputs(custom_flowgen_setup.all_outputs()) # Extra input to DC for constraints synth.extend_inputs([ "common.tcl", "reporting.tcl", "generate-results.tcl", "scenarios.tcl", "report_alu.py", "parse_alu.py" ]) # Extra outputs from DC synth.extend_outputs(["sdc"]) iflow.extend_inputs(["scenarios.tcl", "sdc"]) init.extend_inputs(["sdc"]) power.extend_inputs(["sdc"]) place.extend_inputs(["sdc"]) cts.extend_inputs(["sdc"]) order = synth.get_param('order') order.append('copy_sdc.tcl') synth.set_param('order', order) # Power aware setup if pwr_aware: synth.extend_inputs([ 'designer-interface.tcl', 'upf_Tile_PE.tcl', 'pe-constraints.tcl', 'pe-constraints-2.tcl', 'dc-dont-use-constraints.tcl' ]) init.extend_inputs([ 'upf_Tile_PE.tcl', 'pe-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-pe-floorplan.tcl', 'pe-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'pe-power-switches-setup.tcl', 'add-power-switches.tcl', 'check-clamp-logic-structure.tcl' ]) place.extend_inputs([ 'place-dont-use-constraints.tcl', 'check-clamp-logic-structure.tcl' ]) power.extend_inputs(['pd-globalnetconnect.tcl']) cts.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) postcts_hold.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) route.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) postroute.extend_inputs( ['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl']) signoff.extend_inputs([ 'conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl', 'check-clamp-logic-structure.tcl' ]) pwr_aware_gls.extend_inputs(['design.vcs.pg.v']) gl_sim.extend_inputs(["design.vcs.pg.v"]) #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(testbench) g.add_step(constraints) g.add_step(custom_dc_scripts) g.add_step(synth) g.add_step(custom_timing_assert) g.add_step(custom_genus_scripts) g.add_step(iflow) g.add_step(custom_flowgen_setup) g.add_step(init) g.add_step(custom_init) g.add_step(power) g.add_step(custom_power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(pt_signoff) g.add_step(genlibdb_constraints) g.add_step(genlibdb) g.add_step(drc) g.add_step(lvs) g.add_step(debugcalibre) if rtl_power: g.add_step(rtl_sim) g.add_step(pt_power_rtl) g.add_step(gl_sim) g.add_step(pt_power_gl) g.add_step(parse_power_gl) if synth_power: g.add_step(synth_sim) g.add_step(pt_power_synth) # Power aware step if pwr_aware: g.add_step(power_domains) g.add_step(pwr_aware_gls) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges # Connect by name g.connect_by_name(adk, synth) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(adk, pt_power_gl) if rtl_power: rtl_sim.extend_inputs(['design.v']) g.connect_by_name(adk, rtl_sim) g.connect_by_name(adk, pt_power_rtl) # To generate namemap g.connect_by_name(rtl_sim, dc) # run.saif g.connect_by_name(rtl, rtl_sim) # design.v g.connect_by_name(testbench, rtl_sim) # testbench.sv g.connect_by_name(dc, pt_power_rtl) # design.namemap g.connect_by_name( signoff, pt_power_rtl) # design.vcs.v, design.spef.gz, design.pt.sdc g.connect_by_name(rtl_sim, pt_power_rtl) # run.saif g.connect_by_name(rtl, synth) g.connect_by_name(constraints, synth) g.connect_by_name(custom_genus_scripts, synth) g.connect_by_name(constraints, iflow) g.connect_by_name(custom_dc_scripts, iflow) for c_step in custom_timing_steps: g.connect_by_name(custom_timing_assert, c_step) g.connect_by_name(synth, iflow) g.connect_by_name(synth, init) g.connect_by_name(synth, power) g.connect_by_name(synth, place) g.connect_by_name(synth, cts) g.connect_by_name(synth, custom_flowgen_setup) g.connect_by_name(custom_flowgen_setup, iflow) g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) g.connect_by_name(custom_init, init) g.connect_by_name(custom_power, power) g.connect_by_name(init, power) g.connect_by_name(power, place) g.connect_by_name(place, cts) g.connect_by_name(cts, postcts_hold) g.connect_by_name(postcts_hold, route) g.connect_by_name(route, postroute) g.connect_by_name(postroute, signoff) g.connect_by_name(signoff, drc) g.connect_by_name(signoff, lvs) g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds')) g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds')) g.connect_by_name(signoff, genlibdb) g.connect_by_name(adk, genlibdb) g.connect_by_name(genlibdb_constraints, genlibdb) g.connect_by_name(adk, pt_signoff) g.connect_by_name(signoff, pt_signoff) g.connect_by_name(signoff, pt_power_gl) g.connect_by_name(gl_sim, pt_power_gl) # run.saif g.connect_by_name(adk, gl_sim) g.connect_by_name(signoff, gl_sim) # design.vcs.v, design.spef.gz, design.pt.sdc g.connect_by_name(pt_signoff, gl_sim) # design.sdf g.connect_by_name(testbench, gl_sim) # testbench.sv g.connect_by_name(pt_power_gl, parse_power_gl) # power.hier if synth_power: g.connect_by_name(adk, pt_power_synth) g.connect_by_name(synth, pt_power_synth) g.connect_by_name(synth_sim, pt_power_synth) g.connect_by_name(adk, synth_sim) g.connect_by_name(synth, synth_sim) g.connect_by_name(testbench, synth_sim) g.connect_by_name(adk, debugcalibre) g.connect_by_name(synth, debugcalibre) g.connect_by_name(iflow, debugcalibre) g.connect_by_name(signoff, debugcalibre) g.connect_by_name(drc, debugcalibre) g.connect_by_name(lvs, debugcalibre) # Pwr aware steps: if pwr_aware: g.connect_by_name(power_domains, synth) g.connect_by_name(power_domains, init) g.connect_by_name(power_domains, power) g.connect_by_name(power_domains, place) g.connect_by_name(power_domains, cts) g.connect_by_name(power_domains, postcts_hold) g.connect_by_name(power_domains, route) g.connect_by_name(power_domains, postroute) g.connect_by_name(power_domains, signoff) g.connect_by_name(adk, pwr_aware_gls) g.connect_by_name(signoff, pwr_aware_gls) #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl')) #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) # Add custom timing scripts for c_step in custom_timing_steps: order = c_step.get_param('order') order.append('report-special-timing.tcl') c_step.set_param('order', order) c_step.extend_postconditions([{'pytest': 'inputs/test_timing.py'}]) # Update PWR_AWARE variable synth.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True) if pwr_aware: init.update_params({'flatten_effort': parameters['flatten_effort']}, True) pwr_aware_gls.update_params({'design_name': parameters['design_name']}, True) init.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) place.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) cts.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postcts_hold.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) route.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) postroute.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) signoff.extend_postconditions([ "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )" ]) # Since we are adding an additional input script to the generic Innovus # steps, we modify the order parameter for that node which determines # which scripts get run and when they get run. init.update_params( {'core_density_target': parameters['core_density_target']}, True) # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl' # and 'additional-path-groups' after 'make_path_groups' order = init.get_param('order') # get the default script run order path_group_idx = order.index('make-path-groups.tcl') order.insert(path_group_idx + 1, 'additional-path-groups.tcl') pin_idx = order.index('pin-assignments.tcl') # find pin-assignments.tcl order.insert(pin_idx + 1, 'edge-blockages.tcl') # add here init.update_params({'order': order}) # Adding new input for genlibdb node to run order = genlibdb.get_param('order') # get the default script run order read_idx = order.index('read_design.tcl') # find read_design.tcl order.insert(read_idx + 1, 'genlibdb-constraints.tcl') # add here genlibdb.update_params({'order': order}) # Pwr aware steps: if pwr_aware: # init node order = init.get_param('order') read_idx = order.index('floorplan.tcl') # find floorplan.tcl order.insert(read_idx + 1, 'pe-load-upf.tcl') # add here order.insert(read_idx + 2, 'pd-pe-floorplan.tcl') # add here order.insert(read_idx + 3, 'pe-add-endcaps-welltaps-setup.tcl') # add here order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl') # add here order.insert(read_idx + 5, 'pe-power-switches-setup.tcl') # add here order.insert(read_idx + 6, 'add-power-switches.tcl') # add here order.remove('add-endcaps-welltaps.tcl') order.append('check-clamp-logic-structure.tcl') init.update_params({'order': order}) # power node order = power.get_param('order') order.insert(0, 'pd-globalnetconnect.tcl') # add here order.remove('globalnetconnect.tcl') power.update_params({'order': order}) # place node order = place.get_param('order') read_idx = order.index('main.tcl') # find main.tcl order.insert(read_idx - 1, 'place-dont-use-constraints.tcl') order.append('check-clamp-logic-structure.tcl') place.update_params({'order': order}) # cts node order = cts.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') cts.update_params({'order': order}) # postcts_hold node order = postcts_hold.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postcts_hold.update_params({'order': order}) # route node order = route.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') route.update_params({'order': order}) # postroute node order = postroute.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here order.append('check-clamp-logic-structure.tcl') postroute.update_params({'order': order}) # signoff node order = signoff.get_param('order') order.insert(0, 'conn-aon-cells-vdd.tcl') # add here read_idx = order.index( 'generate-results.tcl') # find generate_results.tcl order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl') order.append('check-clamp-logic-structure.tcl') signoff.update_params({'order': order}) return g
def construct(): g = Graph() #----------------------------------------------------------------------- # Parameters #----------------------------------------------------------------------- adk_name = 'freepdk-45nm' adk_view = 'view-standard' parameters = { 'construct_path': __file__, 'design_name': 'GcdUnit', 'clock_period': 2.0, 'adk': adk_name, 'adk_view': adk_view, 'topographical': True, 'testbench_name': 'GcdUnitTb' } #----------------------------------------------------------------------- # 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') testbench = Step(this_dir + '/testbench') vcs_sim = Step(this_dir + '/synopsys-vcs-sim') rtl_sim = vcs_sim.clone() gl_sim = vcs_sim.clone() rtl_sim.set_name('rtl-sim') gl_sim.set_name('gl-sim') # Default steps info = Step('info', default=True) dc = Step('synopsys-dc-synthesis', default=True) iflow = Step('cadence-innovus-flowsetup', default=True) init = Step('cadence-innovus-init', default=True) power = Step('cadence-innovus-power', default=True) place = Step('cadence-innovus-place', default=True) cts = Step('cadence-innovus-cts', default=True) postcts_hold = Step('cadence-innovus-postcts_hold', default=True) route = Step('cadence-innovus-route', default=True) postroute = Step('cadence-innovus-postroute', default=True) signoff = Step('cadence-innovus-signoff', default=True) genlibdb = Step('synopsys-ptpx-genlibdb', default=True) gdsmerge = Step('mentor-calibre-gdsmerge', default=True) pt_timing = Step('synopsys-pt-timing-signoff', default=True) lvs = Step('mentor-calibre-lvs', default=True) gen_saif = Step('synopsys-vcd2saif-convert', default=True) gen_saif_rtl = gen_saif.clone() gen_saif_gl = gen_saif.clone() gen_saif_rtl.set_name('gen-saif-rtl') gen_saif_gl.set_name('gen-saif-gl') drc = Step('mentor-calibre-drc', default=True) # Not annotating switching activity even on inputs pt_power_rtl = Step('synopsys-ptpx-rtl', default=True) # Not run. GL sim has x's pt_power_gl = Step('synopsys-ptpx-gl', default=True) # To open DRC and LVS results in calibre viewer do: # make debug-[DRC_STEP] or make debug-[LVS_STEP] #----------------------------------------------------------------------- # Graph -- Add nodes #----------------------------------------------------------------------- g.add_step(info) g.add_step(rtl) g.add_step(testbench) g.add_step(rtl_sim) g.add_step(constraints) g.add_step(dc) g.add_step(iflow) g.add_step(init) g.add_step(power) g.add_step(place) g.add_step(cts) g.add_step(postcts_hold) g.add_step(route) g.add_step(postroute) g.add_step(signoff) g.add_step(genlibdb) g.add_step(gdsmerge) g.add_step(drc) g.add_step(lvs) g.add_step(pt_timing) g.add_step(gen_saif_rtl) g.add_step(pt_power_rtl) g.add_step(gl_sim) g.add_step(gen_saif_gl) g.add_step(pt_power_gl) #----------------------------------------------------------------------- # Graph -- Add edges #----------------------------------------------------------------------- # Dynamically add edges rtl_sim.extend_inputs(['design.v']) rtl_sim.extend_inputs(['test_vectors.txt']) # Connect by name g.connect_by_name(adk, dc) g.connect_by_name(adk, iflow) g.connect_by_name(adk, init) g.connect_by_name(adk, power) g.connect_by_name(adk, place) g.connect_by_name(adk, cts) g.connect_by_name(adk, postcts_hold) g.connect_by_name(adk, route) g.connect_by_name(adk, postroute) g.connect_by_name(adk, signoff) g.connect_by_name(adk, genlibdb) g.connect_by_name(adk, gdsmerge) g.connect_by_name(adk, drc) g.connect_by_name(adk, lvs) g.connect_by_name(adk, pt_timing) g.connect_by_name(adk, pt_power_rtl) g.connect_by_name(adk, pt_power_gl) g.connect_by_name(rtl, rtl_sim) # design.v g.connect_by_name(testbench, rtl_sim) # testbench.sv g.connect_by_name(rtl_sim, gen_saif_rtl) # run.vcd g.connect_by_name(rtl, dc) g.connect_by_name(constraints, dc) g.connect_by_name(dc, iflow) g.connect_by_name(dc, init) g.connect_by_name(dc, power) g.connect_by_name(dc, place) g.connect_by_name(dc, cts) g.connect_by_name(dc, pt_power_rtl) # design.namemap g.connect_by_name(iflow, init) g.connect_by_name(iflow, power) g.connect_by_name(iflow, place) g.connect_by_name(iflow, cts) g.connect_by_name(iflow, postcts_hold) g.connect_by_name(iflow, route) g.connect_by_name(iflow, postroute) g.connect_by_name(iflow, signoff) 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, genlibdb) g.connect_by_name(signoff, gdsmerge) g.connect_by_name(signoff, drc) g.connect_by_name(gdsmerge, drc) g.connect_by_name(signoff, lvs) g.connect_by_name(gdsmerge, lvs) g.connect_by_name(signoff, pt_timing) g.connect_by_name(signoff, pt_power_rtl) g.connect_by_name(gen_saif_rtl, pt_power_rtl) # run.saif g.connect_by_name(signoff, pt_power_gl) g.connect_by_name(gen_saif_gl, pt_power_gl) # run.saif g.connect_by_name(adk, gl_sim) g.connect_by_name(signoff, gl_sim) # design.vcs.v g.connect_by_name(pt_timing, gl_sim) # design.sdf g.connect_by_name(testbench, gl_sim) # testbench.sv g.connect_by_name(gl_sim, gen_saif_gl) # run.vcd #----------------------------------------------------------------------- # Parameterize #----------------------------------------------------------------------- g.update_params(parameters) 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