Ejemplo n.º 1
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
Ejemplo n.º 2
0
def construct():

    g = Graph()

    #-----------------------------------------------------------------------
    # Parameters
    #-----------------------------------------------------------------------

    adk_name = 'tsmc16'
    adk_view = 'view-standard'

    parameters = {
        'construct_path': __file__,
        'design_name': 'global_buffer',
        'clock_period': 1.25,
        'adk': adk_name,
        'adk_view': adk_view,
        # Synthesis
        'flatten_effort': 3,
        'topographical': True,
        # hold target slack
        'hold_target_slack': 0.045,
        # array_width = width of CGRA below GLB; `pin-assignments.tcl` uses
        # these parms to set up per-cgra-column ports connecting glb tile
        # signals in glb_top to corresponding CGRA tile columns below glb_top
        'array_width': 32,
        'num_glb_tiles': 16,
        'tool': "VCS",
        # glb tile memory size (unit: KB)
        'glb_tile_mem_size': 256,
        'rtl_testvectors': ["test1", "test2", "test3", "test4"],
        'gls_testvectors': ["test1.pwr", "test2.pwr"]
    }

    #-----------------------------------------------------------------------
    # Create nodes
    #-----------------------------------------------------------------------

    this_dir = os.path.dirname(os.path.abspath(__file__))

    # ADK step

    g.set_adk(adk_name)
    adk = g.get_adk_step()

    # Custom steps

    rtl = Step(this_dir + '/../common/rtl')
    sim_compile = Step(this_dir + '/sim-compile')
    sim_run = Step(this_dir + '/sim-run')
    sim_gl_compile = Step(this_dir + '/sim-gl-compile')
    glb_tile = Step(this_dir + '/glb_tile')
    constraints = Step(this_dir + '/constraints')
    custom_init = Step(this_dir + '/custom-init')
    custom_lvs = Step(this_dir + '/custom-lvs-rules')
    custom_power = Step(this_dir + '/../common/custom-power-hierarchical')
    lib2db = Step(this_dir + '/../common/synopsys-dc-lib2db')

    # Default steps

    info = Step('info', default=True)
    synth = Step('cadence-genus-synthesis', default=True)
    iflow = Step('cadence-innovus-flowsetup', default=True)
    init = Step('cadence-innovus-init', default=True)
    power = Step('cadence-innovus-power', default=True)
    place = Step('cadence-innovus-place', default=True)
    cts = Step('cadence-innovus-cts', default=True)
    postcts_hold = Step('cadence-innovus-postcts_hold', default=True)
    route = Step('cadence-innovus-route', default=True)
    postroute = Step('cadence-innovus-postroute', default=True)
    postroute_hold = Step('cadence-innovus-postroute_hold', default=True)
    signoff = Step('cadence-innovus-signoff', default=True)
    pt_signoff = Step('synopsys-pt-timing-signoff', default=True)
    genlib = Step('cadence-genus-genlib', default=True)
    if which("calibre") is not None:
        drc = Step('mentor-calibre-drc', default=True)
        lvs = Step('mentor-calibre-lvs', default=True)
    else:
        drc = Step('cadence-pegasus-drc', default=True)
        lvs = Step('cadence-pegasus-lvs', default=True)
    debugcalibre = Step('cadence-innovus-debug-calibre', default=True)

    if parameters['tool'] == 'VCS':
        sim_compile.extend_outputs(['simv', 'simv.daidir'])
        sim_gl_compile.extend_outputs(['simv', 'simv.daidir'])
        sim_run.extend_inputs(['simv', 'simv.daidir'])
    elif parameters['tool'] == 'XCELIUM':
        sim_compile.extend_outputs(['xcelium.d'])
        sim_gl_compile.extend_outputs(['xcelium.d'])
        sim_run.extend_inputs(['xcelium.d'])

    sim_gl_run_nodes = {}
    ptpx_gl_nodes = {}
    for test in parameters["gls_testvectors"]:
        sim_gl_run = Step(this_dir + '/sim-gl-run')
        ptpx_gl = Step(this_dir + '/synopsys-ptpx-gl')

        # rename
        sim_gl_run.set_name(f"sim_gl_run_{test}")
        ptpx_gl.set_name(f"ptpx_gl_{test}")
        sim_gl_run_nodes[test] = sim_gl_run
        ptpx_gl_nodes[test] = ptpx_gl
        sim_gl_run.update_params({'test': test}, allow_new=True)
        # Gate-level ptpx node
        ptpx_gl.set_param("strip_path", "top/dut")
        ptpx_gl.extend_inputs(glb_tile.all_outputs())
        if parameters['tool'] == 'VCS':
            sim_gl_run.extend_inputs(['simv', 'simv.daidir'])
        elif parameters['tool'] == 'XCELIUM':
            sim_gl_run.extend_inputs(['xcelium.d'])

    # Add header files to outputs
    rtl.extend_outputs(['header'])
    rtl.extend_postconditions(["assert File( 'outputs/header' ) "])

    # Add (dummy) parameters to the default innovus init step

    init.update_params({'core_width': 0, 'core_height': 0}, allow_new=True)

    # Add glb_tile macro inputs to downstream nodes

    pt_signoff.extend_inputs(['glb_tile_tt.db'])

    # These steps need timing info for glb_tiles
    tile_steps = \
      [ synth, iflow, init, power, place, cts, postcts_hold,
        route, postroute, postroute_hold, signoff, genlib ]

    for step in tile_steps:
        step.extend_inputs(['glb_tile_tt.lib', 'glb_tile.lef'])

    # Need the glb_tile gds to merge into the final layout

    signoff.extend_inputs(['glb_tile.gds'])

    # Need glb_tile lvs.v file for LVS

    lvs.extend_inputs(['glb_tile.lvs.v'])

    # Need sram spice file for LVS

    lvs.extend_inputs(['sram.spi'])

    xlist = synth.get_postconditions()
    xlist = \
      [ _ for _ in xlist if 'percent_clock_gated' not in _ ]
    xlist = synth.set_postconditions(xlist)

    # Add extra input edges to innovus steps that need custom tweaks

    init.extend_inputs(custom_init.all_outputs())
    power.extend_inputs(custom_power.all_outputs())

    #-----------------------------------------------------------------------
    # Graph -- Add nodes
    #-----------------------------------------------------------------------

    g.add_step(info)
    g.add_step(rtl)
    g.add_step(sim_compile)
    g.add_step(sim_run)
    g.add_step(sim_gl_compile)
    g.add_step(glb_tile)
    g.add_step(constraints)
    g.add_step(synth)
    g.add_step(iflow)
    g.add_step(init)
    g.add_step(custom_init)
    g.add_step(power)
    g.add_step(custom_power)
    g.add_step(place)
    g.add_step(cts)
    g.add_step(postcts_hold)
    g.add_step(route)
    g.add_step(postroute)
    g.add_step(postroute_hold)
    g.add_step(signoff)
    g.add_step(pt_signoff)
    g.add_step(genlib)
    g.add_step(lib2db)
    g.add_step(drc)
    g.add_step(lvs)
    g.add_step(custom_lvs)
    g.add_step(debugcalibre)

    for test in parameters["gls_testvectors"]:
        g.add_step(sim_gl_run_nodes[test])
        g.add_step(ptpx_gl_nodes[test])

    #-----------------------------------------------------------------------
    # Graph -- Add edges
    #-----------------------------------------------------------------------

    # Connect by name

    g.connect_by_name(adk, synth)
    g.connect_by_name(adk, iflow)
    g.connect_by_name(adk, init)
    g.connect_by_name(adk, power)
    g.connect_by_name(adk, place)
    g.connect_by_name(adk, cts)
    g.connect_by_name(adk, postcts_hold)
    g.connect_by_name(adk, route)
    g.connect_by_name(adk, postroute)
    g.connect_by_name(adk, postroute_hold)
    g.connect_by_name(adk, signoff)
    g.connect_by_name(adk, drc)
    g.connect_by_name(adk, lvs)

    g.connect_by_name(glb_tile, synth)
    g.connect_by_name(glb_tile, iflow)
    g.connect_by_name(glb_tile, init)
    g.connect_by_name(glb_tile, power)
    g.connect_by_name(glb_tile, place)
    g.connect_by_name(glb_tile, cts)
    g.connect_by_name(glb_tile, postcts_hold)
    g.connect_by_name(glb_tile, route)
    g.connect_by_name(glb_tile, postroute)
    g.connect_by_name(glb_tile, postroute_hold)
    g.connect_by_name(glb_tile, signoff)
    g.connect_by_name(glb_tile, pt_signoff)
    g.connect_by_name(glb_tile, genlib)
    g.connect_by_name(glb_tile, drc)
    g.connect_by_name(glb_tile, lvs)

    g.connect_by_name(rtl, sim_compile)
    g.connect_by_name(sim_compile, sim_run)

    g.connect_by_name(rtl, synth)
    g.connect_by_name(constraints, synth)

    # glb_tile can use the same rtl as glb_top
    g.connect_by_name(rtl, glb_tile)

    g.connect_by_name(synth, iflow)
    g.connect_by_name(synth, init)
    g.connect_by_name(synth, power)
    g.connect_by_name(synth, place)
    g.connect_by_name(synth, cts)

    g.connect_by_name(iflow, init)
    g.connect_by_name(iflow, power)
    g.connect_by_name(iflow, place)
    g.connect_by_name(iflow, cts)
    g.connect_by_name(iflow, postcts_hold)
    g.connect_by_name(iflow, route)
    g.connect_by_name(iflow, postroute)
    g.connect_by_name(iflow, postroute_hold)
    g.connect_by_name(iflow, signoff)

    g.connect_by_name(custom_init, init)
    g.connect_by_name(custom_power, power)
    g.connect_by_name(custom_lvs, lvs)

    g.connect_by_name(init, power)
    g.connect_by_name(power, place)
    g.connect_by_name(place, cts)
    g.connect_by_name(cts, postcts_hold)
    g.connect_by_name(postcts_hold, route)
    g.connect_by_name(route, postroute)
    g.connect_by_name(postroute, postroute_hold)
    g.connect_by_name(postroute_hold, signoff)
    g.connect_by_name(signoff, drc)
    g.connect_by_name(signoff, lvs)
    g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds'))
    g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds'))

    g.connect_by_name(adk, pt_signoff)
    g.connect_by_name(signoff, pt_signoff)

    g.connect_by_name(adk, genlib)
    g.connect_by_name(signoff, genlib)

    g.connect_by_name(rtl, sim_gl_compile)
    g.connect_by_name(adk, sim_gl_compile)
    g.connect_by_name(glb_tile, sim_gl_compile)
    g.connect_by_name(signoff, sim_gl_compile)

    for test in parameters["gls_testvectors"]:
        g.connect_by_name(sim_gl_compile, sim_gl_run_nodes[test])

    for test in parameters["gls_testvectors"]:
        g.connect_by_name(adk, ptpx_gl_nodes[test])
        g.connect_by_name(glb_tile, ptpx_gl_nodes[test])
        g.connect_by_name(signoff, ptpx_gl_nodes[test])
        g.connect_by_name(sim_gl_run_nodes[test], ptpx_gl_nodes[test])

    g.connect_by_name(genlib, lib2db)

    g.connect_by_name(adk, debugcalibre)
    g.connect_by_name(synth, debugcalibre)
    g.connect_by_name(iflow, debugcalibre)
    g.connect_by_name(signoff, debugcalibre)
    g.connect_by_name(drc, debugcalibre)
    g.connect_by_name(lvs, debugcalibre)

    #-----------------------------------------------------------------------
    # Parameterize
    #-----------------------------------------------------------------------

    g.update_params(parameters)

    # Since we are adding an additional input script to the generic Innovus
    # steps, we modify the order parameter for that node which determines
    # which scripts get run and when they get run.

    # rtl parameters update
    rtl.update_params({'glb_only': True}, allow_new=True)

    # pin assignment parameters update
    init.update_params({'array_width': parameters['array_width']},
                       allow_new=True)
    init.update_params({'num_glb_tiles': parameters['num_glb_tiles']},
                       allow_new=True)

    # Change nthreads
    synth.update_params({'nthreads': 4})
    iflow.update_params({'nthreads': 4})

    order = init.get_param('order')  # get the default script run order
    reporting_idx = order.index('reporting.tcl')  # find reporting.tcl
    # Add dont-touch before reporting
    order.insert(reporting_idx, 'dont-touch.tcl')
    init.update_params({'order': order})

    # Increase hold slack on postroute_hold step
    postroute_hold.update_params(
        {'hold_target_slack': parameters['hold_target_slack']}, allow_new=True)

    # useful_skew
    cts.update_params({'useful_skew': False}, allow_new=True)

    return g
Ejemplo n.º 3
0
def construct():

    g = Graph()

    #-----------------------------------------------------------------------
    # Parameters
    #-----------------------------------------------------------------------

    adk_name = 'tsmc16'
    adk_view = 'multivt'

    parameters = {
        'construct_path': __file__,
        'design_name': 'Interconnect',
        'clock_period': 1.1,
        'adk': adk_name,
        'adk_view': adk_view,
        # Synthesis
        'flatten_effort': 3,
        'topographical': True,
        # RTL Generation
        'array_width': 32,
        'array_height': 16,
        'interconnect_only': False,
        # Power Domains
        'PWR_AWARE': True,
        # Useful Skew (CTS)
        'useful_skew': False,
        # hold target slack
        'hold_target_slack': 0.015,
        # Pipeline stage insertion
        'pipeline_config_interval': 8,
        'pipeline_stage_height': 30,
        # Testing
        'testbench_name': 'Interconnect_tb',
        # I am defaulting to True because nothing is worse than finishing
        # a sim and needing the wave but not having it...
        'waves': True,
    }

    #-----------------------------------------------------------------------
    # Create nodes
    #-----------------------------------------------------------------------

    this_dir = os.path.dirname(os.path.abspath(__file__))

    # ADK step

    g.set_adk(adk_name)
    adk = g.get_adk_step()

    # Custom steps

    rtl = Step(this_dir + '/../common/rtl')
    Tile_MemCore = Step(this_dir + '/Tile_MemCore')
    Tile_PE = Step(this_dir + '/Tile_PE')
    constraints = Step(this_dir + '/constraints')
    dc_postcompile = Step(this_dir + '/custom-dc-postcompile')
    custom_init = Step(this_dir + '/custom-init')
    custom_power = Step(this_dir + '/../common/custom-power-hierarchical')
    custom_cts = Step(this_dir + '/custom-cts-overrides')
    custom_lvs = Step(this_dir + '/custom-lvs-rules')
    gls_args = Step(this_dir + '/gls_args')
    testbench = Step(this_dir + '/testbench')
    lib2db = Step(this_dir + '/../common/synopsys-dc-lib2db')

    # Default steps

    info = Step('info', default=True)
    #constraints    = Step( 'constraints',                    default=True )
    #dc             = Step( 'synopsys-dc-synthesis',          default=True )
    synth = Step('cadence-genus-synthesis', default=True)
    iflow = Step('cadence-innovus-flowsetup', default=True)
    init = Step('cadence-innovus-init', default=True)
    power = Step('cadence-innovus-power', default=True)
    place = Step('cadence-innovus-place', default=True)
    cts = Step('cadence-innovus-cts', default=True)
    postcts_hold = Step('cadence-innovus-postcts_hold', default=True)
    route = Step('cadence-innovus-route', default=True)
    postroute = Step('cadence-innovus-postroute', default=True)
    postroute_hold = Step('cadence-innovus-postroute_hold', default=True)
    signoff = Step('cadence-innovus-signoff', default=True)
    pt_signoff = Step('synopsys-pt-timing-signoff', default=True)
    #genlibdb       = Step( 'synopsys-ptpx-genlibdb',         default=True )
    genlib = Step('cadence-genus-genlib', default=True)
    if which("calibre") is not None:
        drc = Step('mentor-calibre-drc', default=True)
        lvs = Step('mentor-calibre-lvs', default=True)
    else:
        drc = Step('cadence-pegasus-drc', default=True)
        lvs = Step('cadence-pegasus-lvs', default=True)
    debugcalibre = Step('cadence-innovus-debug-calibre', default=True)
    vcs_sim = Step('synopsys-vcs-sim', default=True)

    # Add cgra tile macro inputs to downstream nodes

    #dc.extend_inputs( ['Tile_PE.db'] )
    synth.extend_inputs(['Tile_PE_tt.lib'])
    #dc.extend_inputs( ['Tile_MemCore.db'] )
    synth.extend_inputs(['Tile_MemCore_tt.lib'])
    pt_signoff.extend_inputs(['Tile_PE_tt.db'])
    pt_signoff.extend_inputs(['Tile_MemCore_tt.db'])
    #genlibdb.extend_inputs( ['Tile_PE.db'] )
    genlib.extend_inputs(['Tile_PE_tt.lib'])
    #genlibdb.extend_inputs( ['Tile_MemCore.db'] )
    genlib.extend_inputs(['Tile_MemCore_tt.lib'])

    e2e_apps = [
        "tests/conv_3_3", "apps/cascade", "apps/harris_auto",
        "apps/resnet_i1_o1_mem", "apps/resnet_i1_o1_pond"
    ]

    # Only use these steps with power domains off and no flattening...
    use_e2e = True
    e2e_tb_nodes = {}
    e2e_sim_nodes = {}
    e2e_power_nodes = {}
    if use_e2e:
        for app in e2e_apps:
            e2e_testbench = Step(this_dir + '/e2e_testbench')
            e2e_xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim')
            e2e_ptpx_gl = Step(this_dir + '/../common/synopsys-ptpx-gl')
            # Simple rename
            app_name = app.split("/")[1]
            e2e_testbench.set_name(f"e2e_testbench_{app_name}")
            e2e_xcelium_sim.set_name(f"e2e_xcelium_sim_{app_name}")
            e2e_ptpx_gl.set_name(f"e2e_ptpx_gl_{app_name}")
            e2e_tb_nodes[app] = e2e_testbench
            e2e_sim_nodes[app] = e2e_xcelium_sim
            e2e_power_nodes[app] = e2e_ptpx_gl

            # override app_to_run param of the testbench gen
            e2e_testbench.set_param("app_to_run", app)

            # Send all the relevant post-pnr files to sim
            e2e_xcelium_sim.extend_inputs(Tile_MemCore.all_outputs())
            e2e_xcelium_sim.extend_inputs(Tile_PE.all_outputs())
            e2e_xcelium_sim.extend_inputs(['design.vcs.pg.v'])
            e2e_xcelium_sim.extend_inputs(['input.raw'])

            # Configure the ptpx step a little differently...
            e2e_ptpx_gl.set_param("strip_path", "Interconnect_tb/dut")
            e2e_ptpx_gl.extend_inputs(e2e_testbench.all_outputs())
            e2e_ptpx_gl.extend_inputs(Tile_MemCore.all_outputs())
            e2e_ptpx_gl.extend_inputs(Tile_PE.all_outputs())

    # These steps need timing info for cgra tiles
    tile_steps = \
      [ iflow, init, power, place, cts, postcts_hold,
        route, postroute, signoff ]

    for step in tile_steps:
        step.extend_inputs(['Tile_PE_tt.lib', 'Tile_PE.lef'])
        step.extend_inputs(['Tile_MemCore_tt.lib', 'Tile_MemCore.lef'])

    # Need the netlist and SDF files for gate-level sim

    vcs_sim.extend_inputs(['Tile_PE.vcs.v', 'Tile_PE.sdf'])
    vcs_sim.extend_inputs(['Tile_MemCore.vcs.v', 'Tile_MemCore.sdf'])

    # Need the cgra tile gds's to merge into the final layout

    signoff.extend_inputs(['Tile_PE.gds'])
    signoff.extend_inputs(['Tile_MemCore.gds'])

    # Need LVS verilog files for both tile types to do LVS

    lvs.extend_inputs(['Tile_PE.lvs.v'])
    lvs.extend_inputs(['Tile_MemCore.lvs.v'])

    # Need sram spice file for LVS

    lvs.extend_inputs(['sram.spi'])

    # Extra dc inputs
    #dc.extend_inputs( dc_postcompile.all_outputs() )
    #synth.extend_inputs( dc_postcompile.all_outputs() )

    # Add extra input edges to innovus steps that need custom tweaks

    init.extend_inputs(custom_init.all_outputs())
    power.extend_inputs(custom_power.all_outputs())

    cts.extend_inputs(custom_cts.all_outputs())

    #-----------------------------------------------------------------------
    # Graph -- Add nodes
    #-----------------------------------------------------------------------

    g.add_step(info)
    g.add_step(rtl)
    g.add_step(Tile_MemCore)
    g.add_step(Tile_PE)
    g.add_step(constraints)
    g.add_step(dc_postcompile)
    g.add_step(synth)
    g.add_step(iflow)
    g.add_step(init)
    g.add_step(custom_init)
    g.add_step(power)
    g.add_step(custom_power)
    g.add_step(place)
    g.add_step(custom_cts)
    g.add_step(cts)
    g.add_step(postcts_hold)
    g.add_step(route)
    g.add_step(postroute)
    g.add_step(postroute_hold)
    g.add_step(signoff)
    g.add_step(pt_signoff)
    g.add_step(genlib)
    g.add_step(lib2db)
    g.add_step(drc)
    g.add_step(custom_lvs)
    g.add_step(lvs)
    g.add_step(debugcalibre)
    g.add_step(gls_args)
    g.add_step(testbench)
    g.add_step(vcs_sim)

    if use_e2e:
        for app in e2e_apps:
            g.add_step(e2e_tb_nodes[app])
            g.add_step(e2e_sim_nodes[app])
            g.add_step(e2e_power_nodes[app])
    #-----------------------------------------------------------------------
    # Graph -- Add edges
    #-----------------------------------------------------------------------

    # Connect by name

    g.connect_by_name(adk, synth)
    g.connect_by_name(adk, iflow)
    g.connect_by_name(adk, init)
    g.connect_by_name(adk, power)
    g.connect_by_name(adk, place)
    g.connect_by_name(adk, cts)
    g.connect_by_name(adk, postcts_hold)
    g.connect_by_name(adk, route)
    g.connect_by_name(adk, postroute)
    g.connect_by_name(adk, postroute_hold)
    g.connect_by_name(adk, signoff)
    g.connect_by_name(adk, drc)
    g.connect_by_name(adk, lvs)

    if use_e2e:
        for app in e2e_apps:
            g.connect_by_name(adk, e2e_sim_nodes[app])
            g.connect_by_name(Tile_MemCore, e2e_sim_nodes[app])
            g.connect_by_name(Tile_PE, e2e_sim_nodes[app])
            g.connect_by_name(e2e_tb_nodes[app], e2e_sim_nodes[app])
            g.connect_by_name(signoff, e2e_sim_nodes[app])

            g.connect_by_name(adk, e2e_power_nodes[app])
            g.connect_by_name(Tile_MemCore, e2e_power_nodes[app])
            g.connect_by_name(Tile_PE, e2e_power_nodes[app])
            g.connect_by_name(signoff, e2e_power_nodes[app])
            g.connect_by_name(e2e_tb_nodes[app], e2e_power_nodes[app])
            g.connect_by_name(e2e_sim_nodes[app], e2e_power_nodes[app])
    # In our CGRA, the tile pattern is:
    # PE PE PE Mem PE PE PE Mem ...
    # Thus, if there are < 4 columns, the the array won't contain any
    # memory tiles. If this is the case, we don't need to run the
    # memory tile flow.
    if parameters['array_width'] > 3:
        # inputs to Tile_MemCore
        g.connect_by_name(rtl, Tile_MemCore)
        # outputs from Tile_MemCore
        #g.connect_by_name( Tile_MemCore,      dc             )
        g.connect_by_name(Tile_MemCore, synth)
        g.connect_by_name(Tile_MemCore, iflow)
        g.connect_by_name(Tile_MemCore, init)
        g.connect_by_name(Tile_MemCore, power)
        g.connect_by_name(Tile_MemCore, place)
        g.connect_by_name(Tile_MemCore, cts)
        g.connect_by_name(Tile_MemCore, postcts_hold)
        g.connect_by_name(Tile_MemCore, route)
        g.connect_by_name(Tile_MemCore, postroute)
        g.connect_by_name(Tile_MemCore, postroute_hold)
        g.connect_by_name(Tile_MemCore, signoff)
        g.connect_by_name(Tile_MemCore, pt_signoff)
        #g.connect_by_name( Tile_MemCore,      genlibdb       )
        g.connect_by_name(Tile_MemCore, genlib)
        g.connect_by_name(Tile_MemCore, drc)
        g.connect_by_name(Tile_MemCore, lvs)
        # These rules LVS BOX the SRAM macro, so they should
        # only be used if memory tile is present
        g.connect_by_name(custom_lvs, lvs)
        g.connect_by_name(Tile_MemCore, vcs_sim)

    # inputs to Tile_PE
    g.connect_by_name(rtl, Tile_PE)
    # outputs from Tile_PE
    #g.connect_by_name( Tile_PE,      dc             )
    g.connect_by_name(Tile_PE, synth)
    g.connect_by_name(Tile_PE, iflow)
    g.connect_by_name(Tile_PE, init)
    g.connect_by_name(Tile_PE, power)
    g.connect_by_name(Tile_PE, place)
    g.connect_by_name(Tile_PE, cts)
    g.connect_by_name(Tile_PE, postcts_hold)
    g.connect_by_name(Tile_PE, route)
    g.connect_by_name(Tile_PE, postroute)
    g.connect_by_name(Tile_PE, postroute_hold)
    g.connect_by_name(Tile_PE, signoff)
    g.connect_by_name(Tile_PE, pt_signoff)
    #g.connect_by_name( Tile_PE,      genlibdb       )
    g.connect_by_name(Tile_PE, genlib)
    g.connect_by_name(Tile_PE, drc)
    g.connect_by_name(Tile_PE, lvs)

    #g.connect_by_name( rtl,            dc        )
    #g.connect_by_name( constraints,    dc        )
    #g.connect_by_name( dc_postcompile, dc        )

    #g.connect_by_name( dc,       iflow        )
    #g.connect_by_name( dc,       init         )
    #g.connect_by_name( dc,       power        )
    #g.connect_by_name( dc,       place        )
    #g.connect_by_name( dc,       cts          )

    g.connect_by_name(rtl, synth)
    g.connect_by_name(rtl, synth)
    g.connect_by_name(constraints, synth)
    #g.connect_by_name( dc_postcompile, synth        )

    g.connect_by_name(synth, iflow)
    g.connect_by_name(synth, init)
    g.connect_by_name(synth, power)
    g.connect_by_name(synth, place)
    g.connect_by_name(synth, cts)

    g.connect_by_name(iflow, init)
    g.connect_by_name(iflow, power)
    g.connect_by_name(iflow, place)
    g.connect_by_name(iflow, cts)
    g.connect_by_name(iflow, postcts_hold)
    g.connect_by_name(iflow, route)
    g.connect_by_name(iflow, postroute)
    g.connect_by_name(iflow, postroute_hold)
    g.connect_by_name(iflow, signoff)

    g.connect_by_name(custom_init, init)
    g.connect_by_name(custom_power, power)
    g.connect_by_name(custom_cts, cts)

    g.connect_by_name(init, power)
    g.connect_by_name(power, place)
    g.connect_by_name(place, cts)
    g.connect_by_name(cts, postcts_hold)
    g.connect_by_name(postcts_hold, route)
    g.connect_by_name(route, postroute)
    g.connect_by_name(postroute, postroute_hold)
    g.connect_by_name(postroute_hold, signoff)
    g.connect_by_name(signoff, drc)
    g.connect_by_name(signoff, lvs)
    g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds'))
    g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds'))

    g.connect_by_name(adk, pt_signoff)
    g.connect_by_name(signoff, pt_signoff)

    #g.connect_by_name( adk,          genlibdb   )
    g.connect_by_name(adk, genlib)
    #g.connect_by_name( signoff,      genlibdb   )
    g.connect_by_name(signoff, genlib)

    g.connect_by_name(genlib, lib2db)

    g.connect_by_name(adk, debugcalibre)
    #g.connect_by_name( dc,       debugcalibre )
    g.connect_by_name(synth, debugcalibre)
    g.connect_by_name(iflow, debugcalibre)
    g.connect_by_name(signoff, debugcalibre)
    g.connect_by_name(drc, debugcalibre)
    g.connect_by_name(lvs, debugcalibre)

    g.connect_by_name(adk, vcs_sim)
    g.connect_by_name(testbench, vcs_sim)
    g.connect_by_name(gls_args, vcs_sim)
    g.connect_by_name(signoff, vcs_sim)
    g.connect_by_name(Tile_PE, vcs_sim)

    #-----------------------------------------------------------------------
    # Parameterize
    #-----------------------------------------------------------------------

    g.update_params(parameters)

    # Init needs pipeline params for floorplanning
    init.update_params(
        {'pipeline_config_interval': parameters['pipeline_config_interval']},
        True)
    init.update_params(
        {'pipeline_stage_height': parameters['pipeline_stage_height']}, True)

    # CTS uses height/width param to do CTS endpoint overrides properly
    cts.update_params({'array_width': parameters['array_width']}, True)
    cts.update_params({'array_height': parameters['array_height']}, True)

    # Since we are adding an additional input script to the generic Innovus
    # steps, we modify the order parameter for that node which determines
    # which scripts get run and when they get run.

    #order = synth.get_param('order')
    #compile_idx = order.index( 'compile.tcl' )
    #order.insert ( compile_idx + 1, 'custom-dc-postcompile.tcl' )
    #dc.update_params( { 'order': order } )
    #synth.update_params( { 'order': order } )

    # genlibdb -- Remove 'report-interface-timing.tcl' beacuse it takes
    # very long and is not necessary
    #order = genlibdb.get_param('order')
    #order.remove( 'write-interface-timing.tcl' )
    #genlibdb.update_params( { 'order': order } )

    # init -- Add 'dont-touch.tcl' before reporting

    order = init.get_param('order')  # get the default script run order
    reporting_idx = order.index('reporting.tcl')  # find reporting.tcl
    # Add dont-touch before reporting
    order.insert(reporting_idx, 'dont-touch.tcl')
    init.update_params({'order': order})

    # We are overriding certain pin types for CTS, so we need to
    # add the script that does that to the CTS order
    order = cts.get_param('order')
    main_idx = order.index('main.tcl')
    order.insert(main_idx, 'cts-overrides.tcl')
    cts.update_params({'order': order})

    # Remove
    #dc_postconditions = dc.get_postconditions()
    #for postcon in dc_postconditions:
    #    if 'percent_clock_gated' in postcon:
    #        dc_postconditions.remove(postcon)
    #dc.set_postconditions( dc_postconditions )

    synth_postconditions = synth.get_postconditions()
    for postcon in synth_postconditions:
        if 'percent_clock_gated' in postcon:
            synth_postconditions.remove(postcon)
    synth.set_postconditions(synth_postconditions)

    return g
Ejemplo n.º 4
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