5
5
# to point to the location of tclnetgen.so. Also see comments
6
6
# in shell script "netgen.sh".
7
7
#
8
-
8
+ # Added post make to allow for passing the env variable from bin/netgen
9
9
set NETGEN_HOME $::env(NETGEN_HOME)
10
10
11
11
# Check namespaces for existence of other applications
@@ -23,7 +23,7 @@ foreach i $nlist {
23
23
}
24
24
25
25
# -lazy option not needed if stubs libraries are handled correctly
26
- # load -lazy /home/ubuntu/sit-git-repos/silicon-vlsi-repos/eda-netgen /lib/netgen/tcl/tclnetgen.so
26
+ # load -lazy $NETGEN_HOME /lib/netgen/tcl/tclnetgen.so
27
27
28
28
load $NETGEN_HOME /lib/netgen/tcl/tclnetgen.so
29
29
@@ -64,16 +64,18 @@ proc netgen::convert_to_json {filename lvs_final} {
64
64
puts $fjson " \[ "
65
65
set cktval [lindex $value 0]
66
66
foreach pin [lrange $cktval 0 end-1] {
67
- puts $fjson " \" $pin \" ,"
67
+ set pinstr [string map {" \\ " " \\\\ " } $pin ]
68
+ puts $fjson " \" $pinstr \" ,"
68
69
}
69
- set pin [lindex $cktval end]
70
+ set pin [string map { " \\ " " \\\\ " } [ lindex $cktval end] ]
70
71
puts $fjson " \" $pin \" "
71
72
puts $fjson " \] , \[ "
72
73
set cktval [lindex $value 1]
73
74
foreach pin [lrange $cktval 0 end-1] {
74
- puts $fjson " \" $pin \" ,"
75
+ set pinstr [string map {" \\ " " \\\\ " } $pin ]
76
+ puts $fjson " \" $pinstr \" ,"
75
77
}
76
- set pin [lindex $cktval end]
78
+ set pin [string map { " \\ " " \\\\ " } [ lindex $cktval end] ]
77
79
puts $fjson " \" $pin \" "
78
80
puts $fjson " \] "
79
81
if {$kidx == $nkeys } {
@@ -395,7 +397,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
395
397
# If argument is a filename then read the list of cells from it;
396
398
# otherwise, argument is the list of files itself in quotes or
397
399
# braces.
398
- if {![ catch { file exists $value } ]} {
400
+ if {[ file exists $value ]} {
399
401
if {![catch {open $value r} fnf]} {
400
402
while {[gets $fnf line] >= 0} {
401
403
if {[lindex $line 0] != " #" } {
@@ -479,8 +481,12 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
479
481
480
482
netgen::compare assign " $fnum1 $cell1 " " $fnum2 $cell2 "
481
483
482
- if {[file exists $setupfile ]} {
483
- puts stdout " Reading setup file $setupfile "
484
+ if {$setupfile == " " } {
485
+ puts stdout " \n No setup file specified. Using trivial default setup.\n "
486
+ netgen::permute default ;# transistors and resistors
487
+ netgen::property default
488
+ } elseif {[file exists $setupfile ]} {
489
+ puts stdout " \n Reading setup file $setupfile \n "
484
490
# Instead of sourcing the setup file, run each line so we can
485
491
# catch individual errors and not let them halt the LVS process
486
492
set perrors 0
@@ -508,8 +514,10 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
508
514
puts stdout " Warning: There were errors reading the setup file"
509
515
}
510
516
} elseif {[string first nosetup $setupfile ] < 0} {
511
- netgen::permute default ;# transistors and resistors
512
- netgen::property default
517
+ puts stderr " \n Error: Setup file $setupfile does not exist.\n "
518
+ return
519
+ } else {
520
+ puts stderr " \n No setup file specified. Continuing without a setup.\n "
513
521
}
514
522
515
523
if {[string first nolog $logfile ] < 0} {
@@ -534,14 +542,24 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
534
542
}
535
543
set properr {}
536
544
set matcherr {}
537
- set pinsgood 0
545
+ set childMismatch 0 ; # 1 indicates black-box child subcircuit mismatch
538
546
while {$endval != {}} {
539
547
if {$dolist == 1} {
540
548
netgen::run -list converge
541
549
} else {
542
550
netgen::run converge
543
551
}
544
- netgen::log echo on
552
+ set pinMismatch 0 ;# indicates pin mismatch in top cell
553
+ set doCheckFlatten 0
554
+ set doFlatten 0
555
+ if {[netgen::print queue] == {}} {
556
+ set doEquatePins 1 ;# run equate pins on top cell
557
+ } else {
558
+ set doEquatePins 0 ;# don't run equate pins unless unique match
559
+ }
560
+ set forceMatch 0 ;# for pin matching
561
+ netgen::log echo off
562
+
545
563
if {[verify equivalent]} {
546
564
# Resolve automorphisms by pin and property
547
565
if {$dolist == 1} {
@@ -550,93 +568,105 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
550
568
netgen::run resolve
551
569
}
552
570
set uresult [verify unique]
571
+ # uresult: -3 : unique with property error
572
+ # -2 : equivalent with port errors
573
+ # -1 : black box
574
+ # 0 : equivalent but not unique
575
+ # 1 : unique
553
576
if {$uresult == 0} {
577
+ netgen::log echo on
554
578
netgen::log put " Networks match locally but not globally.\n "
555
579
netgen::log put " Probably connections are swapped.\n "
556
580
netgen::log put " Check the end of logfile ${logfile} for implicated nodes.\n "
581
+ netgen::log echo off
557
582
if {$dolist == 1} {
558
583
verify -list nodes
559
584
} else {
560
585
verify nodes
561
586
}
562
-
563
- # Flatten the non-matching subcircuit (but not the top-level cells)
564
- if {[netgen::print queue] != {}} {
565
- if {([lsearch $noflat [lindex $endval 0]] == -1) &&
587
+ set doCheckFlatten 1
588
+ } else {
589
+ # Equate pins for black boxes, unique matches (possibly with property
590
+ # errors), and unique with port errors
591
+ set doEquatePins 1
592
+ }
593
+ if {$uresult == -1} { ;# black box
594
+ set forceMatch 1
595
+ } elseif {$uresult == -3} { ;# property error
596
+ lappend properr [lindex $endval 0]
597
+ } elseif {$uresult == -2} { ;# unmatched pins
598
+ set doCheckFlatten 1
599
+ }
600
+ } else {
601
+ # not equivalent
602
+ netgen::log echo on
603
+ # netgen::log put " DEBUG: not equivalent $endval\n"
604
+ netgen::log echo off
605
+ set doCheckFlatten 1
606
+ }
607
+ if {$doCheckFlatten } {
608
+ # Flatten the non-matching subcircuit (but not the top-level cell,
609
+ # or cells explicitly prohibited from flattening)
610
+ if {[netgen::print queue] != {}} {
611
+ if {([lsearch $noflat [lindex $endval 0]] == -1) &&
566
612
([lsearch $noflat [lindex $endval 1]] == -1)} {
567
- netgen::log put " Flattening non-matched subcircuits $endval "
568
- netgen::flatten class " [ lindex $endval 0] $fnum1 "
569
- netgen::flatten class " [ lindex $endval 1] $fnum2 "
570
- } else {
571
- netgen::log put " Continuing with black-boxed subcircuits $endval "
572
- lappend matcherr [lindex $endval 0]
573
- # Match pins
574
- netgen::log echo off
575
- if {$dolist == 1} {
576
- set result [equate -list -force pins " $fnum1 [ lindex $endval 0] " \
613
+ set doFlatten 1
614
+ } else {
615
+ netgen::log echo on
616
+ netgen::log put " Continuing with black-boxed subcircuits $endval \n "
617
+ netgen::log echo off
618
+ lappend matcherr [lindex $endval 0]" ($fnum1 )"
619
+ lappend matcherr [lindex $endval 1]" ($fnum2 )"
620
+ netgen::flatten prohibit " [ lindex $endval 0] $fnum1 "
621
+ netgen::flatten prohibit " [ lindex $endval 1] $fnum2 "
622
+ set doEquatePins 1
623
+ set childMismatch 1
624
+ set forceMatch 1
625
+ }
626
+ }
627
+ }
628
+ if {$doEquatePins } {
629
+ # Match pins
630
+ if {$dolist == 1} {
631
+ if {$forceMatch } {
632
+ set result [equate -list -force pins " $fnum1 [ lindex $endval 0] " \
577
633
" $fnum2 [ lindex $endval 1] " ]
578
- } else {
579
- set result [equate -force pins " $fnum1 [ lindex $endval 0] " \
634
+ } else {
635
+ set result [equate -list pins " $fnum1 [ lindex $endval 0] " \
580
636
" $fnum2 [ lindex $endval 1] " ]
581
- }
582
- if {$result != 0} {
583
- equate classes " $fnum1 [ lindex $endval 0] " \
584
- " $fnum2 [ lindex $endval 1] "
585
- }
586
- set pinsgood $result
587
- netgen::log echo on
588
- }
589
637
}
590
638
} else {
591
- # Match pins
592
- netgen::log echo off
593
- if {$dolist == 1} {
594
- set result [equate -list pins " $fnum1 [ lindex $endval 0] " \
639
+ if {$forceMatch } {
640
+ set result [equate -force pins " $fnum1 [ lindex $endval 0] " \
595
641
" $fnum2 [ lindex $endval 1] " ]
596
642
} else {
597
- set result [equate pins " $fnum1 [ lindex $endval 0] " \
643
+ set result [equate pins " $fnum1 [ lindex $endval 0] " \
598
644
" $fnum2 [ lindex $endval 1] " ]
599
645
}
600
- if {$result != 0} {
601
- equate classes " $fnum1 [ lindex $endval 0] " \
602
- " $fnum2 [ lindex $endval 1] "
603
- }
604
- set pinsgood $result
605
- netgen::log echo on
606
646
}
607
- if {$uresult == 2} {lappend properr [lindex $endval 0]}
608
- } else {
609
- # Flatten the non-matching subcircuit (but not the top-level cells)
610
- if {[netgen::print queue] != {}} {
611
- if {([lsearch $noflat [lindex $endval 1]] == -1) &&
612
- ([lsearch $noflat [lindex $endval 1]] == -1)} {
613
- netgen::log put " Flattening non-matched subcircuits $endval "
614
- netgen::flatten class " [ lindex $endval 0] $fnum1 "
615
- netgen::flatten class " [ lindex $endval 1] $fnum2 "
616
- } else {
617
- netgen::log put " Continuing with black-boxed subcircuits $endval "
618
- lappend matcherr [lindex $endval 0]
619
- netgen::log put " Continuing with black-boxed subcircuits $endval "
620
- lappend matcherr [lindex $endval 0]
621
- # Match pins
622
- netgen::log echo off
623
- if {$dolist == 1} {
624
- set result [equate -list -force pins " $fnum1 [ lindex $endval 0] " \
625
- " $fnum2 [ lindex $endval 1] " ]
626
- } else {
627
- set result [equate -force pins " $fnum1 [ lindex $endval 0] " \
628
- " $fnum2 [ lindex $endval 1] " ]
629
- }
630
- if {$result != 0} {
631
- equate classes " $fnum1 [ lindex $endval 0] " \
632
- " $fnum2 [ lindex $endval 1] "
633
- }
634
- set pinsgood $result
635
- netgen::log echo on
647
+ if {$result >= 0} {
648
+ equate classes " $fnum1 [ lindex $endval 0] " \
649
+ " $fnum2 [ lindex $endval 1] "
650
+ }
651
+ # Do not set pinMismatch for black boxes
652
+ if {$result < 0} {
653
+ if {$result == -1 && [netgen::print queue] != {} && $forceMatch != 1} {
654
+ # flatten pin mismatch, but not empty cells (-2) or top cell or
655
+ # cells prohibited from flattening.
656
+ set doFlatten 1
636
657
}
658
+ } elseif {[netgen::print queue] == {} && $result == 0} {
659
+ set pinMismatch 1
637
660
}
638
661
}
639
- netgen::log echo off
662
+ if {$doFlatten } {
663
+ netgen::log echo on
664
+ netgen::log put " Flattening non-matched subcircuits $endval \n "
665
+ netgen::log echo off
666
+ netgen::flatten class " [ lindex $endval 0] $fnum1 "
667
+ netgen::flatten class " [ lindex $endval 1] $fnum2 "
668
+ }
669
+
640
670
if {$dolist == 1} {
641
671
catch {lappend lvs_final $lvs_out }
642
672
set lvs_out {}
@@ -645,19 +675,23 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
645
675
set endval [netgen::compare hierarchical]
646
676
}
647
677
}
648
- netgen::log echo off
649
- puts stdout " Result: " nonewline
650
678
netgen::log echo on
651
- if {$pinsgood == 0} {
652
- netgen::log put " The top level cell failed pin matching.\n "
679
+ netgen::log put " \n Final result: "
680
+ if {$pinMismatch || $childMismatch } {
681
+ if {$childMismatch } {
682
+ netgen::log put " Subcell(s) failed matching.\n "
683
+ }
684
+ if {$pinMismatch } {
685
+ netgen::log put " Top level cell failed pin matching.\n "
686
+ }
653
687
} else {
654
688
verify only
655
689
}
656
690
if {$properr != {}} {
657
- netgen::log put " The following cells had property errors: $properr \n "
691
+ netgen::log put " \n The following cells had property errors:\n " [ regsub -all { } $properr " \n "] " \n "
658
692
}
659
693
if {$matcherr != {}} {
660
- netgen::log put " The following subcells failed to match: $matcherr \n "
694
+ netgen::log put " \n The following subcells failed to match:\n " [ regsub -all { } $matcherr " \n "] " \n "
661
695
}
662
696
if {$dolog } {
663
697
netgen::log end
@@ -709,6 +743,19 @@ set auto_noexec 1 ;# don't EVER call UNIX commands w/o "shell" in front
709
743
# Cross-Application section
710
744
# ----------------------------------------------------------------------
711
745
746
+ # For use with open_pdks, set PDK_ROOT from the environment. If no
747
+ # such environment variable exists, check some common locations.
748
+
749
+ if {[catch {set PDK_ROOT $::env(PDK_ROOT) }]} {
750
+ if {[file isdir /usr/local/share/pdk] == 1} {
751
+ set PDK_ROOT /usr/local/share/pdk
752
+ } elseif {[file isdir /usr/share/pdk] == 1} {
753
+ set PDK_ROOT /usr/share/pdk
754
+ } elseif {[file isdir /foss/pdk] == 1} {
755
+ set PDK_ROOT /foss/pdk
756
+ }
757
+ }
758
+
712
759
# Setup IRSIM assuming that the Tcl version is installed.
713
760
# We do not need to rename procedure irsim to NULL because it is
714
761
# redefined in a script, which simply overwrites the original.
0 commit comments