File: getpowerground.tcl.in

package info (click to toggle)
qflow 1.3.17%2Bdfsg.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,852 kB
  • sloc: ansic: 8,342; csh: 3,873; sh: 2,869; makefile: 426; tcl: 6
file content (152 lines) | stat: -rwxr-xr-x 5,186 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!TCLSH_PATH
#---------------------------------------------------------------------------
# getpowerground.tcl ---
#
# Read LEF file up to the first macro with a PIN record having
# USE POWER and one having USE GROUND.  Return the pin names.
#
#---------------------------------------------------------------------------
namespace path {::tcl::mathop ::tcl::mathfunc}

if {$argc < 1} {
   puts stdout "Usage:  getpowerground <lef_file>"
   exit 0
}

puts stdout "Running getpowerground.tcl"

set lefname [lindex $argv 0]

set vddnet ""
set gndnet ""

#-----------------------------------------------------------------
# Open lef file for reading
#-----------------------------------------------------------------

if [catch {open $lefname r} flef] {
   puts stderr "Error: can't open file $lefname for input"
   return
}

#----------------------------------------------------------------
# Read through a LEF file section that we don't care about.
#----------------------------------------------------------------

proc skip_section {leffile sectionname} {
   while {[gets $leffile line] >= 0} {
      if [regexp {[ \t]*END[ \t]+([^ \t]+)[ \t]*$} $line lmatch sectiontest] {
         if {"$sectiontest" != "$sectionname"} {
            puts -nonewline stderr "Unexpected END statement $line "
            puts stderr "while reading section $sectionname"
         }
         break
      }
   }
}

#----------------------------------------------------------------
# Parse the pin contents of the LEF file macro
#----------------------------------------------------------------

proc parse_pin {leffile pinname} {
    global vddnet
    global gndnet

    set portuse ""
    while {[gets $leffile line] >= 0} {
        if [regexp {[ \t]*USE[ \t]+([^ \t]+)[ \t]*;} $line lmatch portuse] {
            set portuse [string toupper $portuse]
            if {$portuse == "GROUND"} {
                set gndnet $pinname
	    } elseif {$portuse == "POWER"} {
                set vddnet $pinname
            }
        } elseif [regexp {[ \t]*END[ \t]+([^ \t]+)[ \t]*$} $line lmatch pintest] {
            if {"$pintest" == "$pinname"} {
                break
            } else {
                puts stdout "Unexpected END statement $line while parsing pin $pinname"
            }
        }
    }
}

#----------------------------------------------------------------
# Parse the macro contents of the LEF file and retain the information
# about pin use.
#----------------------------------------------------------------

proc parse_macro {leffile macroname} {
   global vddnet
   global gndnet

   while {[gets $leffile line] >= 0} {
      if [regexp {[ \t]*PIN[ \t]+(.+)[ \t]*$} $line lmatch pinname] {
         parse_pin $leffile $pinname
      } elseif [regexp {[ \t]*END[ \t]+([^ \t]+)[ \t]*$} $line lmatch macrotest] {
         if {"$macrotest" == "$macroname"} {
            break
         } else {
            puts stderr "Unexpected END statement $line while reading macro $macroname"
         }
      }
   }
}

#-----------------------------------------------------------------
# Read the lef macro file and get the fill cells and their widths
#-----------------------------------------------------------------

puts stdout "Reading macros from LEF file."
flush stdout

while {[gets $flef line] >= 0} {
   if [regexp {[ \t]*MACRO[ \t]+(.+)[ \t]*$} $line lmatch macroname] {
      # Parse the "macro" statement
      parse_macro $flef $macroname
      # Probably the power and ground nets will be set after the first
      # macro is read.
      if {($vddnet != "") && ($gndnet != "")} {break}
   } elseif [regexp {[ \t]*LAYER[ \t]+([^ \t]+)} $line lmatch layername] {
      skip_section $flef $layername
   } elseif [regexp {[ \t]*VIA[ \t]+([^ \t]+)} $line lmatch vianame] {
      skip_section $flef $vianame
   } elseif [regexp {[ \t]*VIARULE[ \t]+([^ \t]+)} $line lmatch viarulename] {
      skip_section $flef $viarulename
   } elseif [regexp {[ \t]*SITE[ \t]+(.+)[ \t]*$} $line lmatch sitename] {
      skip_section $flef $sitename
   } elseif [regexp {[ \t]*SPACING[ \t]*$} $line lmatch] {
      skip_section $flef SPACING
   } elseif [regexp {[ \t]*UNITS[ \t]*$} $line lmatch] {
      skip_section $flef UNITS
   } elseif [regexp {[ \t]*END[ \t]+LIBRARY[ \t]*$} $line lmatch] {
      break
   } elseif [regexp {^[ \t]*#} $line lmatch] {
      # Comment line, ignore.
   } elseif ![regexp {^[ \t]*$} $line lmatch] {
      # Other things we don't care about
      set matches 0
      if [regexp {[ \t]*NAMESCASESENSITIVE} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*VERSION} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*BUSBITCHARS} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*DIVIDERCHAR} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*USEMINSPACING} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*CLEARANCEMEASURE} $line lmatch] {
         incr matches
      } elseif [regexp {[ \t]*MANUFACTURINGGRID} $line lmatch] {
         incr matches
      }
   }
}

close $flef

puts stdout "vddnet=$vddnet"
puts stdout "gndnet=$gndnet"
puts stdout "Done with getpowerground.tcl"