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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 | ###############################################################################
# Copyright (c) 2013-2024 by Altair Engineering, Inc.
# All rights reserved.
#
# Altair Engineering, Inc. makes this software available as part of the Vision
# tool platform. As long as you are a licensee of the Vision tool platform
# you may make copies of the software and modify it to be used within the
# Vision tool platform, but you must include all of this notice on any copy.
# Redistribution without written permission to any third party, with or
# without modification, is not permitted.
# Altair Engineering, Inc. does not warrant that this software is error free
# or fit for any purpose. Altair Engineering, Inc. disclaims any liability for
# all claims, expenses, losses, damages and costs any user may incur as a
# result of using, copying or modifying the software.
# =============================================================================
# @script
# Input:
# Read simple cadstar netlist report and create zdb database file.
#
# Known Issues:
# Beta.
#
# Usage:
# *visionpro -userware2 ../demo/api/cust23/cadstar.tcl design.net
# to directly read the given design file.
# or
# *visionpro -userware ../demo/api/cust23/cadstar.tcl
# to use the menu entry Userware->Import Cadstar to open the design
# file.
#
# Processing:
#
# sheet lines:
# "Sheet name : Block"
# Sheet names are used for creating additional hierarchy, if enabled.
#
# partlines:
# "G00068 TRANSISTOR MOSFET N-CH ENH. 3P Q403 2N7002"
#
# Because the type (2th column) and part (4th column) of the part
# lines may contain blanks, and the port names are missing,
# we can not directly create cells in zdb.
# Instead we store each line indexed by first 'no' field (G000xx)
# and hash each word separated by blanks.
# So we can search for reference designators later when reference
# designators are definitely known in the connectivity section.
#
# e.g.
# no => G00068
# partline => "TRANSISTOR" "MOSFET" "N-CH" "ENH." "3P" "Q403" "2N7002"
#
# refdes => "Q403"
# type => "TRANSISTOR MOSFET N-CH ENH. 3P"
# part => "2N7002"
#
# net line:
# "Net 21 : USB_DM"
#
# Net lines are used to get name of nets. If there is only the net
# number a "unnamed" net name is created.
#
# connectivity line:
# "Q403 1/1 U200-H 5/E2{MSI XXX}"
#
# Because pin names contain blanks in curly brackets we map them
# to "\1". So we can use tcl split and than map them back to blanks.
#
# When the refdes is known we search them in the partlist and
# accumulate the port names.
#
# When all nets are read, we create modules, instances, net and
# connectivity.
#
###############################################################################
# =============================================================================
# global settings
# =============================================================================
#
set Cadstar(hier) 1 ;# enable hierarchy creation at sheets
set Cadstar(func) 1 ;# create function for known parts
# -----------------------------------------------------------------------------
# _msg - Show a message of the given type with file and line info.
# Use command line option -info to filter messages.
# -----------------------------------------------------------------------------
#
proc Cadstar:_msg {type msg} {
global Cadstar
zmessage print $type $msg $Cadstar(nlFname) $Cadstar(lineNo)
}
# -----------------------------------------------------------------------------
# _processPart - Store values from part section
# Cadstar(partLines:$no) contains partInfo for $no
# Cadstar(sheetName:$no) contains sheetname of $no
# Cadstar(wordCadstar:$word) contains mapping from each
# potential refDes to $no
# -----------------------------------------------------------------------------
#
proc Cadstar:_processPart {line} {
global Cadstar
set s [split $line]
set no [lindex $s 0]
set partInfo [lrange $s 1 end ]
Cadstar:_msg "DBG" "part: '$no' - '$partInfo'"
set Cadstar(lineNo:$no) $Cadstar(lineNo)
set Cadstar(partLines:$no) $partInfo
set Cadstar(sheetName:$no) $Cadstar(sheetName)
foreach word $partInfo {
lappend Cadstar(wordCadstar:$word) $no
}
}
# -----------------------------------------------------------------------------
# _mapBlanks - replace blanks in curly brackets by "\1"
# this is needed for split in connectivity section
# with pin names which seem to contain blanks.
# -----------------------------------------------------------------------------
#
proc Cadstar:_mapBlanks {lineName} {
upvar 1 $lineName line
set str {}
set in 0
set len [string length $line]
for {set i 0} {$i < $len} {incr i} {
set c [string index $line $i]
if {$c == "\{"} {
set in 1
} elseif {$c == "\}"} {
set in 0
} elseif {$c == " "} {
if {$in} {
set c "\1"
}
}
append str $c
}
set line $str
}
# -----------------------------------------------------------------------------
# _processConn - get ref/pin pairs
# because some pins contain blanks in pin names (in curly
# brackets) we map them to underscore with 'mapBlanks' and map
# back after split.
#
# Connectivity information is stored in Cadstar(nets:$netname)
# as ref/pin pairs.
# All portnames are stored as value of a Cadstar(refdes:$ref)
# hashtable for later processing.
# -----------------------------------------------------------------------------
#
proc Cadstar:_processConn {line} {
global Cadstar
Cadstar:_mapBlanks line
set state "ref"
##
# maybe split not good enough?
#
foreach str [split $line] {
if {$str == {}} {
continue
}
switch -- $state {
"ref" {
set ref $str
set state "pin"
}
"pin" {
set pin $str
set state "ref"
set pin [string map {"\1" " "} $pin]
Cadstar:_msg "DBG" "connection: '$ref' - '$pin'"
lappend Cadstar(nets:$Cadstar(netName)) [list $ref $pin]
lappend Cadstar(refdes:$ref) $pin
}
default {}
}
}
if {$state == "pin"} {
Cadstar:_msg "WAR" "ref $ref without pin ?"
}
}
# -----------------------------------------------------------------------------
# _createDB - createDB
# -----------------------------------------------------------------------------
#
proc Cadstar:_createDB {} {
global Cadstar
set db $Cadstar(db)
##
# loop over all refdes from connectivity section
# and collect part infos
#
foreach name [array names Cadstar refdes:*] {
set ref [string range $name 7 end]
##
# check for ref in part section
#
if {![info exists Cadstar(wordCadstar:$ref)]} {
Cadstar:_msg "WAR" "no part info for '$ref' found"
continue
}
##
# check for uniq part of this ref
#
set len [llength $Cadstar(wordCadstar:$ref)]
if {$len > 1} {
Cadstar:_msg "WAR" "ref '$ref' not uniquely found\
in part section ($Cadstar(wordCadstar:$ref))"
continue
}
##
# recreate type, ref, part from part section
# using index of ref as a delimiter
#
set no [lindex $Cadstar(wordCadstar:$ref) 0]
set partInfo $Cadstar(partLines:$no)
set idx [lsearch $partInfo $ref]
if {$idx < 0} {
##
# this should hopefully not happen ;-)
#
Cadstar:_msg "WAR" "ref '$ref' not found in partInfo\
'$Cadstar(partLines:$no)' of $no"
continue
}
set type [string trim [join [lrange $partInfo 0 [expr {$idx - 1}]]]]
set part [string trim [join [lrange $partInfo [expr {$idx + 1}] end]]]
Cadstar:_msg "DBG" "partInfo: '$ref' '$type' '$part'"
set Cadstar(refType:$ref) $type
set Cadstar(refPart:$ref) $part
set Cadstar(refNo:$ref) $no
##
# collect all ports for each part, because
# not all refdes instances for one part will have same set of ports
#
foreach pin $Cadstar(refdes:$ref) {
lappend Cadstar(ports:$part) $pin
}
}
##
# loop over all collected refdes
# create parts once
#
foreach name [array names Cadstar refdes:*] {
set ref [string range $name 7 end]
set part $Cadstar(refPart:$ref)
if {[$db search cell $part]=="null"} {
Cadstar:_msg "DBG" "create module $part"
if {[zlicense permit spice]} {
set spice 1
} else {
set spice 0
}
if {$spice} {
set cmd [list $db load primitive $part]
} else {
set cmd [list $db load module $part]
}
if {$Cadstar(func)} {
#checker -scope block exclude warnStyleNesting
switch -glob -- $Cadstar(refType:$ref) {
"RES" -
"CAP" {
set portCount [llength $Cadstar(ports:$part)]
if {$spice} {
if {$portCount > 1} {
lappend cmd $Cadstar(refType:$ref)
} else {
lappend cmd unknown
}
} else {
lappend cmd -primfunc $Cadstar(refType:$ref)
}
}
default {
if {$spice} {
lappend cmd unknown
}
}
}
}
eval $cmd
##
# create ports in sorted order
#
foreach port [lsort -unique -dictionary $Cadstar(ports:$part)] {
Cadstar:_msg "DBG" " create port $port"
$db load port $port "*"
}
}
}
##
# create top module
#
$db load module $Cadstar(designName) -top
##
# create instance incl. spos of line
#
foreach name [array names Cadstar refdes:*] {
set ref [string range $name 7 end]
set part $Cadstar(refPart:$ref)
set no $Cadstar(refNo:$ref) ;# get uniq no of ref
set lineNo $Cadstar(lineNo:$no) ;# get lineNo of ref
set begEnd [$db spos filepos $Cadstar(nlFname) $lineNo]
set beg [lindex $begEnd 0]
set end [lindex $begEnd 1]
$db load inst $ref $part -spos $Cadstar(nlFname) $beg $end
if {$Cadstar(hier)} {
set sheetName $Cadstar(sheetName:$no) ;# get sheetname
set inst [$db oid create [list inst $Cadstar(designName) $ref]]
lappend Cadstar(hier:$sheetName) $inst
}
}
##
# create all nets and connectivity
#
foreach name [array names Cadstar nets:*] {
set net [string range $name 5 end]
set cmd [list $db load net $net]
set lineNo $Cadstar(netLineNo:$net) ;# get lineNo of net
set begEnd [$db spos filepos $Cadstar(nlFname) $lineNo]
set beg [lindex $begEnd 0]
set end [lindex $begEnd 1]
lappend cmd -spos $Cadstar(nlFname) $beg $end
foreach conn $Cadstar(nets:$net) {
set ref [lindex $conn 0]
set pin [lindex $conn 1]
lappend cmd -pin $ref $pin
}
##
# flag power/ground nets
#
switch -glob -nocase -- $net {
"*GROUND*" -
"*GND*" {lappend cmd -flag ground}
"*PWR*" -
"P[0-9].[0-9]V" -
"P[0-9]V" {lappend cmd -flag power}
default {}
}
eval $cmd
}
if {$Cadstar(hier)} {
##
# create sheet hierarchy
#
foreach name [array names Cadstar hier:*] {
set sheetName [string range $name 5 end]
set instList $Cadstar(hier:$sheetName)
$db oper addhier $sheetName $sheetName $instList
}
}
}
# -----------------------------------------------------------------------------
# _import - importCadStar
# -----------------------------------------------------------------------------
#
proc Cadstar:_import {nlFname {dbFname {}} {hier {}} {func {}}} {
global Cadstar
##
# get input file
#
set in [open $nlFname r]
chan configure $in -translation binary
##
# get design name
#
set Cadstar(designName) [file rootname [file tail $nlFname]]
##
# create DB
#
if {$dbFname == {}} {
set dbFname "$Cadstar(designName).zdb"
}
set db [zdb new]
##
# add spos file
#
$db spos addfile $nlFname
##
# init globals
#
set Cadstar(db) $db
set Cadstar(nlFname) $nlFname
set Cadstar(lineNo) 0
set Cadstar(filePos) 0
set Cadstar(sheetName) {}
set Cadstar(netName) {}
if {$hier != {}} {
set Cadstar(hier) $hier
}
if {$func != {}} {
set Cadstar(func) $func
}
##
# read line by line
#
while {[gets $in line] >= 0} {
##
# handle global lineNo, filePos and spos lineno info
#
incr Cadstar(lineNo)
incr Cadstar(filePos) [string length $line]
$db spos addline $nlFname $Cadstar(lineNo) $Cadstar(filePos)
incr Cadstar(filePos)
set line [string trim $line]
switch -regexp -- $line {
{^[ \t]*$} {
##
# skip empty line
#
continue
}
{^Sheet name :.*$} {
##
# get current sheet name
#
set Cadstar(sheetName) [string range $line 13 end]
Cadstar:_msg "DBG" "Sheet '$Cadstar(sheetName)'"
}
{^Net .*$} {
##
# get current net
#
set l [split [string range $line 3 end] ":"]
set Cadstar(netName) [string trim [lindex $l 1]]
if {$Cadstar(netName) == {}} {
set Cadstar(netName) "unnamed[string trim [lindex $l 0]]"
}
Cadstar:_msg "DBG" "Net '$Cadstar(netName)'"
##
# store lineNo to create spos later
#
set Cadstar(netLineNo:$Cadstar(netName)) $Cadstar(lineNo)
}
default {
##
# get instance or pins
#
if {$Cadstar(netName) == {}} {
##
# instance section
#
Cadstar:_processPart $line
} else {
##
# net section
#
Cadstar:_processConn $line
}
}
}
}
##
# register spos end of file
#
$db spos addline $nlFname end $Cadstar(filePos)
##
# create db
#
Cadstar:_createDB
$db save $dbFname
$db close
close $in
##
# open in GUI.
#
set db [zdb open $dbFname]
gui database changed $db
}
# -----------------------------------------------------------------------------
# _loadFile - file dialog
# -----------------------------------------------------------------------------
#
proc Cadstar:_loadFile {} {
set f [gui window fileDialog openFile \
"Open a Cadstar file" {{"Cadstar" {".net"}}}]
if {$f == "" } {
return
}
Cadstar:_import $f
}
##
# create menu entry
#
gui menu command {"Userware" "Import Cadstar"} {Cadstar:_loadFile}
##
# direct start if -userware2 is used
#
if {$argc> 0} {
Cadstar:_import [lindex $argv 0]
}
|