Skip to content
VLSI Mentor

Tcl · Module 20

Reviewing a Constraint Set

A wrong constraint set does not produce an error. It produces a confident timing report that means nothing — so the review has to be a program, not a reading.

Advanced18 min readtcledapart-iisdcreviewchecklistquality

Part II · Module 20 · Chapter 20.8 · Reviewing a Constraint Set

Everything in this module shares one failure mode: a wrong constraint set does not produce an error. It produces a clean, confident timing report that happens to mean nothing.

So the review cannot be somebody reading the file and feeling satisfied. It has to be a script that proves it — and because a .sdc file is Tcl (Chapter 20.1), you can write one.

1. What the review must establish

Four things, from the registry's own list:

  1. Every clock declared — and the right kind, primary or generated.
  2. Every input and output timed — no port left on the optimistic default.
  3. Every exception justified — a recorded reason, not a bare constraint.
  4. Multicycle paths complete — both setup and hold stated.

Each is mechanically checkable. §6 is about the things that are not.

2. An incomplete set

Here is a constraint set that looks reasonable:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
create_clock -name core_clk -period 2.0 [get_ports clk]
set_input_delay 0.4 -clock core_clk [get_ports {d_in[*]}]
set_false_path -from [get_ports reset_n] -to [get_cells u_core]
set_multicycle_path 2 -from [get_cells u_cfg] -to [get_cells u_core] -setup

A clock, input delays on the data bus, an exception, a multicycle. Run the review against it:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== an incomplete constraint set ===
  ok      1 clock(s) defined
  ERROR   3 input port(s) with no input delay: ref_clk, reset_n, cfg_mode
  ERROR   2 output port(s) with no output delay: d_out[0], d_out[1]
  ERROR   1 false path(s) with no recorded reason
  ERROR   a multicycle -setup was declared with no matching -hold
  ---
  4 problem(s)

3. The review script

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc review_constraints {} {
    set problems 0

    # 1. is there a clock at all?
    if {[llength $::sdc::clocks] == 0} {
        puts stderr "  ERROR   no clock is defined"
        incr problems
    } else {
        puts "  ok      [llength $::sdc::clocks] clock(s) defined"
    }

    # 2. every input port timed (except the clocks themselves)
    set clk_ports {}
    foreach c $::sdc::clocks { lappend clk_ports [lindex $c 2] }
    set timed {}
    foreach d $::sdc::idelays { lappend timed [lindex $d 0] }
    set untimed {}
    foreach_in_collection p [get_ports *] {
        if {[get_attribute $p direction] ne "in"} { continue }
        if {[lsearch -exact $clk_ports $p] >= 0} { continue }
        if {[lsearch -exact $timed $p] < 0} { lappend untimed $p }
    }
    if {[llength $untimed]} {
        puts stderr "  ERROR   [llength $untimed] input port(s) with no input delay: [join $untimed {, }]"
        incr problems
    } else {
        puts "  ok      every input port has an input delay"
    }

    # 3. every exception justified
    set unjustified 0
    foreach f $::sdc::falsepath { if {[lindex $f 2] eq ""} { incr unjustified } }
    if {$unjustified} {
        puts stderr "  ERROR   $unjustified false path(s) with no recorded reason"
        incr problems
    } else {
        puts "  ok      every false path has a reason"
    }

    # 4. multicycle paths state both sides
    set sides {}
    foreach m $::sdc::mcp { lappend sides [lindex $m 3] }
    if {[lsearch -exact $sides "setup"] >= 0 && [lsearch -exact $sides "hold"] < 0} {
        puts stderr "  ERROR   a multicycle -setup was declared with no matching -hold"
        incr problems
    } elseif {[llength $::sdc::mcp]} {
        puts "  ok      multicycle paths state both setup and hold"
    }

    puts "  ---"
    puts "  $problems problem(s)"
    return $problems
}

The output-port check is the input check with out substituted, and is omitted above for length.

Four Part I decisions in that procedure, and each is from Chapter 15.9:

  • Problems go to stderr, the summary to stdout — so the check runs in a pipeline and the diagnostics still reach a human (Chapter 14.9 §2).
  • It reports the ok cases too. A check that only speaks when unhappy leaves you unsure whether it ran. Five ok lines is evidence.
  • It names the offenders, not just the count — ref_clk, reset_n, cfg_mode is actionable where "3 ports" is not.
  • It returns a count, and the caller decides the exit status. The procedure never calls exit (Chapter 15.4 §3).

4. A complete set

The same review against a constraint set that does the job:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set PERIOD 2.0
create_clock -name core_clk -period $PERIOD [get_ports clk]
create_clock -name ref_clk  -period 10.0    [get_ports ref_clk]

foreach_in_collection p [get_ports {d_in[*]}] {
    set_input_delay [expr {$PERIOD * 0.20}] -clock core_clk $p
}
set_input_delay [expr {$PERIOD * 0.20}] -clock core_clk [get_ports reset_n]
set_input_delay [expr {$PERIOD * 0.20}] -clock core_clk [get_ports cfg_mode]

foreach_in_collection p [get_ports {d_out[*]}] {
    set_output_delay [expr {$PERIOD * 0.15}] -clock core_clk $p
}

false_path [get_ports cfg_mode] [get_cells u_core] \
    {cfg_mode is static after reset; software sets it before the core runs}

set_multicycle_path 2 -from [get_cells u_cfg] -to [get_cells u_core] -setup
set_multicycle_path 1 -from [get_cells u_cfg] -to [get_cells u_core] -hold

set_clock_groups -asynchronous -group {core_clk} -group {ref_clk}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== a complete constraint set ===
  ok      2 clock(s) defined
  ok      every input port has an input delay
  ok      every output port has an output delay
  ok      every false path has a reason
  ok      multicycle paths state both setup and hold
  ---
  0 problem(s)

Four problems to zero. And notice what the complete file is made of: a variable for the period, loops over the buses, the false_path wrapper from Chapter 20.5 §4, and a paired multicycle — all of which are Part I applied to constraints.

5. Running it

As part of the flow, not on request:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
source constraints.sdc
if {[review_constraints] > 0} {
    puts stderr "constraint review failed — not proceeding"
    exit 1
}

Three properties worth insisting on:

  • It runs every time, immediately after the constraints are read. A check somebody has to remember is run after the problem is expensive.
  • It fails the build. A non-zero exit so the surrounding automation stops rather than spending four hours on a run that cannot mean anything.
  • Its output is in the log, so two runs can be compared and a regression is visible.

6. What a script cannot check

The honest half, and it matters as much as the script.

Mechanical — the script handles these:

  • Is there a clock? Are all ports timed? Does every false path have a reason? Is every multicycle paired? Is every clock in exactly one group?

Not mechanical — a human must:

  • Is the period right? The script sees 2.0; only the specification says whether that is correct.
  • Is the budget right? 20% input and 15% output is a decision, not a fact — Chapter 20.4 §5.
  • Is a false path's claim true? The reason is recorded; whether it is still correct needs somebody who knows the design.
  • Is there a synchroniser behind each clock group? Chapter 20.7 §5 — the constraint cannot tell you, and neither can simulation.
  • Is an exception covering a design problem? The hardest one, and the most consequential.

7. The review as a document

The constraint set is a design document, and the review has a human half worth running at every milestone:

  • Read every exception and ask whether its reason still holds. Designs change; claims do not update themselves.
  • Count the exceptions. A handful is normal; a long list usually means something structural is being papered over.
  • Check the clock periods against the specification, not against memory.
  • Check the I/O budget adds up, and that the far side of each interface agrees — Chapter 20.4 §6.
  • Ask what changed since last time. A diff of the constraint set between milestones is one of the highest-value reviews available, and it costs nothing because the file is in version control.

8. Exercises

Exercise 1. Why can a constraint-set review not be "somebody reads the file"?

Exercise 2. Name the four mechanically checkable properties.

Exercise 3. The incomplete set had four problems and no syntax errors. What would the timing report have looked like?

Exercise 4. Why does the review report the ok cases as well as the failures?

Exercise 5. Why does review_constraints return a count instead of calling exit?

Exercise 6. The review reports no problems on a design that was never loaded. What is missing?

Exercise 7. Name three things the script cannot check.

Where this fits

Part of the Tcl curriculum.