Static Checks

UNDER CONSTRUCTION

Mflowgen nodes are typically designed to reused across different designs, different technologies, or both. When a designer attempts to reuse an mflowgen node, we want to provide early and rapid feedback on whether or not that node is being used properly in the new flow. However, long CAD tool runtimes make runtime assertions insufficient for this purpose, as designers would have to wait for the flow to reach the code fragment of interest, which could take hours or even days.

Mflowgen static checks are designed to provide early and rapid feedback on whether or not a reusable mflowgen node is being reused properly by running static program analysis at graph elaboration time to flag any inconsistencies, instead of actually running any CAD tools.

Intent-Implementation Split

The intent-implementation split is one of mflowgen’s built-in static checks. Using the schema below, designers can separately express the intent of a particular code fragment (along with formal properties which any implementation of that intent must follow), from a potentially design- or technology-specific implementation of that intent.

_images/intent-impl-split-schema.pdf

Here’s an example where the intent-implementation split is used to add power domains to 2 different blocks while reusing the same power domains insertion intent.

Specifically, this power domains strategy involves the creation of an AON region within the block’s floorplan. It’s the same concept regardless of which block it’s placed in, but the AON region must be placed carefully to avoid a variety of DRC and/or LVS errors.

Here’s how a designer would write the intent block for drawing this AON region. The intent runs the necessary tool command, accepts parameters from an implementation as inputs, and contains a set of properties that any implementation must obey.

proc mflowgen.intent.createAON { $aon_llx $aon_lly $aon_urx $aon_ury $x_gap $y_gap } {
  modifyPowerDomainAttr AON \
    -box $aon_llx $aon_lly $aon_urx $aon_ury  \
    -minGaps $aon_y_gap $aon_y_gap $aon_x_gap] $aon_x_gap]

  array set mflowgen.property.even_y {
    property "((aon_lly//y_pitch) % 2 == 0) & ((aon_ury//y_pitch) % 2 == 0)"
    describe "The AON region must begin and end on an even numbered
             standard cell row to prevent obstructed power switches and
             LUP DRCs"
  }

  array set mflowgen.property.max_width {
    property "(aon_urx - aon_llx) < horiz_switch_pitch)"
    describe "The always on region must be narrower than the pitch
              between power switch pitches so that no more than 1 column
              of switches is obstructed"
  }

  array set mflowgen.property.away_from_left_edge {
    property "aon_llx > (M3_str_offset + 2*M3_str_pitch)"
    describe "AON region must be far enough from left edge to allow space for at
              least one set of M3 VDD/VSS stripes"
  }

  array set mflowgen.property.away_from_right_edge {
    property "aon_urx < (fp_width - M3_str_offset - 2*M3_str_pitch)"
    describe "AON region must be far enough from right edge to allow space for at
              least one set of M3 VDD/VSS stripes"
  }

  array set mflowgen.property.M3_stripe_obstruction_left {
    property "math.fmod(aon_llx - M3_str_offset, M3_str_pitch) > (2 * M3_str_width)"
    describe "Left edge of AON region cannot overlap with M3 stripe"
  }

  array set mflowgen.property.M3_stripe_obstruction_right {
    property "math.fmod(aon_urx - M3_str_offset, M3_str_pitch) > (2 * M3_str_width)"
    describe "Right edge of AON region cannot overlap with M3 stripe"
  }
}

An implementation must provide all of the inputs that the intent requires. Here’s an example implementation for creating the AON region in a given block:

proc mflowgen.implement.createAON {} {
    # Params
    set x_offset   3
    set aon_width  14
    set aon_height 10
    set lly 50
    set minGap 1

    # Plase AON region in middle of tile (+ x_offset) on X-axis
    set aon_llx [expr $core_width/2 - $aon_width/2 + $x_offset]
    set aon_urx [expr $core_width/2 + $aon_width/2 + $x_offset]
    set aon_lly $lly
    set aon_ury [expr $aon_lly_coord + $aon_height]

    # Snap coords to placement grid
    set aon_llx_snap ...

    return [list $aon_llx_snap $aon_lly_snap $aon_urx_snap $aon_ury_snap $minGap $minGap]
}

As you can see, this implementation provides values for all of the parameters required by the createAON intent. Now that we have both an implementation and an intent for this feature, we can run the code fragment like this:

mflowgen.intent.createAON {*}[mflowgen.implement.createAON]

All of the parameter values are passed calculated by the implementation are passed to the intent, and they are all checked for consistency at graph elaboration time, not tool runtime. This allows for immediate feedback if a given implementation is incorrect and greatly shortens the debug loop for any designer trying to reuse this code.

Here are 2 separate blocks that reused the same createAON intent, but with different implementation blocks.

_images/pe-aon-example.png _images/mem-aon-example.png