예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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