Skip to content
VLSI Mentor

Tcl · Module 21

Generating the Report Set

The netlist is what the run produced; the reports are how anyone knows whether to use it. A run that compiled successfully and wrote no reports has produced nothing anybody can sign off.

Advanced16 min readtcledapart-iisynthesisreportsfilesvalidation

Part II · Module 21 · Chapter 21.8 · Generating the Report Set

Compile produces a netlist. The reports are how anybody decides whether that netlist is usable — and a run without them has produced an artefact nobody can evaluate.

Writing them is almost entirely Part I: making a directory, opening files, checking they landed.

1. What a run must leave behind

Four reports, minimum, and each answers a question somebody will ask:

ReportAnswers
timingdid it meet the constraints, and where is the worst path?
areahow big is it?
powerwhat does it cost to run?
qualitythe summary numbers — worst slack, total negative slack, violation counts

The quality report is the one read first, because it is the one that decides whether the others need reading at all.

To these add the session log — Chapter 21.5 §3's elaboration warnings live there, and without it an unresolved reference has no record.

2. Create the directory first

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc ensure_dir {path} {
    if {[file exists $path] && ![file isdirectory $path]} {
        error "'$path' exists and is not a directory" {} {RUN NOTDIR}
    }
    file mkdir $path
    if {![file writable $path]} { error "'$path' is not writable" {} {RUN NOWRITE} }
    return $path
}
ensure_dir [file join $RUN reports]
ensure_dir [file join $RUN netlist]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== 1. create the output directory BEFORE anything writes to it ===
    created: /private/tmp/m21/run/reports
    created: /private/tmp/m21/run/netlist

Three deliberate details, all from Chapter 14.11:

  • The not-a-directory check first. file mkdir on a path occupied by a file fails with a message about the path; checking first gives a message about the situation.
  • file mkdir creates intermediate directories and is not an error if the directory already exists — so it is safe to call every run.
  • The writable check. A directory that exists and cannot be written to is the case that produces zero-byte reports later.

3. Write them, and check each landed

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc write_report {path body} {
    set fp [open $path w]
    puts $fp $body
    close $fp
    if {![file isfile $path] || [file size $path] == 0} {
        error "report '$path' was not written" {} [list REPORT EMPTY $path]
    }
    return [file size $path]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== 2. write the report set, checking each one landed ===
    timing.rpt     47 bytes
    area.rpt       35 bytes
    power.rpt      17 bytes
    qor.rpt        20 bytes
    -> 4 report(s)

In a real flow the body comes from the tool's report command rather than a literal, but the wrapper is the same: produce it, write it, check it is non-zero.

4. Check the set is complete

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc check_reports {dir expected} {
    set missing {} ; set empty {}
    foreach r $expected {
        set p [file join $dir $r]
        if {![file isfile $p]}   { lappend missing $r ; continue }
        if {[file size $p] == 0} { lappend empty $r }
    }
    return [list $missing $empty]
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== 3. the check: every expected report present and non-empty ===
    missing: <none>
    empty  : <none>
    with clock.rpt expected too -> missing: clock.rpt

The expected list is declared, which is the point. Checking "are there some files in the reports directory" passes on a run that wrote one report; checking against a stated list catches the three that are absent.

This is Chapter 19.5 §6's expectation idea again: a count or a set you predicted and then verified says far more than one you merely observed.

5. Extracting the numbers

The reports are for humans, but the summary numbers should also be machine-readable, because that is how runs get compared:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc qor_number {path key} {
    set fp [open $path r]
    set text [read $fp]
    close $fp
    if {![regexp "${key}\\s+(\\S+)" $text -> value]} {
        error "no '$key' line in [file tail $path]" {} [list QOR MISSING $key]
    }
    return $value
}

One regexp per number — Module 13 — with an error rather than an empty string when the line is absent, so a changed report format is noticed rather than silently producing blanks.

Then the run can state its own result:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set wns [qor_number [file join $RUN reports qor.rpt] wns]
puts "  worst negative slack: $wns"

6. Where the reports go

One directory per run, named so two runs cannot collide:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set RUN [file join $PROJECT runs ${TOP}_${CORNER}_[clock format [clock seconds] -format %Y%m%d_%H%M%S]]

Three properties worth having:

  • Unique, so a new run never overwrites the evidence for the last one.
  • Sortable, because a timestamp in %Y%m%d_%H%M%S sorts chronologically as a string.
  • Self-describing, so the directory name alone says which block and which corner.

And since Chapter 21.9 puts the netlist in the same run directory, the netlist and the evidence for it stay together — which is the whole point of the next chapter.

7. Exercises

Exercise 1. Name the four reports a run must leave, and which is read first.

Exercise 2. Why create the output directories at the start of the run rather than before the report phase?

Exercise 3. Name the three checks in ensure_dir and what each catches.

Exercise 4. Why is a zero-byte report worse than a missing one?

Exercise 5. Why check against a declared list of expected reports rather than counting files?

Exercise 6. Why should qor_number raise rather than return an empty string?

Exercise 7. Give three properties a run directory name should have.

Where this fits

Part of the Tcl curriculum.