0% found this document useful (0 votes)
72 views3 pages

A TCL Proc To Create A Quick SPEF From A Netlist Without Need For RC Extraction

tempus rm sctpr

Uploaded by

thsim85
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views3 pages

A TCL Proc To Create A Quick SPEF From A Netlist Without Need For RC Extraction

tempus rm sctpr

Uploaded by

thsim85
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

A Tcl proc to create a quick SPEF from a netlist without need for RC extraction

Explanation of Script
It is a good idea to start timing and Spice analysis with a small testcase. Often, the netlist is hand written to just show the circuit. Many times, you do not have the PnR
layout for these experimental cases to run actual SPEF RC extract, but you want to provide a formally correct SPEF parasitics file to the timing engine or Spice simulation
tools in the Tempus tool.

The Tcl proc provided here uses the database access functionality to gather information of a netlist and then writes out a syntactically correct SPEF file for timing analysis.

There are some controls provided to the SPEF-creation proc:

A collection of the nets that you wish to consider for the SPEF
Numerical values for the resistors and capacitors to be put into the SPEF
An output file name for the created SPEF file
Following is the simple schematic and netlist based on which you decide how you want to construct the resistor and capacitor topology for the SPEF.

You want to construct a topology that gives a picture relatively close to the design reality.

A resistor is attached to every pin or port.


You now have a new internal node where you attach a capacitor.
Below is the desired RC structure:

Next, you will look at an application example.

For the above simple netlist, you load the testcase and perform a timing analysis.

read_lib ./LIB/STDCELL.lib
read_verilog ./3buf.v
set_top_module buf3​
read_sdc top.sdc
set_global report_timing_format { cell arc fanout load annotation delay slew arrival hpin }
update_timing
report_timing -from in -to out1

You get the following timing report:

###############################################################
Path 1: MET Late External Delay Assertion
Endpoint: out2 (v) checked with leading edge of 'clock'
Beginpoint: in (v) triggered by leading edge of 'clock'
Path Groups: {clock}
Other End Arrival Time 0.000
- External Delay 0.500
+ Phase Shift 10.000
= Required Time 9.500
- Arrival Time 0.827
= Slack Time 8.673
Clock Rise Edge 0.000
+ Input Delay 0.500
= Beginpoint Arrival Time 0.500
--------------------------------------------------------------------------------
Cell Arc Fanout Load Arc Delay Slew Arrival Pin
Annotation Time
--------------------------------------------------------------------------------
- in v 1 0.004 WLM - 0.004 0.500 in ->
BUFFHVTD2 I v -> Z v 2 0.008 WLM 0.111 0.048 0.611 I0/Z
BUFFHVTD2 I v -> Z v 1 0.004 WLM 0.114 0.039 0.725 I2/Z
BUFFHVTD2 I v -> Z v 1 0.000 WLM 0.102 0.029 0.827 I3/Z
- out2 v - 0.000 WLM 0.000 0.029 0.827 out2 ->
--------------------------------------------------------------------------------

Notice here that only wire load model parasitics are provided in the timing analysis. This may not be realistic. Suppose you want to do Spice analysis on the path using the
create_spice_deck command; you will not find realistic connection resistors and load capacitors in the Spice deck. (Spice deck not shown here)
Now, use the script provided and create a SPEF, apply the SPEF, and perform the timing analysis again. For your SPEF, you chose a net capacitance of 0.1fF and
10ohm, which are realistic values for a larger technology node.

source ./testspef.tcl
set mynets [ get_nets {in w* out*} ]
testspef -net_collection $mynets -net_cap 0.1 -net_res 10.0 -outfile testspef.spef
read_spef testspef.spef testspef.spef
update_timing -full
report_timing -from in -to out1

Below is the timing report:

###############################################################
Path 1: MET Late External Delay Assertion
Endpoint: out2 (^) checked with leading edge of 'clock'
Beginpoint: in (^) triggered by leading edge of 'clock'
Path Groups: {clock}
Other End Arrival Time 0.000
- External Delay 0.500
+ Phase Shift 10.000
= Required Time 9.500
- Arrival Time 1.670
= Slack Time 7.830
Clock Rise Edge 0.000
+ Input Delay 0.500
= Beginpoint Arrival Time 0.500
--------------------------------------------------------------------------------
Cell Arc Fanout Load Arc Delay Slew Arrival Pin
Annotation Time
--------------------------------------------------------------------------------
- in ^ 1 0.104 SPEF - 0.004 0.500 in ->
BUFFHVTD2 I ^ -> Z ^ 2 0.108 SPEF 0.322 0.450 0.822 I0/Z
BUFFHVTD2 I ^ -> Z ^ 1 0.104 SPEF 0.430 0.435 1.252 I2/Z
BUFFHVTD2 I ^ -> Z ^ 1 0.100 SPEF 0.418 0.419 1.669 I3/Z
- out2 ^ - 0.100 SPEF 0.001 0.419 1.670 out2 ->
--------------------------------------------------------------------------------

Notice here that you now show proper SPEF annotation in the report as well as your delay and slew values show the impact of the RC loading. These are more realistic
values. You can also use create_spice_deck, and you will have a better interconnect model for the Spice simulation.

Usage
read_lib ./LIB/STDCELL.lib
read_verilog ./3buf.v
set_top_module buf3​
source ./testspef.tcl
set mynets [ get_nets {in w* out*} ]​
testspef -net_collection $mynets -net_cap 0.1 -net_res 10.0 -outfile test.spef
read_spef test.spef
update_timing -full
report_timing -from in -to out1

Code
#################################################
# testspef.tcl
#################################################

define_proc_arguments testspef -info "Create test spef file." \


-define_args {
{ -net_collection "Net collection" "" string required }
{ -net_cap "Net cap" "" float required }
{ -net_res "Net res" "" float required }
{ -outfile "Output file" "" string required }
}

proc testspef { args } {

parse_proc_arguments -args $args opts


foreach argname [array names opts] {

switch $argname {
-net_collection {set net_coll $opts($argname)}
-net_cap {set net_cap $opts($argname)}
-net_res {set net_res $opts($argname)}
-outfile {set outfile $opts($argname)}
default { Puts "This should not happen" }
}
}

set wfp [ open $outfile w ]

set design [ dbget top.name ]

puts $wfp "*SPEF \"IEEE 1481-1998\""


puts $wfp "*DESIGN \"$design\""
puts $wfp "*DATE \"[exec date]\""
puts $wfp "*VENDOR \"testspef\""
puts $wfp "*PROGRAM \"testspef\""
puts $wfp "*VERSION \"0.1\""
puts $wfp "*DESIGN_FLOW \"testspef\""
puts $wfp "*DIVIDER /"
puts $wfp "*DELIMITER :"
puts $wfp "*BUS_DELIMITER \[\]"
puts $wfp "*T_UNIT 1 NS"
puts $wfp "*C_UNIT 1 PF"
puts $wfp "*R_UNIT 1 OHM"
puts $wfp "*L_UNIT 1 HENRY"
puts $wfp ""
puts $wfp "// MMMC spef file for corner 'testspef'"
puts $wfp ""

foreach_in_collection net $net_coll {


set net_nm [ get_object_name $net ]

puts $wfp "*D_NET ${net_nm} $net_cap"


puts $wfp ""
puts $wfp "*CONN"
foreach_in_collection net_pin [ add_to_collection [get_property $net driver_pins] [get_property $net load_pins] ] {
set p_dir [ get_property $net_pin direction ]

if {$p_dir == "in"} {set p_dir "I"} else {set p_dir "O"}


if {[get_property $net_pin object_type] == "port"} {
set p_name [ get_property $net_pin hierarchical_name ]
puts $wfp "*P $p_name $p_dir"
} elseif {[get_property $net_pin object_type] == "pin"} {
set p_name [ get_property $net_pin ref_lib_pin_name ]
set inst_nm [get_object_name [get_cells -of_objects $net_pin ]]
set inst_cell_nm [file tail [get_object_name [get_lib_cells -of_objects [get_cells -of_objects $net_pin ]]]]
puts $wfp "*I ${inst_nm}:${p_name} $p_dir *D $inst_cell_nm"
}
}
puts $wfp ""
puts $wfp "*CAP"
puts $wfp "1 ${net_nm}:1 $net_cap"

puts $wfp ""


puts $wfp "*RES"
set res_ct 1
foreach_in_collection driver_pin [ add_to_collection [get_property $net driver_pins] [get_property $net load_pins] ]
{
if {[get_property $driver_pin object_type] == "port"} {
set p_name [ get_property $driver_pin hierarchical_name ]
puts $wfp "$res_ct $p_name ${net_nm}:1 $net_res"
} elseif {[get_property $driver_pin object_type] == "pin"} {
set p_name [ get_property $driver_pin ref_lib_pin_name ]
set inst_nm [get_object_name [get_cells -of_objects $driver_pin ]]
puts $wfp "$res_ct ${inst_nm}:${p_name} ${net_nm}:1 $net_res"
}
incr res_ct
}
puts $wfp "*END"
puts $wfp ""
}
close $wfp
}

Internal Notes
None
Return to the top of the page

You might also like