Skip to content
VLSI Mentor

Tcl · Module 21

Writing the Netlist

Writing the netlist is one command. Recording what produced it is the part that decides whether anybody can trust the file in six months.

Advanced15 min readtcledapart-iisynthesisnetlistprovenancehandoff

Part II · Module 21 · Chapter 21.9 · Writing the Netlist

The last phase hands the result to whatever comes next. The write is one command. Everything worth saying about this phase is about what goes beside it.

1. The write

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
write_verilog [file join $RUN netlist ${TOP}_mapped.v]     ;# a tool command
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== writing the netlist, and the provenance record beside it ===
    netlist: cpu_top_mapped.v (34 bytes)

Two details worth getting right:

The name comes from $TOP. Chapter 21.3 §6 made the top a variable precisely so the netlist cannot be named after a different design than the one elaborated.

It goes in the run directory, beside the reports — Chapter 21.8 §6. The netlist and the evidence for it belong together.

2. Check it landed

Same discipline as the reports:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set nl [file join $RUN netlist ${TOP}_mapped.v]
write_verilog $nl
if {![file isfile $nl] || [file size $nl] == 0} {
    error "netlist was not written: $nl" {} [list NETLIST EMPTY $nl]
}
puts "  netlist: [file tail $nl] ([file size $nl] bytes)"

A zero-byte netlist is the same hazard as Chapter 21.8 §3's zero-byte report, and more consequential: the next stage reads it, finds nothing, and reports an empty design.

3. The question six months later

Somebody finds this netlist and asks: what produced it?

Which sources, at which revision. Which libraries, at which corner. Which constraints. Which compile options. Which tool version.

Without a record, the honest answer is "probably the script in the repository, as it was then" — which is a guess. With one, it is a file.

4. The provenance record

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc write_provenance {path args} {
    set fp [open $path w]
    puts $fp "# what produced the netlist in this directory"
    foreach {k v} $args { puts $fp [format "%-14s %s" $k $v] }
    close $fp
    return $path
}

write_provenance [file join $RUN netlist PROVENANCE.txt] \
    top          cpu_top \
    sources      [join $names {,}] \
    source_count [llength $files] \
    tcl_version  [info patchlevel] \
    script       [file tail [info script]]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    PROVENANCE.txt:
      # what produced the netlist in this directory
      top            cpu_top
      sources        alu.v,cpu_top.v,fifo.v
      source_count   3
      tcl_version    8.5.9
      script         netlist.tcl

Twelve lines of ordinary Tcl — args as key-value pairs (Chapter 10.4), format to align, info patchlevel and info script from Chapter 14.10.

A real record should also carry:

  • The libraries and the corner — Chapter 21.4 §5. Without these the timing numbers cannot be interpreted at all.
  • The constraint files sourced — Chapter 21.6 §6.
  • The compile options and runtime — Chapter 21.7 §4.
  • The tool name and version, not just Tcl's.
  • The source revision, if the sources are under version control.
  • The summary numbers — worst slack, area — so the file says what it achieved as well as how it was made.

5. Make it machine-readable

The name value per line format is deliberate — Chapter 16.3 §5. It is readable by a person and parseable in two lines:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc read_provenance {path} {
    set d [dict create]
    set fp [open $path r]
    while {[gets $fp line] >= 0} {
        set line [string trim $line]
        if {$line eq "" || [string index $line 0] eq "#"} { continue }
        dict set d [lindex $line 0] [lrange $line 1 end]
    }
    close $fp
    return $d
}

Which makes the interesting question cheap: what differs between this run and the last one? Two provenance files and a dict comparison, outside the tool, with no licence — and the answer to "why did these two runs disagree" is usually in that diff.

6. The handoff

A netlist handed to the next stage should arrive with:

  • the netlist itself,
  • the constraints that produced it, or the post-synthesis constraints,
  • the reports, so the receiver can see what was achieved,
  • the provenance, so they can tell what it was built from,
  • and an exit status from the run that says it is complete — Chapter 21.10.

The last is the one that is usually missing, and it is the one that matters most: a netlist produced by a run that exited non-zero should not be used, and nothing in the file itself says so.

7. Exercises

Exercise 1. Why should the netlist filename be built from $TOP?

Exercise 2. Why check the netlist size after writing it?

Exercise 3. What question does a provenance record answer?

Exercise 4. Name four things a real provenance record should contain beyond the sources.

Exercise 5. Why keep it beside the netlist rather than in a tracking system?

Exercise 6. Why use name value per line rather than prose?

Exercise 7. What should accompany a netlist handed to the next stage?

Where this fits

Part of the Tcl curriculum.