1 #------------------------------------------
3 #------------------------------------------
4 # This script should be sourced into
5 # XCircuit and provides the capability to
6 # translate .sue files into XCircuit
7 # schematics. This script works properly
8 # with XCircuit version 3.2.24 or newer.
9 #------------------------------------------
10 # The primary routine is "make_sue_all",
11 # which is a TCL procedure to be run from
12 # the XCircuit command line in the directory
13 # containing .sue format files. Without
14 # options, it creates a single XCircuit
15 # PostScript output file "sue_gates.ps",
16 # containing all of the gate symbols and
17 # associated schematics in a single file.
18 #------------------------------------------
19 # Written by R. Timothy Edwards
23 #------------------------------------------
28 #------------------------------------------------------------
29 # scale an {x y} list value from SUE units to XCircuit units
30 #------------------------------------------------------------
32 proc scale_coord
{coord
} {
34 set x
[lindex $coord 0]
35 set y
[lindex $coord 1]
36 set newc
[lreplace $coord 0 1 [expr {int
($x * $fscale)}] \
37 [expr {int
(-$y * $fscale)}]]
41 #------------------------------------------------------------
42 # make and make_wire: create the schematic elements
43 #------------------------------------------------------------
45 proc make
{type args
} {
48 if {[llength $args] == 1} {
49 set args
[lindex $args 0]
59 set instance_params
{}
61 foreach {key value
} $args {
69 set flipped horizontal
102 lappend instance_params
[list [string range
$key 1 end
] $value]
107 set origin
[scale_coord
$origin]
111 set newgate
[instance make pMOS
$origin]
112 # SUE pMOS is wider than xcircuit pMOS.
113 set x1
[lindex $origin 0]
114 set s1
[lreplace $origin 0 0 [expr {$x1 - 64}]]
115 set s2
[lreplace $origin 0 0 [expr {$x1 - 96}]]
116 set newpoly
[polygon make
2 $s1 $s2]
118 parameter
set width
$width -forward
119 parameter
set length
$length -forward
120 select
[list $newgate $newpoly]
121 rotate
$angle $origin
122 if {$flipped != {}} {
123 select
[list $newgate $newpoly]
124 flip
$flipped $origin
129 set newgate
[instance make nMOS
$origin]
130 # SUE nMOS is wider than xcircuit nMOS.
131 set x1
[lindex $origin 0]
132 set s1
[lreplace $origin 0 0 [expr {$x1 - 64}]]
133 set s2
[lreplace $origin 0 0 [expr {$x1 - 96}]]
134 set newpoly
[polygon make
2 $s1 $s2]
136 parameter
set width
$width -forward
137 parameter
set length
$length -forward
138 select
[list $newgate $newpoly]
139 rotate
$angle $origin
140 if {$flipped != {}} {
141 select
[list $newgate $newpoly]
142 flip
$flipped $origin
150 set newtext
[label make pin
$name $origin]
151 rotate
$newtext $angle $origin
152 if {$flipped != {}} {
153 flip
$newtext $flipped $origin
158 set newtext
[label make
global $name $origin]
159 rotate
$newtext $angle $origin
160 if {$flipped != {}} {
161 flip
$newtext $flipped $origin
166 set newtext
[list $name]
167 while {[set rp
[string first
\n $newtext]] >= 0} {
168 set newtext
[string replace
$newtext $rp $rp "\} \{return\} \{"]
169 set rp
[string first
\n $newtext]
171 set newtext
[label make normal
$newtext $origin]
172 rotate
$newtext $angle $origin
173 if {$flipped != {}} {
174 flip
$newtext $flipped $origin
178 # Default behavior is to generate an object instance of the
179 # given name. This assumes that these are only objects that
180 # have been defined in .sue files already.
183 set newgate
[instance make
$type $origin]
185 rotate
$angle $origin
186 if {$flipped != {}} {
188 flip
$flipped $origin
190 if {$instance_params != {}} {
192 foreach pair
$instance_params {
193 set key
[lindex $pair 0]
194 set value
[lindex $pair 1]
195 parameter
set $key $value -forward
204 #------------------------------------------------------------
205 # Draw text on the schematic
206 #------------------------------------------------------------
208 proc make_text
{args
} {
212 #------------------------------------------------------------
213 # Draw a wire into the schematic
214 #------------------------------------------------------------
216 proc make_wire
{x1 y1 x2 y2
} {
218 # Scale the origin from SUE units to XCircuit units
219 set sx1
[expr {int
($x1 * $fscale)}]
220 set sy1
[expr {int
(-$y1 * $fscale)}]
221 set sx2
[expr {int
($x2 * $fscale)}]
222 set sy2
[expr {int
(-$y2 * $fscale)}]
223 polygon make
2 [list $sx1 $sy1] [list $sx2 $sy2]
226 proc make_line
{args
} {
227 eval "make_wire $args"
230 #------------------------------------------------------------
231 # icon_*: create the symbol
232 #------------------------------------------------------------
234 #------------------------------------------------------------
235 # default parameters (deferred)
236 #------------------------------------------------------------
238 proc icon_setup
{icon_args params
} {
240 set icon_params
[concat $icon_params $params]
243 #------------------------------------------------------------
245 #------------------------------------------------------------
247 proc icon_term
{args
} {
250 set name
"bad_pin_name"
252 foreach {key value
} $args {
265 set newtext
[label make pin
$name $origin]
268 #------------------------------------------------------------
269 # instance parameters and symbol text labels
270 #------------------------------------------------------------
272 proc icon_property
{args
} {
276 set name
"bad_parameter"
278 foreach {key value
} $args {
290 # label size. Ignore, for now.
293 label make normal
"$value" [scale_coord
$origin]
299 #------------------------------------------------------------
300 # Line drawing on the symbol
301 #------------------------------------------------------------
303 proc icon_line
{args
} {
306 foreach {x y
} $args {
307 set s
[scale_coord
[list $x $y]]
311 eval "polygon make $i $coords"
314 #------------------------------------------------------------
315 # Main routine: Load the .sue file for the indicated
316 # gate. Draw the schematic and the (user library) symbol,
317 # and associate them.
318 #------------------------------------------------------------
320 proc make_sue_gate
{name
} {
324 # Go to a new page unless the current one is empty
325 while {[llength [object parts
]] > 0} {
328 while {[catch {page
$p}]} {
333 # Evaluate the symbol. Generate the symbol in xcircuit.
334 # Then clear the page to make the schematic
337 set hlist
[object parts
]
338 object make
$name $hlist
339 set hlist
[object parts
]
341 foreach pair
$icon_params {
342 set key
[lindex $pair 0]
343 set value
[lindex $pair 1]
347 # Do nothing for now. These are library instance values
348 # in xcircuit, and could be set as such.
351 parameter make substring
$key [list $value]
358 eval "SCHEMATIC_${name}"
360 schematic associate
$name
364 #------------------------------------------------------------
365 # Top-level routine: Find all the .sue files in the
366 # current directory and generate a library from them
367 #------------------------------------------------------------
369 proc make_all_sue
{{name sue_gates
}} {
370 set files
[glob \*.sue
]
372 set filename [file tail
[file root
$i]]
373 make_sue_gate
$filename
376 page encapsulation full
378 if {[page
scale] > 1.0} {