Esempio n. 1
0
def construct():

    g = Graph()

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

    adk_name = 'tsmc16'
    adk_view = 'multicorner-multivt'
    pwr_aware = True

    parameters = {
        'construct_path': __file__,
        'design_name': 'Tile_MemCore',
        # 'clock_period'        : 1.1,    # 900MHz never finishes AFAICT
        # 'clock_period'        : 1.25,   # 800MHz requires > ten hours
        'clock_period': 4.0,  # 250MHz finishes in three hours
        'adk': adk_name,
        'adk_view': adk_view,
        # Synthesis
        'flatten_effort': 3,
        'topographical': True,
        # SRAM macros
        'num_words': 512,
        'word_size': 32,
        'mux_size': 4,
        'corner': "tt0p8v25c",
        'bc_corner': "ffg0p88v125c",
        'partial_write': False,
        # Utilization target
        'core_density_target': 0.74,
        # RTL Generation
        'interconnect_only': True,
        # Power Domains
        'PWR_AWARE': pwr_aware,
        'testbench_name': 'Interconnect_tb',
        'gl_strip_path': 'Interconnect_tb/dut'
    }

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

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

    # ADK step

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

    # Custom steps
    rtl = Step(this_dir + '/../common/rtl')
    genlibdb_constraints = Step(this_dir +
                                '/../common/custom-genlibdb-constraints')
    constraints = Step(this_dir + '/constraints')
    gen_sram = Step(this_dir + '/../common/gen_sram_macro')
    custom_init = Step(this_dir + '/custom-init')
    custom_genus_scripts = Step(this_dir + '/custom-genus-scripts')
    custom_flowgen_setup = Step(this_dir + '/custom-flowgen-setup')
    custom_lvs = Step(this_dir + '/custom-lvs-rules')
    custom_power = Step(this_dir + '/../common/custom-power-leaf')
    gen_testbench = Step(this_dir + '/gen_testbench')
    gl_sim = Step(this_dir + '/custom-vcs-sim')
    gl_power = Step(this_dir + '/../common/synopsys-ptpx-gl')
    xcelium_sim = Step(this_dir + '/../common/cadence-xcelium-sim')

    # Power aware setup
    if pwr_aware:
        power_domains = Step(this_dir + '/../common/power-domains')
        pwr_aware_gls = Step(this_dir + '/../common/pwr-aware-gls')

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

    # Extra DC input
    synth.extend_inputs(["common.tcl"])
    synth.extend_inputs(["simple_common.tcl"])

    # Add sram macro inputs to downstream nodes

    synth.extend_inputs(['sram_tt.lib', 'sram.lef'])
    #pt_signoff.extend_inputs( ['sram_tt.db'] )
    genlibdb.extend_inputs(['sram_tt.lib'])

    # These steps need timing and lef info for srams

    sram_steps = \
      [iflow, init, power, place, cts, postcts_hold, route, postroute, postroute_hold, signoff]
    for step in sram_steps:
        step.extend_inputs(['sram_tt.lib', 'sram_ff.lib', 'sram.lef'])

    # Need the sram gds to merge into the final layout

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

    # Need SRAM spice file for LVS

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

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

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

    # Add extra input edges to genlibdb for loop-breaking constraints

    genlibdb.extend_inputs(genlibdb_constraints.all_outputs())
    synth.extend_inputs(custom_genus_scripts.all_outputs())
    iflow.extend_inputs(custom_flowgen_setup.all_outputs())

    synth.extend_outputs(["sdc"])
    iflow.extend_inputs(["sdc"])
    init.extend_inputs(["sdc"])
    power.extend_inputs(["sdc"])
    place.extend_inputs(["sdc"])
    cts.extend_inputs(["sdc"])

    xcelium_sim.extend_inputs(
        ["array_rtl.v", "CW_fp_mult.v", "CW_fp_add.v", "sram.v"])

    order = synth.get_param('order')
    order.append('copy_sdc.tcl')
    synth.set_param('order', order)

    # Power aware setup
    if pwr_aware:
        synth.extend_inputs([
            'designer-interface.tcl', 'upf_Tile_MemCore.tcl',
            'mem-constraints.tcl', 'mem-constraints-2.tcl',
            'dc-dont-use-constraints.tcl'
        ])
        init.extend_inputs([
            'check-clamp-logic-structure.tcl', 'upf_Tile_MemCore.tcl',
            'mem-load-upf.tcl', 'dont-touch-constraints.tcl',
            'pd-mem-floorplan.tcl', 'mem-add-endcaps-welltaps-setup.tcl',
            'pd-add-endcaps-welltaps.tcl', 'mem-power-switches-setup.tcl',
            'add-power-switches.tcl'
        ])
        place.extend_inputs([
            'check-clamp-logic-structure.tcl', 'place-dont-use-constraints.tcl'
        ])
        power.extend_inputs(['pd-globalnetconnect.tcl'])
        cts.extend_inputs(
            ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl'])
        postcts_hold.extend_inputs(
            ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl'])
        route.extend_inputs(
            ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl'])
        postroute.extend_inputs(
            ['check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl'])
        postroute_hold.extend_inputs(['conn-aon-cells-vdd.tcl'])
        signoff.extend_inputs([
            'check-clamp-logic-structure.tcl', 'conn-aon-cells-vdd.tcl',
            'pd-generate-lvs-netlist.tcl'
        ])
        pwr_aware_gls.extend_inputs(['design.vcs.pg.v', 'sram_pwr.v'])
    #-----------------------------------------------------------------------
    # Graph -- Add nodes
    #-----------------------------------------------------------------------

    g.add_step(info)
    g.add_step(rtl)
    g.add_step(gen_sram)
    g.add_step(constraints)
    g.add_step(synth)
    g.add_step(custom_genus_scripts)
    g.add_step(iflow)
    g.add_step(custom_flowgen_setup)
    g.add_step(init)
    g.add_step(custom_init)
    g.add_step(power)
    g.add_step(custom_power)
    g.add_step(place)
    g.add_step(cts)
    g.add_step(postcts_hold)
    g.add_step(route)
    g.add_step(postroute)
    g.add_step(postroute_hold)
    g.add_step(signoff)
    g.add_step(pt_signoff)
    g.add_step(genlibdb_constraints)
    g.add_step(genlibdb)
    g.add_step(drc)
    g.add_step(lvs)
    g.add_step(custom_lvs)
    g.add_step(debugcalibre)

    g.add_step(gen_testbench)
    g.add_step(gl_sim)
    g.add_step(gl_power)

    g.add_step(xcelium_sim)

    # Power aware step
    if pwr_aware:
        g.add_step(power_domains)
        g.add_step(pwr_aware_gls)

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

    # Connect by name

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

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

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

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

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

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

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

    g.connect_by_name(signoff, genlibdb)
    g.connect_by_name(adk, genlibdb)
    g.connect_by_name(genlibdb_constraints, genlibdb)

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

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

    # Gl sim just needs tb, adk, and outputs from signoff...
    g.connect_by_name(gen_testbench, gl_sim)
    g.connect_by_name(adk, gl_sim)
    g.connect_by_name(signoff, gl_sim)

    # xcelium sim just needs tb, adk, and outputs from signoff...
    g.connect_by_name(gen_testbench, xcelium_sim)
    g.connect_by_name(adk, xcelium_sim)
    g.connect_by_name(signoff, xcelium_sim)
    g.connect_by_name(gen_sram, xcelium_sim)

    # Now hand off the rest of everything to ptpx-gl
    g.connect_by_name(adk, gl_power)
    g.connect_by_name(signoff, gl_power)
    g.connect_by_name(xcelium_sim, gl_power)

    # Pwr aware steps:
    if pwr_aware:
        g.connect_by_name(power_domains, synth)
        g.connect_by_name(power_domains, init)
        g.connect_by_name(power_domains, power)
        g.connect_by_name(power_domains, place)
        g.connect_by_name(power_domains, cts)
        g.connect_by_name(power_domains, postcts_hold)
        g.connect_by_name(power_domains, route)
        g.connect_by_name(power_domains, postroute)
        g.connect_by_name(power_domains, postroute_hold)
        g.connect_by_name(power_domains, signoff)
        g.connect_by_name(adk, pwr_aware_gls)
        g.connect_by_name(gen_sram, pwr_aware_gls)
        g.connect_by_name(signoff, pwr_aware_gls)
        #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl'))

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

    g.update_params(parameters)

    # Update PWR_AWARE variable
    synth.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True)
    init.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True)
    power.update_params({'PWR_AWARE': parameters['PWR_AWARE']}, True)

    gl_power.update_params({'strip_path': parameters['gl_strip_path']}, True)

    if pwr_aware:
        pwr_aware_gls.update_params({'design_name': parameters['design_name']},
                                    True)

        init.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        place.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        cts.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        postcts_hold.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        route.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        postroute.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])
        signoff.extend_postconditions([
            "assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"
        ])

    # Core density target param
    init.update_params(
        {'core_density_target': parameters['core_density_target']}, True)

    # Disable pwr aware flow
    #init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True )
    #power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, allow_new=True  )

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

    # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl'

    order = init.get_param('order')  # get the default script run order
    path_group_idx = order.index('make-path-groups.tcl')
    order.insert(path_group_idx + 1, 'additional-path-groups.tcl')
    pin_idx = order.index('pin-assignments.tcl')  # find pin-assignments.tcl
    order.insert(pin_idx + 1, 'edge-blockages.tcl')  # add here
    init.update_params({'order': order})

    # Adding new input for genlibdb node to run
    order = genlibdb.get_param('order')  # get the default script run order
    read_idx = order.index('read_design.tcl')  # find read_design.tcl
    order.insert(read_idx + 1, 'genlibdb-constraints.tcl')  # add here
    genlibdb.update_params({'order': order})

    # Pwr aware steps:
    if pwr_aware:
        # init node
        order = init.get_param('order')
        read_idx = order.index('floorplan.tcl')  # find floorplan.tcl
        order.insert(read_idx + 1, 'mem-load-upf.tcl')  # add here
        order.insert(read_idx + 2, 'pd-mem-floorplan.tcl')  # add here
        order.insert(read_idx + 3,
                     'mem-add-endcaps-welltaps-setup.tcl')  # add here
        order.insert(read_idx + 4, 'pd-add-endcaps-welltaps.tcl')  # add here
        order.insert(read_idx + 5, 'mem-power-switches-setup.tcl')  # add here
        order.insert(read_idx + 6, 'add-power-switches.tcl')  # add here
        order.remove('add-endcaps-welltaps.tcl')
        order.append('check-clamp-logic-structure.tcl')
        init.update_params({'order': order})

        # power node
        order = power.get_param('order')
        order.insert(0, 'pd-globalnetconnect.tcl')  # add here
        order.remove('globalnetconnect.tcl')
        power.update_params({'order': order})

        # place node
        order = place.get_param('order')
        read_idx = order.index('main.tcl')  # find main.tcl
        order.insert(read_idx - 1, 'place-dont-use-constraints.tcl')
        order.append('check-clamp-logic-structure.tcl')
        place.update_params({'order': order})

        # cts node
        order = cts.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        order.append('check-clamp-logic-structure.tcl')
        cts.update_params({'order': order})

        # postcts_hold node
        order = postcts_hold.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        order.append('check-clamp-logic-structure.tcl')
        postcts_hold.update_params({'order': order})

        # route node
        order = route.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        order.append('check-clamp-logic-structure.tcl')
        route.update_params({'order': order})

        # postroute node
        order = postroute.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        order.append('check-clamp-logic-structure.tcl')
        postroute.update_params({'order': order})

        # postroute-hold node
        order = postroute_hold.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        postroute_hold.update_params({'order': order})

        # signoff node
        order = signoff.get_param('order')
        order.insert(0, 'conn-aon-cells-vdd.tcl')  # add here
        order.append('check-clamp-logic-structure.tcl')
        read_idx = order.index(
            'generate-results.tcl')  # find generate_results.tcl

        order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl')
        signoff.update_params({'order': order})

    return g
Esempio n. 2
0
def construct():

  g = Graph()

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

  adk_name = 'tsmc16'
  adk_view = 'multicorner-multivt'
  pwr_aware = True

  flatten = 3
  if os.environ.get('FLATTEN'):
      flatten = os.environ.get('FLATTEN')

  synth_power = False
  if os.environ.get('SYNTH_POWER') == 'True':
      synth_power = True
  # power domains do not work with post-synth power
  if synth_power:
      pwr_aware = False

  parameters = {
    'construct_path'    : __file__,
    'design_name'       : 'Tile_PE',
    'clock_period'      : 1.1,
    'adk'               : adk_name,
    'adk_view'          : adk_view,
    # Synthesis
    'flatten_effort'    : flatten,
    'topographical'     : True,
    # RTL Generation
    'interconnect_only' : True,
    # Power Domains
    'PWR_AWARE'         : pwr_aware,
    'core_density_target': 0.63,
    # Power analysis
    "use_sdf"           : False, # uses sdf but not the way it is in xrun node
    'app_to_run'        : 'tests/conv_3_3',
    'saif_instance'     : 'testbench/dut',
    'testbench_name'    : 'testbench',
    'strip_path'        : 'testbench/dut'
    }

  # steveri 2101: Hoping this is temporary.
  # But for now, 1.1ns pe tile is too big and full-chip CI test FAILS
  if (os.getenv('USER') == "buildkite-agent"):
      parameters['clock_period'] = 4.0; # 4ns = 250 MHz

  # User-level option to change clock frequency
  # E.g. 'export clock_period_PE="4.0"' to target 250MHz
  # Optionally could restrict to bk only: if (os.getenv('USER') == "buildkite-agent")
  cp=os.getenv('clock_period_PE')
  if (cp != None):
      print("@file_info: WARNING found env var 'clock_period_PE'")
      print("@file_info: WARNING setting PE clock period to '%s'" % cp)
      parameters['clock_period'] = cp;

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

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

  # ADK step

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

  # Custom steps

  rtl                  = Step( this_dir + '/../common/rtl'                         )
  constraints          = Step( this_dir + '/constraints'                           )
  custom_init          = Step( this_dir + '/custom-init'                           )
  custom_genus_scripts = Step( this_dir + '/custom-genus-scripts'                  )
  custom_flowgen_setup = Step( this_dir + '/custom-flowgen-setup'                  )
  custom_power         = Step( this_dir + '/../common/custom-power-leaf'           )
  short_fix            = Step( this_dir + '/../common/custom-short-fix'  )
  genlibdb_constraints = Step( this_dir + '/../common/custom-genlibdb-constraints' )
  custom_timing_assert = Step( this_dir + '/../common/custom-timing-assert'        )
  custom_dc_scripts    = Step( this_dir + '/custom-dc-scripts'                     )
  testbench            = Step( this_dir + '/../common/testbench'                   )
  application          = Step( this_dir + '/../common/application'                 )
  lib2db               = Step( this_dir + '/../common/synopsys-dc-lib2db'          )
  if synth_power:
    post_synth_power     = Step( this_dir + '/../common/tile-post-synth-power'     )
  post_pnr_power       = Step( this_dir + '/../common/tile-post-pnr-power'         )

  # Power aware setup
  power_domains = None
  pwr_aware_gls = None
  if pwr_aware:
      power_domains = Step( this_dir + '/../common/power-domains' )
      pwr_aware_gls = Step( this_dir + '/../common/pwr-aware-gls' )

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

  # Add custom timing scripts
  custom_timing_steps = [ synth, postcts_hold, signoff ] # connects to these
  for c_step in custom_timing_steps:
    c_step.extend_inputs( custom_timing_assert.all_outputs() )

  # Add extra input edges to innovus steps that need custom tweaks
  init.extend_inputs( custom_init.all_outputs() )
  power.extend_inputs( custom_power.all_outputs() )
  genlibdb.extend_inputs( genlibdb_constraints.all_outputs() )
  synth.extend_inputs( custom_genus_scripts.all_outputs() )
  iflow.extend_inputs( custom_flowgen_setup.all_outputs() )

  # Extra input to DC for constraints
  synth.extend_inputs( ["common.tcl", "reporting.tcl", "generate-results.tcl", "scenarios.tcl", "report_alu.py", "parse_alu.py"] )
  # Extra outputs from DC
  synth.extend_outputs( ["sdc"] )
  iflow.extend_inputs( ["scenarios.tcl", "sdc"] )
  init.extend_inputs( ["sdc"] )
  power.extend_inputs( ["sdc"] )
  place.extend_inputs( ["sdc"] )
  cts.extend_inputs( ["sdc"] )

  order = synth.get_param( 'order' )
  order.append( 'copy_sdc.tcl' )
  synth.set_param( 'order', order )

  # Power aware setup
  if pwr_aware:
      synth.extend_inputs(['designer-interface.tcl', 'upf_Tile_PE.tcl', 'pe-constraints.tcl', 'pe-constraints-2.tcl', 'dc-dont-use-constraints.tcl'])
      init.extend_inputs(['upf_Tile_PE.tcl', 'pe-load-upf.tcl', 'dont-touch-constraints.tcl', 'pd-pe-floorplan.tcl', 'pe-add-endcaps-welltaps-setup.tcl', 'pd-add-endcaps-welltaps.tcl', 'pe-power-switches-setup.tcl', 'add-power-switches.tcl', 'check-clamp-logic-structure.tcl'])
      power.extend_inputs(['pd-globalnetconnect.tcl'] )
      place.extend_inputs(['place-dont-use-constraints.tcl', 'check-clamp-logic-structure.tcl', 'add-aon-tie-cells.tcl'])
      cts.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'])
      postcts_hold.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] )
      route.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] )
      postroute.extend_inputs(['conn-aon-cells-vdd.tcl', 'check-clamp-logic-structure.tcl'] )
      signoff.extend_inputs(['conn-aon-cells-vdd.tcl', 'pd-generate-lvs-netlist.tcl', 'check-clamp-logic-structure.tcl'] )
      pwr_aware_gls.extend_inputs(['design.vcs.pg.v'])
  
  # Add short_fix script(s) to list of available postroute scripts
  postroute.extend_inputs( short_fix.all_outputs() )

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

  g.add_step( info                     )
  g.add_step( rtl                      )
  g.add_step( constraints              )
  g.add_step( custom_dc_scripts        )
  g.add_step( synth                    )
  g.add_step( custom_timing_assert     )
  g.add_step( custom_genus_scripts     )
  g.add_step( iflow                    )
  g.add_step( custom_flowgen_setup     )
  g.add_step( init                     )
  g.add_step( custom_init              )
  g.add_step( power                    )
  g.add_step( custom_power             )
  g.add_step( place                    )
  g.add_step( cts                      )
  g.add_step( postcts_hold             )
  g.add_step( route                    )
  g.add_step( postroute                )
  g.add_step( short_fix                )
  g.add_step( signoff                  )
  g.add_step( pt_signoff               )
  g.add_step( genlibdb_constraints     )
  g.add_step( genlibdb                 )
  g.add_step( lib2db                   )
  g.add_step( drc                      )
  g.add_step( lvs                      )
  g.add_step( debugcalibre             )

  g.add_step( application              )
  g.add_step( testbench                )
  if synth_power:
    g.add_step( post_synth_power       )
  g.add_step( post_pnr_power           )

  # Power aware step
  if pwr_aware:
      g.add_step( power_domains        )
      g.add_step( pwr_aware_gls        )

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

  # Dynamically add edges

  # Connect by name

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

  g.connect_by_name( rtl,         synth          )
  g.connect_by_name( constraints, synth          )
  g.connect_by_name( custom_genus_scripts, synth )
  g.connect_by_name( constraints, iflow          )
  g.connect_by_name( custom_dc_scripts, iflow    )

  for c_step in custom_timing_steps:
    g.connect_by_name( custom_timing_assert, c_step )

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

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

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

  # Fetch short-fix script in prep for eventual use by postroute
  g.connect_by_name( short_fix, postroute )

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

  g.connect_by_name( signoff,      drc          )
  g.connect_by_name( signoff,      lvs          )
  g.connect(signoff.o('design-merged.gds'), drc.i('design_merged.gds'))
  g.connect(signoff.o('design-merged.gds'), lvs.i('design_merged.gds'))

  g.connect_by_name( signoff,              genlibdb )
  g.connect_by_name( adk,                  genlibdb )
  g.connect_by_name( genlibdb_constraints, genlibdb )
  
  g.connect_by_name( genlibdb,             lib2db   )

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

  g.connect_by_name( application, testbench       )
  if synth_power:
      g.connect_by_name( application, post_synth_power )
      g.connect_by_name( synth,       post_synth_power )
      g.connect_by_name( testbench,   post_synth_power )
  g.connect_by_name( application, post_pnr_power )
  g.connect_by_name( signoff,     post_pnr_power )
  g.connect_by_name( pt_signoff,  post_pnr_power )
  g.connect_by_name( testbench,   post_pnr_power )

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

  # Pwr aware steps:
  if pwr_aware:
      g.connect_by_name( power_domains,        synth        )
      g.connect_by_name( power_domains,        init         )
      g.connect_by_name( power_domains,        power        )
      g.connect_by_name( power_domains,        place        )
      g.connect_by_name( power_domains,        cts          )
      g.connect_by_name( power_domains,        postcts_hold )
      g.connect_by_name( power_domains,        route        )
      g.connect_by_name( power_domains,        postroute    )
      g.connect_by_name( power_domains,        signoff      )
      g.connect_by_name( adk,                  pwr_aware_gls)
      g.connect_by_name( signoff,              pwr_aware_gls)
      #g.connect(power_domains.o('pd-globalnetconnect.tcl'), power.i('globalnetconnect.tcl'))

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

  g.update_params( parameters )

  # Add custom timing scripts

  for c_step in custom_timing_steps:
    order = c_step.get_param( 'order' )
    order.append( 'report-special-timing.tcl' )
    c_step.set_param( 'order', order )
    c_step.extend_postconditions( [{ 'pytest': 'inputs/test_timing.py' }] )

  # Update PWR_AWARE variable
  synth.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True )
  init.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True )
  power.update_params( { 'PWR_AWARE': parameters['PWR_AWARE'] }, True )

  if pwr_aware:
     init.update_params( { 'flatten_effort': parameters['flatten_effort'] }, True )
     pwr_aware_gls.update_params( { 'design_name': parameters['design_name'] }, True )

     init.extend_postconditions(         ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     place.extend_postconditions(        ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     cts.extend_postconditions(          ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     postcts_hold.extend_postconditions( ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     route.extend_postconditions(        ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     postroute.extend_postconditions(    ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
     signoff.extend_postconditions(      ["assert 'Clamping logic structure in the SBs and CBs is maintained' in File( 'mflowgen-run.log' )"] )
  # Since we are adding an additional input script to the generic Innovus
  # steps, we modify the order parameter for that node which determines
  # which scripts get run and when they get run.

  init.update_params( { 'core_density_target': parameters['core_density_target'] }, True )
  # init -- Add 'edge-blockages.tcl' after 'pin-assignments.tcl'
  # and 'additional-path-groups' after 'make_path_groups'

  order = init.get_param('order') # get the default script run order
  path_group_idx = order.index( 'make-path-groups.tcl' )
  order.insert( path_group_idx + 1, 'additional-path-groups.tcl' )
  pin_idx = order.index( 'pin-assignments.tcl' ) # find pin-assignments.tcl
  order.insert( pin_idx + 1, 'edge-blockages.tcl' ) # add here
  init.update_params( { 'order': order } )

  # Adding new input for genlibdb node to run
  order = genlibdb.get_param('order') # get the default script run order
  read_idx = order.index( 'read_design.tcl' ) # find read_design.tcl
  order.insert( read_idx + 1, 'genlibdb-constraints.tcl' ) # add here
  genlibdb.update_params( { 'order': order } )

  # Pwr aware steps:
  if pwr_aware:
      # init node
      order = init.get_param('order')
      read_idx = order.index( 'floorplan.tcl' ) # find floorplan.tcl
      order.insert( read_idx + 1, 'pe-load-upf.tcl' ) # add here
      order.insert( read_idx + 2, 'pd-pe-floorplan.tcl' ) # add here
      order.insert( read_idx + 3, 'pe-add-endcaps-welltaps-setup.tcl' ) # add here
      order.insert( read_idx + 4, 'pd-add-endcaps-welltaps.tcl' ) # add here
      order.insert( read_idx + 5, 'pe-power-switches-setup.tcl') # add here
      order.insert( read_idx + 6, 'add-power-switches.tcl' ) # add here
      order.remove('add-endcaps-welltaps.tcl')
      order.append('check-clamp-logic-structure.tcl')
      init.update_params( { 'order': order } )

      # power node
      order = power.get_param('order')
      order.insert( 0, 'pd-globalnetconnect.tcl' ) # add here
      order.remove('globalnetconnect.tcl')
      power.update_params( { 'order': order } )

      # place node
      order = place.get_param('order')
      read_idx = order.index( 'main.tcl' ) # find main.tcl
      order.insert(read_idx + 1, 'add-aon-tie-cells.tcl')
      order.insert(read_idx - 1, 'place-dont-use-constraints.tcl')
      order.append('check-clamp-logic-structure.tcl')
      place.update_params( { 'order': order } )

      # cts node
      order = cts.get_param('order')
      order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here
      order.append('check-clamp-logic-structure.tcl')
      cts.update_params( { 'order': order } )

      # postcts_hold node
      order = postcts_hold.get_param('order')
      order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here
      order.append('check-clamp-logic-structure.tcl')
      postcts_hold.update_params( { 'order': order } )

      # route node
      order = route.get_param('order')
      order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here
      order.append('check-clamp-logic-structure.tcl')
      route.update_params( { 'order': order } )

      # postroute node
      order = postroute.get_param('order')
      order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here
      order.append('check-clamp-logic-structure.tcl')
      postroute.update_params( { 'order': order } )

      # Add fix-shorts as the last thing to do in postroute
      order = postroute.get_param('order') ; # get the default script run order
      order.append('fix-shorts.tcl' )      ; # Add fix-shorts at the end
      postroute.update_params( { 'order': order } ) ; # Update

      # signoff node
      order = signoff.get_param('order')
      order.insert( 0, 'conn-aon-cells-vdd.tcl' ) # add here
      read_idx = order.index( 'generate-results.tcl' ) # find generate_results.tcl
      order.insert(read_idx + 1, 'pd-generate-lvs-netlist.tcl')
      order.append('check-clamp-logic-structure.tcl')
      signoff.update_params( { 'order': order } )

  return g
Esempio n. 3
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
Esempio n. 4
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
Esempio n. 5
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