Conditional Flows

There are many different types of conditions that affect the shape of the flow, from conditions that are known at "build-time", meaning at the time vovbuild is first executed, to conditions that are known only after one or more jobs have been executed. In this section, we examine a couple of common types.

Build-time Conditions

Conditions that can be evaluated at build time are the easiest to handle because we can use standard Tcl procedures like if and switch.
if { $blockType == "large" } {
    J vw runFastRouter $block
} else {
    J vw runNormalRouter $block

Complex Conditions

Sometimes a flow depends on a computation that involves one or more complex tools. For example, we may have a methodology that says:

If the block meets timing, then publish the block, else improve timing

where the condition "meets timing" is computed by running expensive (in term of software licenses) and time-consuming tools. The way to handle such flows is to build them one piece at a time and to include the invocation of the vovbuild itself as part of the flow.
# This is BlockFlow.tcl
# A procedure to get the slack (timing) of a block.
# A negative slack means that the block does not meet timing.
proc getBlockSlack { file step } {
    set fp [open $file]
    set slack [read $fp]
    close $fp
    return $slack

# In the first part of the flow, we run a few jobs
# and then we run another vovbuild.
proc partOne { block } {
    S "Block:$block:Step1" {
        E WORK
        J vw runSynth $block
        J vw measureSlack $block -step 1
        O reports/step1/$block.timing

        J vovbuild -T -f BlockFlow.tcl  -- -step 2
        I reports/step1/$block.timing

# In the second part of the flow, we get the 
# timing of the block and then decide what to do
# based in it.
proc partTwo { block step } {
    set n1    [expr $step -1 ]
    set slack [getBlockTiming "step$n1/$block.timing"]
    S "Block:$block:Step$step" {
        if { $slack >= 0 } {
            # The block meets timing.
            J clevercopy -m 644 $block.v ../../netlists
        } else {
            # The block does not meet timing.
            E WORK
            R "timing_opt_license"
            J vw refineTiming $block -step $step
            O reports/step$step/$block.timing

            J vovbuild -T -f BlockFlow.tcl  -- -step [expr $step + 1]
            I reports/step$step/$block.timing

# Main controller code for the flow.

set block [file tail [pwd]]
set step  1
while { $argv != {} } {
    set arg [shift]
    switch -glob -- $arg {
        "-step" { set step [shift] }

switch $step {
    1 { partOne $block }
    2 - 3 - 4 - 5 - 6  { partTwo $block $step }
    default {
        VovFatalError "Too many iterations: timing does not converge"