( ESNUG 331 Item 3 ) --------------------------------------------- [10/7/99]
From: [ My Own Private Idaho ]
Subject: "Stats" -- A User Customizable PrimeTime Timing Report Tcl Script
Hi John,
I know you weren't too enthused when Synopsys announced their supporting
the Tcl interface, but have you ever wanted to create your own PrimeTime
report that has data not found in a standard report? Perhaps consolidate
information from different PrimeTime reports into one report? Include
Cindy Crawford's fan club URL in the report header? With Tcl in PrimeTime,
you can do this. It's all done with PT attributes.
In PrimeTime you have direct access to any timing path(s) and attributes
for the pins, ports, clocks, nets, etc. These attributes include arrival
times, capacitance, transition, slack, uncertainty, etc. You can have
PrimeTime list them all by:
pt_shell> list_attributes -application
Once you have the values of these attributes, you can do anything you wish
with them. You can format them, print them, and even modify some of them.
You can make your report a new PT command. You can share it with your
co-workers. Life is great and the world is your oyster.
The basic mechanics of creating your own PT command:
1. Create a Tcl procedure in your fave editor:
proc my_report { <options> } {
...PT Tcl code here...
}
2. Save the file, call it say 'my_report.tcl'
3. Fire up PT. Declare your new command by sourcing the script:
pt_shell> source my_report.tcl
(Note that this doesnt *run* the procedure, it just declares it.)
4. Run your new command:
pt_shell> my_report <options>
That's all there is to it. Yes, you can put multiple procedures in a file.
Yes, you can declare multiple script files. No, you can't re-define
existing PrimeTime/Tcl commands (although the practical joke implications
of this are mind-boggling.) Don't want to source the proc every time you
run PT? Put it in your .synopsys_pt.setup and be done with it!
Below is a script "stats" that will report a nice summary of your design,
showing things like the total number of ports, pins, nets, cells, latches,
flip-flops, etc. I encourage you to modify it any which way you find
useful! Here's an example of the output of "stats":
pt_shell> stats
****************************************
Report : stats
Design : LATCH
Version: 1999.05-PT2.1
Date : Thu Sep 30 12:17:30 PDT 1999
****************************************
Design : BIG_TOP
Ports : 176 (in:13 out:7 inout:156)
Cells : 219343
Hierarchical : 9102
Leaf : 210241
Sequential : 33587 (latch:5640 ff:27935 ms:0)
Combinational : 176032
Pins : 925036
Leaf : 759638 (in:517896 out:240168 inout:1574)
Hier : 165398 (in:99913 out:54244 inout:11241)
Three_state : 10385
Clocks : 12
Generated clocks : 5
Timing exceptions : 2312
-through : 55
Pretty neat, huh? Below is the PrimeTime Tcl source code for the "stats"
script. It's fairly straightforward, getting attributes about the design
and formatting them into a simple report. No conditional statements,
nothing fancy. The only tricky part is counting the exceptions in the
design, as this isn't available directly as an attribute in PrimeTime.
It actually issues a report_exceptions command and parses the output,
right in-line.
# PROCEDURE: report_print_header
#
# Abstract: Prints a report header for the current design.
proc report_print_header {title} {
global sh_product_version;
echo "****************************************"
echo [format "Report : %s" $title]
echo [format "Design : %s" [get_attribute [current_design] full_name]]
echo [format "Version: %s" $sh_product_version]
echo [format "Date : %s" [report_get_date]]
echo "****************************************\n"
}
# PROCEDURE: stats
#
# ABSTRACT: returns quick stats on the current design
#
# SYNTAX: stats
proc stats {} {
report_print_header "stats"
# port stats
set ports [get_ports *]
set in_ports [filter_collection $ports "direction == in" ]
set out_ports [filter_collection $ports "direction == out" ]
set inout_ports [filter_collection $ports "direction == inout"]
set port_num [sizeof_collection $ports]
set in_port_num [sizeof_collection $in_ports]
set out_port_num [sizeof_collection $out_ports]
set inout_port_num [sizeof_collection $inout_ports]
# cell stats
set cells [get_cells -hier -quiet *]
set hier_cells [filter_collection $cells "is_hierarchical == true"]
set leaf_cells [filter_collection $cells "is_hierarchical == false"]
set cell_num [sizeof_collection $cells]
set hier_cell_num [sizeof_collection $hier_cells]
set leaf_cell_num [sizeof_collection $leaf_cells]
# combo and sequential cells
set seq_cells [filter_collection $leaf_cells "is_sequential == true"]
set seq_cell_num [sizeof_collection $seq_cells]
set comb_cells [filter_collection $leaf_cells "is_combinational == true"]
set comb_cell_num [sizeof_collection $comb_cells]
# categorize seq cells
set latch_regs [all_registers -level_sensitive]
set latch_reg_num [sizeof_collection $latch_regs]
set ff_regs [all_registers -edge_triggered]
set ff_reg_num [sizeof_collection $ff_regs]
set ms_regs [all_registers -master_slave]
set ms_reg_num [sizeof_collection $ms_regs]
# pin stats
set pins [get_pins -quiet -hier *]
set pin_num [sizeof_collection $pins]
# leaf pin stats
set leaf_pins [get_pins -quiet -of_object $leaf_cells]
set leaf_in_pins [filter_collection $leaf_pins "direction == in" ]
set leaf_out_pins [filter_collection $leaf_pins "direction == out" ]
set leaf_inout_pins [filter_collection $leaf_pins "direction == inout"]
set leaf_tristate_pins [filter_collection $leaf_pins "is_three_state == true"]
set leaf_pin_num [sizeof_collection $leaf_pins]
set leaf_in_pin_num [sizeof_collection $leaf_in_pins]
set leaf_out_pin_num [sizeof_collection $leaf_out_pins]
set leaf_inout_pin_num [sizeof_collection $leaf_inout_pins]
set leaf_tristate_pin_num [sizeof_collection $leaf_tristate_pins]
# hierarchical pin stats
set hier_pins [get_pins -quiet -of_object $hier_cells]
set hier_in_pins [filter_collection $hier_pins "direction == in" ]
set hier_out_pins [filter_collection $hier_pins "direction == out" ]
set hier_inout_pins [filter_collection $hier_pins "direction == inout"]
set hier_pin_num [sizeof_collection $hier_pins]
set hier_in_pin_num [sizeof_collection $hier_in_pins]
set hier_out_pin_num [sizeof_collection $hier_out_pins]
set hier_inout_pin_num [sizeof_collection $hier_inout_pins]
# clocks
set clocks [get_clocks -quiet *]
set gen_clocks [get_generated_clocks -quiet *]
set clock_num [sizeof_collection $clocks]
set gen_clock_num [sizeof_collection $gen_clocks]
# timing exceptions - the tricky part
redirect ./rpt_except.log {report_exception -nosplit}
set F [open ./rpt_except.log r]
set found_start 0
set thru_excpt_num 0
set excpt_num 0
foreach line [split [read $F] \n] {
if {[regexp {^-+$} $line] } {
set found_start 1
continue
}
if { $found_start == 0 } continue
if {[regexp {^[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+$} $line] == 1} {
set thru_excpt_num [expr $thru_excpt_num + 1]
set excpt_num [expr $excpt_num + 1]
} elseif {[regexp {^.+\ +.+\ +.+\ +.+$} $line] == 1} {
set excpt_num [expr $excpt_num + 1]
}
}
close $F
echo [format "Design : %s" \
[get_attribute [current_design] full_name]]
echo [format "Ports : %d (in:%d out:%d inout:%d)" \
$port_num $in_port_num $out_port_num $inout_port_num]
echo [format "Cells : %d" $cell_num]
echo [format " Hierarchical : %d" $hier_cell_num]
echo [format " Leaf : %d" $leaf_cell_num]
echo [format " Sequential : %d (latch:%d ff:%d ms:%d)" \
$seq_cell_num $latch_reg_num $ff_reg_num $ms_reg_num]
echo [format " Combinational : %d" $comb_cell_num]
echo [format "Pins : %d" $pin_num]
echo [format " Leaf : %d (in:%d out:%d inout:%d)" \
$leaf_pin_num $leaf_in_pin_num $leaf_out_pin_num \
$leaf_inout_pin_num]
echo [format " Hier : %d (in:%d out:%d inout:%d)" \
$hier_pin_num $hier_in_pin_num $hier_out_pin_num \
$hier_inout_pin_num]
echo [format " Three_state : %d" $leaf_tristate_pin_num]
echo [format "Clocks : %d" $clock_num]
echo [format "Generated clocks : %d" $gen_clock_num]
echo [format "Timing exceptions : %d" $excpt_num]
echo [format " -through : %d" $thru_excpt_num]
return 1
}
define_proc_attributes stats \
-info "Report design statistics (cells, pins,..)"
Feel free to modify this, reformat it, etc. as needed. However, be careful
if you are depending on your script in a sign-off situation, be sure its
correct, accurate, yada, yada, yada. It would be kind of a shame if, say,
an entire city lost power because your chip didn't meet timing, simply
because you forgot to account for clock latency in a custom timing report.
Oops.
No names, etc. Politics.
- [ My Own Private Idaho ]
|
|