Git Product home page Git Product logo

netgen's People

Contributors

antonblanchard avatar ax3ghazy avatar d-m-bailey avatar donn avatar hpretl avatar just22 avatar kammoh avatar lankasaicharan avatar mithro avatar rtimothyedwards avatar thejackal360 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

netgen's Issues

Verilog ports shorted with assign statements in subcells are not handled correctly.

Netgen 1.5.253
Using verilog generated from Cadence Innovus.

  1. From sky130 mpw-4 slot-005, the user_proj_example has many ports shorted.

    assign VWPR = VPWR;
    assign wbs_ack_o = io_oeb[27];
    assign wbs_dat_o[31] = io_oeb[27];
    assign wbs_dat_o[30] = io_oeb[27];
    assign wbs_dat_o[29] = io_oeb[27];
    assign wbs_dat_o[28] = io_oeb[27];
    assign wbs_dat_o[27] = io_oeb[27];
    assign wbs_dat_o[26] = io_oeb[27];
    assign wbs_dat_o[25] = io_oeb[27];
    assign wbs_dat_o[24] = io_oeb[27];
    assign wbs_dat_o[23] = io_oeb[27];
    assign wbs_dat_o[22] = io_oeb[27];
    assign wbs_dat_o[21] = io_oeb[27];
    assign wbs_dat_o[20] = io_oeb[27];
    ...
    

    When used as is, netgen generates results indicating that the internal netlist has been corrupted.

    Net: _noconnect_4_
    sky130_fd_sc_hd__a22o_1/X = 4
    sky130_fd_sc_hd__and2_1/X = 18
    sky130_fd_sc_hd__and3b_1/X = 4
    sky130_fd_sc_hd__conb_1/HI = 1
    sky130_fd_sc_hd__mux2_2/A0 = 16
    sky130_fd_sc_hd__mux2_2/A1 = 16
    sky130_fd_sc_hd__nand4_1/C = 1
    sky130_fd_sc_hd__nand4_1/D = 1
    sky130_fd_sc_hd__or4bb_1/C_N = 1
    sky130_fd_sc_hd__sdfrtn_1/D = 3
    sky130_fd_sc_hd__sdfrtn_1/RESET_B = 3
    sky130_fd_sc_hd__sdfrtn_1/SCD = 3
    sky130_sram_1kbyte_1rw1r_32x256_8/csb1 = 3
    sky130_sram_1kbyte_1rw1r_32x256_8/din0[0:14] = 3
    sky130_sram_1kbyte_1rw1r_32x256_8/din0[25:28] = 3
    sky130_sram_1kbyte_1rw1r_32x256_8/wmask0[0:3] = 3
    

    These terminals are not connected in either the layout or verilog. _noconnect_4_ is a net name generated by netgen.

    Moving the assign statements to the top level user_project_wrapper level yields expected results.

  2. VWPR is a typo that only exists in user_proj_example. Moving this assign statement to the top level causes a segmentation error.
    It appears that assign statements to non-existent nets cause a segfault.

    (Note: user_project_wrapper.v has been modified from the original data to connect power to user_project_example.)

Test case

test_netgen.tgz

tar xzf test_netgen.tgz
cd test_netgen
netgen -batch source lvs.script.error
netgen -batch source lvs.script.fix
netgen -batch source lvs.script.flatten
netgen -batch source lvs.script.segfault
  • lvs.script.error uses the original verilog and will produce lvs.report.error which contains the _noconnect 4_ net explained above.
  • lvs.scrip.fix uses verilog that has been modified by moving the assign statements from user_proj_example to user_project_wrapper. This yields the expected results in lvs.report.fix. The sram power is not connected at the
    user_proj_example level, so there are many errors at that level.
  • lvs.script.flatten uses the original verilog but explicitly flattens the user_proj_example before comparison. It also yields expected results in lvs.report.flatten (no difference with lvs.report.fix at the user_project_wrapper level).
  • lvs.script.segfault has an assign statement to a non-existing net. It segfaults without any output files.

In summary, the work-around is to explicitly flatten any verilog submodules that have assign statements.

./configure --with-x doesn't fail if X is not found

+ ./configure --prefix=/home/tansell/github/VLSIDA/skywater-tech-master/env/conda/envs/sky130_fd_bd_sram/conda-bld/netgen_1606696033980/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placeho
ld_placehold_placehold_placehold_placehold_placehold_placehold_place --with-tk=/home/tansell/github/VLSIDA/skywater-tech-master/env/conda/envs/sky130_fd_bd_sram/conda-bld/netgen_1606696033980/_h_env_placehold_p
lacehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place --with-tcl=/home/tansell/github/VLSIDA/skywater-tech-master/env/conda/envs/sky130_fd_
bd_sram/conda-bld/netgen_1606696033980/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place --with-x                    
checking build system type... x86_64-conda-linux-gnu                                                                                                                                                              
checking host system type... x86_64-conda-linux-gnu                                                                                                                                                               
checking target system type... x86_64-conda-linux-gnu                                                                                                                                                             
checking for x86_64-conda-linux-gnu-gcc... $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-cc                                                                                                                            
checking whether the C compiler works... yes                                                                                                                                                                      
checking for C compiler default output file name... a.out                                                                                                                                                         
checking for suffix of executables...                                                                                                                                                                             
checking whether we are cross compiling... no                                                                                                                                                                     
checking for suffix of object files... o                                                                                                                                                                          checking whether we are using the GNU C compiler... yes                                                                                                                                                           
checking whether $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-cc accepts -g... yes                                                                                                                                    
checking for $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-cc option to accept ISO C89... none needed                                                                                                                  
checking how to run the C preprocessor... $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-cpp                                                                                                                            
checking for library containing strerror... none required                                                                                                                                                         
checking for a BSD-compatible install... /usr/bin/install -c                                                                                                                                                      
checking for x86_64-conda-linux-gnu-ranlib... $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-ranlib                                                                                                                     
checking for gm4... no                  
checking for gnum4... no                                                                                                                                                                                          
checking for m4... $PREFIX/bin/m4                                                                                                                                                                                 
checking for ld used by GCC... $BUILD_PREFIX/bin/x86_64-conda-linux-gnu-ld                                                                                                                                        
checking if the linker ($BUILD_PREFIX/bin/x86_64-conda-linux-gnu-ld) is GNU ld... yes                                                                                                                             
checking for grep that handles long lines and -e... /usr/bin/grep                                                                                                                                                 
checking for egrep... /usr/bin/grep -E                                                                                                                                                                            
checking for ANSI C header files... yes                                                                                                                                                                           
checking for sys/types.h... yes                                                                                                                                                                                   
checking for sys/stat.h... yes                                                                                                                                                                                    
checking for stdlib.h... yes                                                                                                                                                                                      
checking for string.h... yes                                                                                                                                                                                      
checking for memory.h... yes                                                                                                                                                                                      
checking for strings.h... yes                                                                                                                                                                                     
checking for inttypes.h... yes                                                                           
checking for stdint.h... yes                                                                                                                                                                                      
checking for unistd.h... yes                                                                                                                                                                                      
checking size of void *... 8                                                                                                                                                                                      
checking size of unsigned int... 4                                                                                                                                                                                checking size of unsigned long... 8                                                                                                                                                                               checking size of unsigned long long... 8                                                                                                                                                                          checking whether byte ordering is bigendian... no                                                                                                                                                                 checking for ANSI C header files... (cached) yes                                                                                                                                                                  checking for setenv... yes                                                                                                                                                                                        
checking for putenv... yes                                                                                                                                                                                        checking for vfork... yes                                                                                                                                                                                         checking dirent.h usability... yes                                                                                                                                                                                
checking dirent.h presence... yes                                                                                                                                                                                 checking for dirent.h... yes                                                                                                                                                                                      checking limits.h usability... yes                                                                                                                                                                                checking limits.h presence... yes                                                                                                                                                                                 checking for limits.h... yes                                                                                                                                                                                      checking param.h usability... no                                                                                                                                                                                  
checking param.h presence... no                                                                                                                                                                                   checking for param.h... no                                                                                                                                                                                        checking for python3... yes                                                                                                                                                                                       
checking for va_copy... yes                                                                                                                                                                                       checking for __va_copy... yes                                                                                                                                                                                     checking for tclConfig.sh... $PREFIX/lib/tclConfig.sh                                                                                                                                                             checking for tkConfig.sh... $PREFIX/lib/tkConfig.sh                                                                                                                                                               checking for wish executable... $PREFIX/bin/wish                                                                                                                                                                  checking for tclsh executable... $PREFIX/bin/tclsh                                                                                                                                                                
checking for X... no                                                                                                                                                                                              Cannot compile TCL version without X11, disabling.                                                                                                                                                                configure: creating ./config.status                                                                                                                                                                               
config.status: creating defs.mak                                                                                                                                                                                  config.status: WARNING:  'defs.mak.in' seems to ignore the --datarootdir setting                                                                                                                                                                                                                                                                                                                                                    -----------------------------------------------------------                                                                                                                                                       Configuration Summary (principle requirements):                                                                                                                                                                                                                                                                                                                                                                                     
Tcl/Tk:      no                                                                                                                                                                                                                                                                                                                                                                                                                        Without Tcl/Tk, you cannot run the enhanced version of netgen                                                                                                                                                  
   with scripting ability, console window, convenience commands                                                                                                                                                      such as "lvs", and other useful features.  If you did not                                                                                                                                                         specifically disable Tcl/Tk on the configure command line, then                                                                                                                                                   getting this message means that you do not have Tcl/Tk headers                                                                                                                                                    and/or libraries installed, or they are not in a standard path.                                                                                                                                                   Try using configure options --with-tcl=<DIR> and --with-tk=<DIR>.                                                                                                                                              
                                                                                                                                                                                                                  Python3:    yes                                                                                                                                                                                                   -----------------------------------------------------------                                                                                                                                                       
                                                                                                                                                                                                                  
Use 'make' to compile and 'make install' to install. 

Errors may not be printed to stdout:  see files 'make.log' 
   and 'install.log' for a complete error summary.

-----------------------------------------------------------

+ echo 'Configure ended with: 0'

Non symmetric processing

@RTimothyEdwards

In tcltk/netgen.tcl.in at line 563

               if {([lsearch $noflat [lindex $endval 0]] == -1) &&
                        ([lsearch $noflat [lindex $endval 1]] == -1)} {
                   netgen::log put "  Flattening non-matched subcircuits $endval\n\n"
                   netgen::flatten class "[lindex $endval 0] $fnum1"
                   netgen::flatten class "[lindex $endval 1] $fnum2"
               } else {
                   netgen::log put "  Continuing with black-boxed subcircuits $endval\n\n"
                   lappend matcherr [lindex $endval 0]
                   # Match pins

but at line 612

            if {([lsearch $noflat [lindex $endval *1*]] == -1) &&
                    ([lsearch $noflat [lindex $endval 1]] == -1)} {
               netgen::log put "  Flattening non-matched subcircuits $endval\n\n"
               netgen::flatten class "[lindex $endval 0] $fnum1"
               netgen::flatten class "[lindex $endval 1] $fnum2"
            } else {
               netgen::log put "  Continuing with black-boxed subcircuits $endval\n"
               lappend matcherr [lindex $endval 0]
??? duplicate ???
               netgen::log put "  Continuing with black-boxed subcircuits $endval\n"
               lappend matcherr [lindex $endval 0]
               # Match pins

The *1* should be a 0, correct? (I added the * for emphasis, they're not in the code).
Also are the lines after ??? duplicate ??? correct?

What do you think about appending the file number to matcherr? (at both places)

Suggested fixes for code line 612

            if {([lsearch $noflat [lindex $endval 0]] == -1) &&
                    ([lsearch $noflat [lindex $endval 1]] == -1)} {
               netgen::log put "  Flattening non-matched subcircuits $endval\n\n"
               netgen::flatten class "[lindex $endval 0] $fnum1"
               netgen::flatten class "[lindex $endval 1] $fnum2"
            } else {
               netgen::log put "  Continuing with black-boxed subcircuits $endval\n"
               lappend matcherr [lindex $endval 0]"(1)"
               lappend matcherr [lindex $endval 1]"(2)"
               # Match pins

I'm looking into some other cosmetic changes to this program and can include these if that's ok.

Proxy pins for implicit verilog pins no longer working

Since merging code related to pull request #59, netgen no longer correctly handles implicit pins in verilog. This issue is caused by the fact that verilog syntax allows pins to be missing from a module instance call if those pins do not connect to anything. This case was previously handled by the "proxy pins" method.

Uninitialized count in pnp device count comparison

Slot-002 of mpw-3.

Subcircuit summary:
Circuit 1: WY_SY_ldo_v1                                                           |Circuit 2: ldo_v1
----------------------------------------------------------------------------------|----------------------------------------------------------------------------------
sky130_fd_pr__pfet_g5v0d10v5 (870->14)                                            |sky130_fd_pr__pfet_g5v0d10v5 (870->14)
sky130_fd_pr__res_xhigh_po (122->16)                                              |sky130_fd_pr__res_xhigh_po (116->9) **Mismatch**
sky130_fd_pr__nfet_g5v0d10v5 (70->11)                                             |sky130_fd_pr__nfet_g5v0d10v5 (70->11)
sky130_fd_pr__cap_mim_m3_1 (2)                                                    |sky130_fd_pr__cap_mim_m3_1 (2)
sky130_fd_pr__pnp_05v5 (-2147483647->2)                                           |sky130_fd_pr__pnp_05v5 (9->2)
Number of devices: 45 **Mismatch**                                                |Number of devices: 38 **Mismatch**
Number of nets: 28 **Mismatch**                                                   |Number of nets: 23 **Mismatch**

Will attach test case later.

Can't change column width in lvs report

The documentation says that ::netgen::format <col_width> can be used to change the column width of the lvs report, but results in an error in version 1.5.206.

bash-4.2$ netgen -noc
Netgen 1.5.206 compiled on Thu Oct 28 07:12:42 UTC 2021
Warning: netgen command 'format' use fully-qualified name '::netgen::format'
Warning: netgen command 'global' use fully-qualified name '::netgen::global'
% ::netgen::format 
41 41
% ::netgen::format 100
command returned bad code: -762612944
% ::netgen::format 
100 100
% quit

bash-4.2$ cat test.source 
puts [netgen::format]
netgen::format 100
puts [netgen::format]

bash-4.2$ netgen -batch source test.source 
Netgen 1.5.206 compiled on Thu Oct 28 07:12:42 UTC 2021
Warning: netgen command 'format' use fully-qualified name '::netgen::format'
Warning: netgen command 'global' use fully-qualified name '::netgen::global'
41 41
couldn't open "/usr/lib64/tcl8.5/tclIndex": no such file or directory
    while executing
"open [file join $dir tclIndex]"

bash-4.2$ ls /usr/lib64/tcl8.5/        
tclx8.4
bash-4.2$ find /usr/lib64/tcl8.5/ -name tclIndex
bash-4.2$ 

The above is from docker, but had the same result in native OS.

ciic-cvc:~/mpw-2/caravel-lvs/openlane$ netgen -batch source test.source 
Netgen 1.5.206 compiled on Tue Nov  9 22:10:06 PST 2021
Warning: netgen command 'format' use fully-qualified name '::netgen::format'
Warning: netgen command 'global' use fully-qualified name '::netgen::global'
41 41
couldn't open "/usr/share/tcltk/tclIndex": no such file or directory
    while executing
"open [file join $dir tclIndex]"

ciic-cvc:~/mpw-2/caravel-lvs/openlane$ ls /usr/share/tcltk
tcl8.6  tk8.6
ciic-cvc:~/mpw-2/caravel-lvs/openlane$ find /usr/share/tcltk -name tclIndex
/usr/share/tcltk/tk8.6/tclIndex
/usr/share/tcltk/tcl8.6/tclIndex

It appears that the error occurs during the following call in _netcmp_format but may have something to do with the path settings.
if (Tcl_GetIntFromObj(interp, objv[1], &col1_width) != TCL_OK)

I tried export TcLLibPath=/usr/share/tcltk/tcl8.6/ but didn't make a difference.

So batch mode, the error stops execution, but in interactive mode, you can ignore the error and continue it seems.

Verilog bus map to spice subcircuits in reversed order

Verilog bus indices in instances are being mapped in the wrong order to spice subckt definitions.

Extract the tarball into a new directory

netgen -batch source storage.netgen.ng
netgen -batch source storage.netgen.ok

The output is in

storage.lvs.lef.ng.log
storage.lvs.lef.ok.log

Both will end with Result: Circuits match uniquely.
However, storage.lvs.lef.ng.log contains mismatches (ports are reversed).

I don't know that there is a viable solution to this problem. The bus index mapping depends on how the busses are defined in the missing verilog module definition which may be in either order. It might be better to not allow bus mapping from verilog to spice and instead require that bus connections are expanded in the gate level verilog.

netgen-verilog-bus.tar.gz

lvs issue with openlane

Hi Tim, when hardening the user project wrapper in openlane I get an LVS issue with logic analyser pin not being found.

multi_project_harness.lvs.log

but multi_project_harness.lvs.powered.v

shows input [127:0] la_data_in as a signal

let me know if you need any more info.

Unconnected unmatched ports cause mismatch. Unmatched subckts only partially flattened.

From slack channel discussion https://skywater-pdk.slack.com/archives/C017UA7LEUV/p1628746152015600

netgen 1.5.196

During device level LVS comparison, proxy nets are created for unmatched ports. This can happen when a layout has 2 or more unconnected power nets of the same name that magic extracts as vdd, vdd_uq01, etc. netgen will flatten these cells and hopefully get a match at a higher level in the hierarchy.

However, when the unmatched port is unconnected, the proxy nets are apparently never resolved and cause net count mismatches.

The attached file contains an example using the storage macro of mpw2 caravel.

run_lvs_ok.sh contains fixes to the netlist and setup file to yield a match.
run_lvs_ng.sh runs lvs using the default setup file and does not match for 3 reasons.

  1. The control_logic_r subckt had been totally flattened in the layout, but only automatic flattening during lvs was only partially done.
Subcircuit summary:
Circuit 1: control_logic_r                 |Circuit 2: control_logic_r
-------------------------------------------|-------------------------------------------
sky130_fd_pr__pfet_01v8 (87)               |sky130_fd_pr__pfet_01v8 (5) **Mismatch**
sky130_fd_pr__nfet_01v8 (87)               |sky130_fd_pr__nfet_01v8 (5) **Mismatch**
(no matching element)                      |dff_buf_0 (1)
(no matching element)                      |pinv_6 (1)
(no matching element)                      |pinv_0 (1)
(no matching element)                      |pand2_0 (2)
(no matching element)                      |pdriver_2 (1)
(no matching element)                      |pand3_0 (1)
(no matching element)                      |pinv_20 (45)
(no matching element)                      |pnand2_1 (1)
(no matching element)                      |pdriver_5 (1)
Number of devices: 174 **Mismatch**        |Number of devices: 64 **Mismatch**
Number of nets: 102 **Mismatch**           |Number of nets: 65 **Mismatch**
---------------------------------------------------------------------------------------
Flattening instances of pinv_0 in cell control_logic_r makes a better match
Flattening instances of pinv_6 in cell control_logic_r makes a better match
Flattening instances of pinv_20 in cell control_logic_r makes a better match
Flattening instances of pnand2_1 in cell control_logic_r makes a better match
Making another compare attempt.

Subcircuit summary:
Circuit 1: control_logic_r                 |Circuit 2: control_logic_r
-------------------------------------------|-------------------------------------------
sky130_fd_pr__pfet_01v8 (87)               |sky130_fd_pr__pfet_01v8 (54) **Mismatch**
sky130_fd_pr__nfet_01v8 (87)               |sky130_fd_pr__nfet_01v8 (54) **Mismatch**
(no matching element)                      |dff_buf_0 (1)
(no matching element)                      |pand2_0 (2)
(no matching element)                      |pdriver_2 (1)
(no matching element)                      |pand3_0 (1)
(no matching element)                      |pdriver_5 (1)
Number of devices: 174 **Mismatch**        |Number of devices: 114 **Mismatch**
Number of nets: 102 **Mismatch**           |Number of nets: 66 **Mismatch**
---------------------------------------------------------------------------------------
NET mismatches: Class fragments follow (with fanout counts):

The netlists can be made to match by adding the following to the netgen setup file.

flatten class dff_buf_array_0 "-circuit2 dff_buf_0"
flatten class pand2_0 "-circuit2 pdriver_0"
flatten class pand3_0 "-circuit2 pdriver_4"

flatten class control_logic_r "-circuit2 dff_buf_array_0"
flatten class control_logic_r "-circuit2 pdriver_6"
flatten class control_logic_r "-circuit2 pinv_0"
flatten class control_logic_r "-circuit2 pand2_0"
flatten class control_logic_r "-circuit2 pdriver_2"
flatten class control_logic_r "-circuit2 pand3_0"
flatten class control_logic_r "-circuit2 delay_chain"
flatten class control_logic_r "-circuit2 pnand2_1"
flatten class control_logic_r "-circuit2 pdriver_5"

Is netgen capable of recursively flattening subckts?

  1. The previously reported magic bug that does not connect some nets with multiple texts. i.e. vdd, vdd_uq1023, etc.
    The run_lvs_ok.sh script uses sed to correct this.

  2. Unconnected unmatched ports causing unmatched net counts.
    There are 2 subckts extracted from the layout that have ports that are not connected inside the subckt.
    sky130_fd_bd_sram__openram_dp_cell_dummy has an unconnected VDD. (I had to comment out the parasitics.)

.subckt sky130_fd_bd_sram__openram_dp_cell_dummy VDD BL0 BL1 BR0 BR1 GND WL0 WL1 a_38_n79#
+ w_144_n79# a_400_n79#
X0 BL0 WL0 a_38_291# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
X1 GND GND a_38_133# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
*X2 GND GND BL1 GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=80000u
X3 a_400_133# WL1 BR1 GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
*X4 GND GND a_400_n79# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=80000u
X5 a_400_291# GND GND GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
X6 a_38_133# WL1 BL1 GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
*X7 GND GND a_38_n79# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=80000u
*X8 GND GND BR1 GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=80000u
X9 a_38_291# GND GND GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
X10 BR0 WL0 a_400_291# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
X11 GND GND a_400_133# GND sky130_fd_pr__special_nfet_latch ad=0p pd=0u as=0p ps=0u w=210000u l=150000u
.ends

precharge_1 has an unconnected VSUBS port.

.subckt pmos_m1_w0_550_sli_dli D S G w_n59_n29# VSUBS
X0 D G S w_n59_n29# sky130_fd_pr__pfet_01v8 ad=0p pd=0u as=0p ps=0u w=550000u l=150000u
.ends

.subckt precharge_1 bl br en_bar vdd VSUBS
Xpmos_m1_w0_550_sli_dli_0 br vdd en_bar vdd VSUBS pmos_m1_w0_550_sli_dli
Xpmos_m1_w0_550_sli_dli_1 vdd bl en_bar vdd VSUBS pmos_m1_w0_550_sli_dli
Xpmos_m1_w0_550_sli_dli_2 br bl en_bar vdd VSUBS pmos_m1_w0_550_sli_dli
.ends

Adding the following to the setup file yields a match.

flatten class precharge_array "-circuit1 precharge_0"
flatten class precharge_array_0 "-circuit1 precharge_1"
flatten class port_data "-circuit1 precharge_array"
flatten class port_data_0 "-circuit1 precharge_array_0"
flatten class dummy_array "-circuit1 sky130_fd_bd_sram__openram_dp_cell_dummy"
flatten class replica_column "-circuit1 sky130_fd_bd_sram__openram_dp_cell_dummy"
flatten class replica_column "-circuit1 sky130_fd_bd_sram__openram_dp_cell_replica"
flatten class replica_column_0 "-circuit1 sky130_fd_bd_sram__openram_dp_cell_dummy"
flatten class replica_column_0 "-circuit1 sky130_fd_bd_sram__openram_dp_cell_replica"
flatten class replica_bitcell_array "-circuit1 dummy_array"
flatten class replica_bitcell_array "-circuit2 dummy_array"
flatten class bitcell_array "-circuit1 sky130_fd_bd_sram__openram_dp_cell"
flatten class bitcell_array "-circuit2 sky130_fd_bd_sram__openram_dp_cell"

netgen_float_196.tar.gz

netgen performance issues

I have a design where netgen is taking over 90 minutes to complete. I notice a few things:

  1. We only ignore fill/tap/fake diode cells on GDS extraction (I'm using DEF extraction). Any reason for that?
    https://github.com/RTimothyEdwards/open_pdks/blob/e4b453599ad0b112e90c89220145c8219dda3cb0/sky130/netgen/sky130_setup.tcl#L335
  2. Even with GDS extraction, we don't ignore decap cells. If I do 1 and 2, netgen drops to taking about 2 minutes. I'm not sure if ignoring them all is dangerous, if so we could have a "go fast" option to use while working on a design, and switch to checking all cells on final tape out.
  3. A lot of the extra time is in CombineParallel(), where for every insertion we walk the entire property list:
            spropfirst = sproplast = NULL;
            for (ob2 = sob; ob2->type > FIRSTPIN || ob2 == sob; ob2 = ob2->next)
               pob = ob2;
            if (ob2->type == PROPERTY) spropfirst = ob2;
            for (; ob2->type == PROPERTY; ob2 = ob2->next)            <------------ HERE
               sproplast = ob2;

I don't quite have my head around how CombineParallel() works, but couldn't we just insert at the front of the list?

Tool is Wrongly mapping same module two time.

Design/Spice netlist have one instance of
"u_core.u_skew_wi",
"u_core.u_skew_wh",
"u_core.u_skew_uart",
"u_core.u_skew_spi",
"u_core.u_skew_sdram",
"u_core.u_skew_sd_ci",
"u_core.u_skew_riscv",
"u_core.u_skew_glbl",

But Tool reporting it is one more time defining it as
"skew_adjustu_core.u_skew_uart",
"skew_adjustu_core.u_skew_sd_ci",
"skew_adjustu_core.u_skew_sdram",
"skew_adjustu_core.u_skew_glbl",
"skew_adjustu_core.u_skew_spi",
"skew_adjustu_core.u_skew_riscv",
"skew_adjustu_core.u_skew_wi",
"skew_adjustu_core.u_skew_wh",

Look like it's once again appending Module name with instance.

Attached the complete setup.
Run command is : run_cmd
All Inputs are inside input directory.
exp4.tar.gz

Disconnected pin not matching between two circuits

Netgen Version: 738c1f7

So the spice model (extracted with magic) has a disconnected pin by design, but when Netgen runs it against the powered netlist (which also has a disconnected pin,) the report shows that the pin straight up does not exist in Circuit 1 in the log:

VGND                                       |VGND                                       
VPWR                                       |VPWR                                       
(no matching pin)                          |rounds[0]                                  
----------------------

I'm not sure if this is intended behavior

lvs.log
reproducible.tar.gz

segfaults when running device level LVS on caravel's `chip_io` block with these changes.

@RTimothyEdwards I get segfaults when running device level LVS on caravel's chip_io block with these changes 1.5.205.

Looks like the netlist pointers are getting whacked. Still haven't quite wrapped my head around the netlist structure, but it looks like it's mainly ports first followed by intermixed nodes, instance pin connections, and parameter records.

As you are no doubt aware, the hash keys for the subcircuits depend on the first port. If the first port changes, pointers throughout the entire netlist need to be reset. Also, if all ports and pins were to be deleted in a circuit, it looks like there's a special case where the port is kept.

What about creating a dummy anchor port that never get processed for each circuit? It doesn't look like there's a node 0, maybe that could be the key. This would keep the hash for each circuit constant and avoid a lot of unnecessary processing, I think.
The program changes required would be to add one line after the start of each loop.

assert(tc->cell && IsPort(tc->cell) && tc->cell->node == 0);  // sanity check
for ( ob = tc->cell; !ob ; ob->next ) {
   ...  // last pointer processing
   if ( IsPort(ob) && ob->node == 0 ) continue;  // skip anchor node

Originally posted by @d-m-bailey in #33 (comment)

N to 1 matching is does not appear to be working

netgen 1.5.233

The layout contains prefixed and unprefixed cells that should match to the same unprefixed name in gl verilog.

eg. BO_sky130_fd_sc_hd__clkbuf_8 and sky130_fd_sc_hd__clkbuf_8 should both match sky130_fd_sc_hd__clkbuf_8 in the spice library.

The setup file contains

            equate classes "-circuit2 sky130_fd_sc_hd__clkbuf_8" "-circuit1 BO_sky130_fd_sc_hd__clkbuf_8"
            equate classes "-circuit2 sky130_fd_sc_hd__clkbuf_8" "-circuit1 sky130_fd_sc_hd__clkbuf_8"

because "netlist with the N names should always be the second netlist".
However, only the matching cell comparison is preformed and BO_sky130_fd_sc_hd__clkbuf_8 is flattened during prematch, which causes sky130_fd_sc_hd__clkbuf_8 to be flattened also.

1 to 1 matching with prefixes using equate classes works as expected. Both of the following are ok.

            equate classes "-circuit2 precharge_0" "-circuit1 BO_sky130_sram_2kbyte_1rw1r_32x512_8_precharge_0"
            equate classes "-circuit2 sky130_fd_bd_sram__openram_write_driver" "-circuit1 BO_sky130_fd_bd_sram__openram_write_driver"
Contents of circuit 1:  Circuit: 'BO_sky130_sram_2kbyte_1rw1r_32x512_8_precharge_0'
Circuit BO_sky130_sram_2kbyte_1rw1r_32x512_8_precharge_0 contains 3 device instances.
  Class: sky130_fd_pr__pfet_01v8 instances:   3
Circuit contains 4 nets.
Contents of circuit 2:  Circuit: 'precharge_0'
Circuit precharge_0 contains 3 device instances.
  Class: sky130_fd_pr__pfet_01v8 instances:   3
Circuit contains 4 nets.

Contents of circuit 1:  Circuit: 'BO_sky130_fd_bd_sram__openram_write_driver'
Circuit BO_sky130_fd_bd_sram__openram_write_driver contains 16 device instances.
  Class: sky130_fd_pr__nfet_01v8 instances:   9
  Class: sky130_fd_pr__pfet_01v8 instances:   7
Circuit contains 15 nets.
Contents of circuit 2:  Circuit: 'sky130_fd_bd_sram__openram_write_driver'
Circuit sky130_fd_bd_sram__openram_write_driver contains 16 device instances.
  Class: sky130_fd_pr__nfet_01v8 instances:   9
  Class: sky130_fd_pr__pfet_01v8 instances:   7
Circuit contains 13 nets.

However, N to 1 matching yields

Subcircuit summary:
Circuit 1: sky130_fd_sc_hd__clkbuf_8       |Circuit 2: sky130_fd_sc_hd__clkbuf_8
-------------------------------------------|-------------------------------------------
sky130_fd_pr__pfet_01v8_hvt (10->2)        |sky130_fd_pr__pfet_01v8_hvt (10->2)
sky130_fd_pr__nfet_01v8 (10->2)            |sky130_fd_pr__nfet_01v8 (10->2)
Number of devices: 4                       |Number of devices: 4
Number of nets: 7                          |Number of nets: 7
---------------------------------------------------------------------------------------
Netlists match uniquely.

and then

Flattening unmatched subcell BO_sky130_fd_sc_hd__clkbuf_8 in circuit BO_mgmt_core (0)(40 instances)
...
Flattening instances of sky130_fd_sc_hd__clkbuf_8 in cell mgmt_core (1) makes a better match
...
Making another compare attempt.

To duplicate, see efabless/caravel#159
Warning: not a minimal case.

Note: This is not a critical problem. It causes longer LVS runs, but they still pass.

black box flattening

I can't think of a use case where we'd want black boxes to be flattened out of existence.

However, in the pre-compare name check, if a black box doesn't exist in one of the circuits, the other one will be flattened.

Flattening unmatched subcell sky130_fd_sc_hvl__fill_2 in circuit xres_buf (1)(2 instances)
Flattening unmatched subcell sky130_fd_sc_hvl__fill_1 in circuit xres_buf (1)(5 instances)

Will submit a test case if necessary.

Netgen isn't case sensitive

In the attached test case, the design has two ports with the same name but one is uppercase and the other is lower case. Netgen reports one pin mismatch because it sees both ports as lower-case.

output p; 
output P;

spm.zip

install fails: cp: netgen: No such file or directory

--- installing executable to /usr/ports/cad/netgen-lvs/work/stage/usr/local/bin
--- installing run-time files to /usr/ports/cad/netgen-lvs/work/stage/usr/local/lib
cp: netgen: No such file or directory
gmake[3]: *** [Makefile:30: /usr/ports/cad/netgen-lvs/work/stage/usr/local/bin/netgen] Error 1
cp: netgen: No such file or directory
gmake[3]: *** [Makefile:30: /usr/ports/cad/netgen-lvs/work/stage/usr/local/bin/netgen] Error 1

Version 1.6.3
FreeBSD 12

Missing circuit matching.

If there are circuit instances but no circuit definition, netgen will warn of a black box match.

However, if the spice circuit exists and is a stub with no devices, netgen will match with no warning.

We hope for at least a warning, when as in the case of black boxing, there are missing definitions in one of the netlists.

I'll try to post a test case in the next couple days.

segfault when combing parallel devices

Netgen 1.5.217

This is for the fully flattened sky130_ef_io__gpiov2_pad_wrapped cell from caravel chip_io.

Property l in circuit1 has no matching property in circuit2
sky130_fd_pr__res_generic_m1:181 vs. sky130_ef_io__gpiov2_pad:gpiov2_ef_q0/sky130_fd_io__top_gpiov2:gpiov2_base_q0/sky130_fd_io__gpiov2_opath:opath_q0/sky130_fd_io__gpiov2_octl_dat:opath_q0/sky130_fd_io__gpiov2_obpredrvr:predrvr_q0/sky130_fd_io__gpiov2_pdpredrvr_strong:pd_strong_q0/sky130_fd_io__tk_opto:I77/sky130_fd_io__tk_em1s:e2_q0/sky130_fd_pr__res_generic_m1:I1:
Property w in circuit1 has no matching property in circuit2
Segmentation fault (core dumped)

To duplicate:

  1. tar xzf merge-issue.tar.gz
  2. cd merge-issue
  3. netgen -batch source setup_file.gds.lvs

merge-issue.tar.gz

Parallel FETs not being merged when drain/source connections are swapped

Hi Tim, I think that this was working at some point in time. Test case provided,

netgen_tc1.tar.gz

this is an inverter with three parallel pfets and three parallel nfets.

schematic:
Screenshot from 2021-07-10 05-36-03

layout:
Screenshot from 2021-07-10 05-36-41

schematic netlist:

.subckt inv_c z a vdd vss
M1000 z a vdd vdd pfet W=5.85u L=0.6u M=3
M1001 z a vss vss nfet w=2.75u l=0.6u m=3
.ends

layout netlist:

.subckt inv_c z a vdd vss
M1000 vss a z vss nfet w=2.75u l=0.6u
+  ad=2.29167p pd=5.33333u as=2.29167p ps=5.33333u
M1001 z a vdd vdd pfet w=5.85u l=0.6u
+  ad=4.875p pd=9.46667u as=4.875p ps=9.46667u
M1002 z a vss vss nfet w=2.75u l=0.6u
+  ad=2.29167p pd=5.33333u as=2.29167p ps=5.33333u
M1003 z a vdd vdd pfet w=5.85u l=0.6u
+  ad=4.875p pd=9.46667u as=4.875p ps=9.46667u
M1004 z a vss vss nfet w=2.75u l=0.6u
+  ad=2.29167p pd=5.33333u as=2.29167p ps=5.33333u
M1005 vdd a z vdd pfet w=5.85u l=0.6u
+  ad=4.875p pd=9.46667u as=4.875p ps=9.46667u
C0 vdd vss 4.52fF
.ends

netgen indicates a mismatch:

Circuit 1 contains 4 devices, Circuit 2 contains 2 devices. *** MISMATCH ***
Circuit 1 contains 4 nets, Circuit 2 contains 4 nets.
Result: Netlists do not match.

This mismatch appears to come from the layout netlist being collapsed into 2 pfets and 2 nfets (versus one each), and appears to be done so because the source and drain connections are swapped on one of each of the pfets and nfets.

I tested this by manually editting the layout netlist to swap these around, and LVS passed.

Am I missing a configuration setting?

Pin matching (discussion)

Observations:

  • The MatchPins is only called if the circuit topology matches.
  • Only pin matches only show pin information. Pin matches to nets and disconnected pins are indistinguishable.
  • proxy pins work in some situations but cause mismatches in others.

netgen doesn't handle attributes correctly or escapes inside escapes.

Netgen 1.5.253

Sky130 MPW-4 Slot-029 coriolis_test_soc_-_mpw4

  1. (* ... *) denotes attributes in verilog that various tools can use as needed. In netgen, they should probably be treated as comments.
    This verilog
/* Generated by Yosys 0.12+1 (git sha1 0417528ff, clang 13.0.0 -fPIC -Os) */

(* \amaranth.hierarchy  = "user_project_core_lambdasoc" *)
(* top =  1  *)
(* generator = "Amaranth" *)
(* src = "build/sky130/top.v:22213.1-22612.10" *)
module user_project_core_lambdasoc_cts(io_out, io_oeb, io_in, vccd1, vssd1);

yields

Expected to find instance pin block but got "="
Expected to find end of instance but got ""user_project_core_lambdasoc""
line number 3 = '(* \amaranth.hierarchy  = "user_project_core_lambdasoc" *)'
Warning:  Cell (* has no pins
Creating placeholder cell definition for module (*.
Note:  Implicit pin (no pins) in instance \amaranth.hierarchy  of (* in cell user_project_core_lambdasoc.v
Expected to find instance pin block but got "top"
Expected to find end of instance but got "="
line number 4 = '(* top =  1  *)'
Warning:  Cell *) has no pins
Creating placeholder cell definition for module *).
Note:  Implicit pin (no pins) in instance (* of *) in cell user_project_core_lambdasoc.v
Expected to find instance pin block but got "(*"
Expected to find end of instance but got "generator"
...
  1. Removing the attributes. Uncovers another problem.
Badly formed subcircuit pin line at "[0]"
Expected to find end of instance but got ")"
line number 54517 = '  );'
Error:  Verilog backslash-escaped name does not end with a space.

Looking at line 54517

  nand2_x0 \$abc$109383$auto$blifparse.cc:381:parse_blif$110323  ( .vss(vssd1), .vdd(vccd1),
    .i0(\$abc$109383$new_n15674_ ),
    .i1(\$abc$109383$new_n15609_ ),
    .nq(\$\soc.cpu.minerva.gprf.mem._mem$rdreg[1]$d [0])
  );

There is a variable with 2 \ that seems to be causing a problem. Changing \$\soc to \$soc solves the problem. Maybe netgen does not process \ inside escaped variables (variables that start with \) correctly.

test_netgen.tgz

To reproduce:

tar xzf test_netgen.tgz
cd test_netgen
netgen -batch source lvs.script  # original file with all errors
netgen -batch source lvs.script.fix1  # attributes removed
netgen -batch source lvs.script.fix2  # attributes and double \ removed

Note: vdd and vss instance connections have been added to the original verilog files.

netgen generates json with invalid escape sequence

It seems that netgen generates invalid escape sequence when run on the spm design with the gf180mcuC PDK:

Logging to file "/content/OpenLane/designs/spm/runs/RUN_2022.09.17_01.33.20/logs/signoff/35-spm.lef.log" disabled
LVS Done.
Traceback (most recent call last):
  File "/content/OpenLane/scripts/count_lvs.py", line 118, in <module>
    failures = count_LVS_failures(args.file)
  File "/content/OpenLane/scripts/count_lvs.py", line 37, in count_LVS_failures
    lvsdata = json.load(cfile)
  File "/content/conda-env/lib/python3.7/json/__init__.py", line 296, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  File "/content/conda-env/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/content/conda-env/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/content/conda-env/lib/python3.7/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Invalid \escape: line 774 column 10 (char 13637)
child process exited abnormally
    while executing
"exec python3 $::env(SCRIPTS_DIR)/count_lvs.py  -f $extraction_prefix.json  |& tee $::env(TERMINAL_OUTPUT) $count_lvs_log"
    (procedure "run_lvs" line 75)
    invoked from within
"run_lvs"
    (procedure "run_lvs_step" line 10)
    invoked from within
"[lindex $step_exe 0] [lindex $step_exe 1] "
    (procedure "run_non_interactive_mode" line 52)
    invoked from within
"run_non_interactive_mode {*}$argv"
    invoked from within
"if { [info exists flags_map(-interactive)] || [info exists flags_map(-it)] } {
    if { [info exists arg_values(-file)] } {
        run_file [file nor..."
    (file "OpenLane/flow.tcl" line 401)

Looking at the attached JSON: 35-spm.lef.json.gz, it seems that it comes from the following sequence that include a \ in the pin name:

        "\genblk1[7].csa.sc ",
        "\genblk1[8].csa.sc ",
        "\genblk1[8].csa.y ",
        "\genblk1[10].csa.y ",
        "\genblk1[14].csa.y ",
        "\genblk1[15].csa.sc ",
        "\genblk1[22].csa.sc ",
        "\genblk1[29].csa.y ",
        "\genblk1[30].csa.sc ",
        "\genblk1[30].csa.y ",

It should instead be escaped with:

        "\\genblk1[7].csa.sc ",
        "\\genblk1[8].csa.sc ",
        "\\genblk1[8].csa.y ",
        "\\genblk1[10].csa.y ",
        "\\genblk1[14].csa.y ",
        "\\genblk1[15].csa.sc ",
        "\\genblk1[22].csa.sc ",
        "\\genblk1[29].csa.y ",
        "\\genblk1[30].csa.sc ",
        "\\genblk1[30].csa.y ",

Order of verilog files effects LVS results

It appears that the order of the verilog files effects the connectivity.

If the parent verilog is read before the child verilog, a placeholder is created. When the actual verilog is input, the ports do not align correctly. I'll attach a minimal test case later, but here are the results of a comparison.

  % nodes powergood_check mgmt_protect                                                               |  % nodes powergood_check mgmt_protect                                                              
  Circuit 'mgmt_protect' not found.                                                                  |  Circuit 'mgmt_protect' not found.                                                                 
  Device 'powergood_check' Pins:                                                                     |  Device 'powergood_check' Pins:                                                                    
     ...                                                                                             |     ...                                                                                            
     Pin 3 (mprj2_logic_high_hvl/VGND) = vssa1 (port of mgmt_protect)                                |     Pin 3 (mprj2_logic_high_hvl/VGND) = vssa2 (port of mgmt_protect)                               
     Pin 4 (mprj2_logic_high_hvl/VNB) = vssa1 (port of mgmt_protect)                                 |     Pin 4 (mprj2_logic_high_hvl/VNB) = vssa2 (port of mgmt_protect)                                
     Pin 5 (mprj2_logic_high_hvl/VPWR) = vdda1 (port of mgmt_protect)                                |     Pin 5 (mprj2_logic_high_hvl/VPWR) = vdda2 (port of mgmt_protect)                               
     Pin 6 (mprj2_logic_high_hvl/VPB) = vdda1 (port of mgmt_protect)                                 |     Pin 6 (mprj2_logic_high_hvl/VPB) = vdda2 (port of mgmt_protect)                                
     ...                                                                                             |     ...                                                                                            
     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/3) = vssa2 (port of mgmt_protect)     |     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/3) = vssd (port of mgmt_protect)     
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/4) = vssa2 (port of mgmt_protect)     |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/4) = vssd (port of mgmt_protect)     
     ...                                                                                             |     ...                                                                                            
     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/1) = vdda1 (port of mgmt_protect)     |     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/1) = vdda2 (port of mgmt_protect)    
     ...                                                                                             |     ...                                                                                            
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/4) = vdda1 (port of mgmt_protect)     |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/4) = vdda2 (port of mgmt_protect)    
     ...                                                                                             |     ...                                                                                            
     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_01v8:2/3) = vssa2 (port of mgmt_protect)          |     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_01v8:2/3) = vssd (port of mgmt_protect)          
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_01v8:2/4) = vssa2 (port of mgmt_protect)          |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_01v8:2/4) = vssd (port of mgmt_protect)          
     ...                                                                                             |     ...                                                                                            
     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:3/3) = vssa2 (port of mgmt_protect)     |     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:3/3) = vssd (port of mgmt_protect)     
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:3/4) = vssa2 (port of mgmt_protect)     |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:3/4) = vssd (port of mgmt_protect)     
     ...                                                                                             |     ...                                                                                            
     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:7/1) = vssa2 (port of mgmt_protect)     |     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:7/1) = vssd (port of mgmt_protect)     
     ...                                                                                             |     ...                                                                                            
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:7/4) = vssa2 (port of mgmt_protect)     |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:7/4) = vssd (port of mgmt_protect)     
     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:10/1) = vdda1 (port of mgmt_protect)    |     Pin 1 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:10/1) = vdda2 (port of mgmt_protect)   
     ...                                                                                             |     ...                                                                                            
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:10/4) = vdda1 (port of mgmt_protect)    |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:10/4) = vdda2 (port of mgmt_protect)   
     ...                                                                                             |     ...                                                                                            
     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:11/3) = vssa2 (port of mgmt_protect)    |     Pin 3 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:11/3) = vssd (port of mgmt_protect)    
     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:11/4) = vssa2 (port of mgmt_protect)    |     Pin 4 (mprj2_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:11/4) = vssd (port of mgmt_protect)    
     ...                                                                                             |     ...
     Pin 3 (mprj_logic_high_hvl/VGND) = vdda2 (port of mgmt_protect)                                 |     Pin 3 (mprj_logic_high_hvl/VGND) = vssa1 (port of mgmt_protect)                                
     Pin 4 (mprj_logic_high_hvl/VNB) = vdda2 (port of mgmt_protect)                                  |     Pin 4 (mprj_logic_high_hvl/VNB) = vssa1 (port of mgmt_protect)                                 
     Pin 5 (mprj_logic_high_hvl/VPWR) = vssd (port of mgmt_protect)                                  |     Pin 5 (mprj_logic_high_hvl/VPWR) = vdda1 (port of mgmt_protect)                                
     Pin 6 (mprj_logic_high_hvl/VPB) = vssd (port of mgmt_protect)                                   |     Pin 6 (mprj_logic_high_hvl/VPB) = vdda1 (port of mgmt_protect)                                 
     ...                                                                                             |     ...
     Pin 3 (mprj_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/3) = vssa2 (port of mgmt_protect)      |     Pin 3 (mprj_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/3) = vssd (port of mgmt_protect)      
     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/4) = vssa2 (port of mgmt_protect)      |     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__nfet_g5v0d10v5:0/4) = vssd (port of mgmt_protect)      
     ...                                                                                             |     ...
     Pin 1 (mprj_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/1) = vssd (port of mgmt_protect)       |     Pin 1 (mprj_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/1) = vdda1 (port of mgmt_protect)     
     ...                                                                                             |     ...                                                                                            
     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/4) = vssd (port of mgmt_protect)       |     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/4) = vdda1 (port of mgmt_protect)     
     ...                                                                                             |     ...
     Pin 3 (mprj_logic_high_lv/sky130_fd_pr__nfet_01v8:2/3) = vssa2 (port of mgmt_protect)           |     Pin 3 (mprj_logic_high_lv/sky130_fd_pr__nfet_01v8:2/3) = vssd (port of mgmt_protect)           
     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__nfet_01v8:2/4) = vssa2 (port of mgmt_protect)           |     Pin 4 (mprj_logic_high_lv/sky130_fd_pr__nfet_01v8:2/4) = vssd (port of mgmt_protect)           
     ...                                                                                             |     ...                                                                                            
debug.ng [+]                                                                       32,6           Top debug.ok [+]                                                                      32,6           Top

The incorrect results are on the left and the correct results are on the right.
Particularly notice the pfet bulk connection to vssd.
Pin 4 (mprj_logic_high_lv/sky130_fd_pr__pfet_g5v0d10v5:1/4) = vssd (port of mgmt_protect)

Verilog port processing may be incomplete.

Netgen's internal routines assume that all ports (type -1) are at the beginning of the netlist structure.

However, when reading verilog netlists, input, output, and inout (port) definitions can be intermixed with wire definitions.

Many netgen routines do not process ports declared after wire definitions.

In order to correct this problem, I propose reordering the ports at the end of the module input routine.
This will ensure that all ports come first and therefore the actual processing routines will not need to be changed.

parallel/series reduction of resistor network yields size errors.

Netgen 1.5.253

Here's the schematic
ps-resistor
and here are the comparison results

sky130_fd_pr__res_xhigh_po:4 vs. bgr_sym:1/sky130_fd_pr__res_xhigh_po:R5:
 w circuit1: 36.57   circuit2: 37.26   (delta=1.87%, cutoff=1%)
Circuit 2 parallel/series network does not match Circuit 1
Circuit 1 instance sky130_fd_pr__res_xhigh_po:4 network:
  l = 27
  w = 36.57
  M = 1
+
  l = 27
  w = 0.69
Circuit 2 instance bgr_sym:1/sky130_fd_pr__res_xhigh_po:R5 network:
  m = 1
  mult = 1
  L = 27
  W = 37.26
sky130_fd_pr__res_xhigh_po:5 vs. sky130_fd_pr__res_xhigh_po:R2:
 w circuit1: 6.9   circuit2: 7.59   (delta=9.52%, cutoff=1%)
Circuit 2 parallel/series network does not match Circuit 1
Circuit 1 instance sky130_fd_pr__res_xhigh_po:5 network:
  l = 24
  w = 6.9
  M = 1
+
  l = 24
  w = 0.69
Circuit 2 instance sky130_fd_pr__res_xhigh_po:R2 network:
  m = 1
  mult = 3
  L = 24
  W = 7.59
sky130_fd_pr__res_xhigh_po:12 vs. sky130_fd_pr__res_xhigh_po:R1:
 w circuit1: 3.45   circuit2: 4.14   (delta=18.2%, cutoff=1%)
Circuit 2 parallel/series network does not match Circuit 1
Circuit 1 instance sky130_fd_pr__res_xhigh_po:12 network:
  l = 24
  w = 3.45
  M = 1
+
  l = 24
  w = 0.69
Circuit 2 instance sky130_fd_pr__res_xhigh_po:R1 network:
  m = 1
  mult = 2
  L = 24
  W = 4.14
sky130_fd_pr__res_xhigh_po:7 vs. bgr_sym:1/sky130_fd_pr__res_xhigh_po:R6:
 w circuit1: 10.35   circuit2: 11.04   (delta=6.45%, cutoff=1%)
Circuit 2 parallel/series network does not match Circuit 1
Circuit 1 instance sky130_fd_pr__res_xhigh_po:7 network:
  l = 27
  w = 10.35
  M = 1
+
  l = 27
  w = 0.69
Circuit 2 instance bgr_sym:1/sky130_fd_pr__res_xhigh_po:R6 network:
  m = 1
  mult = 1
  L = 27
  W = 11.04

Looks like the source side might be merging series resistors with w values that don't match.
Parallel resistors merge if l is equal by adding w and series resistors merge if w is equal by adding l, correct?

Test data is in test_lpo1 here.

gf180mcuC lvs mismatch

using latest negten, open_pdks and magic. attached are two testcase that include gatelevel netlist, spice and def/lef used to extract the spice. one testcase has the VPW and VNW in the gatelevel netlist and the other doesn't.
extraction method used:

extract do local
extract no capacitance
extract no coupling
extract no resistance
extract no adjust
extract

ext2spice lvs
ext2spice -o $::env(EXT_NETLIST) $::env(DESIGN_NAME).ext

issue-vpw-vnw.tar.gz
issue-no-vpw-vnw.tar.gz

[OpenBSD/ld.bfd] (netgen|magic)exec wants GR_LIBS to link successfully

Hi!

While netgen and magic builds properly with LLVM's lld on OpenBSD, our older GNU binutils ld.bfd fails while linking netgenexec, because it's picky.

Note that magic is also impacted because they share the same build script.

Adding GR_LIBS to netgenexec lib flags does the job. I'm not sure it's the right thing to do, so i wanted to know you opinion about that.

(cc @just22 @kmosiejczuk)

--- tcltk/Makefile.orig
+++ tcltk/Makefile
@@ -25,7 +25,7 @@ install-tcl: netgenexec${EXEEXT} $(DESTDIR)${BINDIR}/n
 netgenexec${EXEEXT}: netgenexec.c
 	${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS_NOSTUB} netgenexec.c \
 		-o netgenexec${EXEEXT} \
-		${LDFLAGS} ${LIBS} ${LIB_SPECS_NOSTUB}
+		${LIB_SPECS_NOSTUB} ${LDFLAGS} ${LIBS} ${GR_LIBS}
 
 netgen.tcl: netgen.tcl.in
 	sed -e 's%TCL_DIR%${TCLDIR}%g' \

Segmentation fault following symmetry breaking optimization

Program received signal SIGSEGV, Segmentation fault.
0x00007f9ff3e79f51 in ResolveAutomorphisms () at netcmp.c:5886
5886	          while (E1->graph != Circuit1->file) E1 = E1->next;
(gdb) bt
#0  0x00007f9ff3e79f51 in ResolveAutomorphisms () at netcmp.c:5886
#1  0x00007f9ff3ea5edc in _netcmp_run (clientData=0x0, interp=0x563dfc5a39c0, objc=2, objv=0x563dfc5b1828) at tclnetgen.c:2436
#2  0x00007f9ff4a3f777 in TclNRRunCallbacks () from /lib/x86_64-linux-gnu/libtcl8.6.so
#3  0x00007f9ff4a40b6f in ?? () from /lib/x86_64-linux-gnu/libtcl8.6.so
#4  0x00007f9ff4af9bb8 in Tcl_FSEvalFileEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#5  0x00007f9ff4af8517 in Tcl_EvalFile () from /lib/x86_64-linux-gnu/libtcl8.6.so
#6  0x00007f9ff4b0172e in Tcl_SourceRCFile () from /lib/x86_64-linux-gnu/libtcl8.6.so
#7  0x00007f9ff4b01c7d in Tcl_MainEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#8  0x0000563dfbff4264 in main (argc=9, argv=0x7fffce974a68) at netgenexec.c:82
(gdb) print E1
$1 = (struct Element *) 0x0
(gdb) print Circuit1
$2 = (struct nlist *) 0x563dfc73b6d0
(gdb) 

Previous run with 251622c on the same input finished successfully just took a long time ( ~21.5 h )

Hash routines (discussion)

  • Hash size is fixed at hash initialization #define OBJHASHSIZE 42073. Leads to performance issues in larger chips. Proposal: allow hash resizing.
  • HashIntPtrInstall and HashIntPtrLookup use (*matchintfunc)(name, np->name, value, (int)(*((int *)np->ptr))) where value is a file number. (int)(*((int *)np->ptr))) is the first 32 bits of whatever is at the address stored in np->ptr, correct? I don't see how that would match a file number (unless they're both zero). Proposal: Change to HashInt2PtrInstall and HashInt2PtrLookup.
  • HashInt2PtrInstall and HashInt2PtrLookup use genhash to generate the key, which is not case insensitive. Although the hash does contain the integer c, it is possible that creating the key via modulo would give the same key for the same name and 2 different int values. The hash origin comparison does not include a check for the integer, so the wrong value may be returned. Proposal: Save int in the hash list for comparison. Create case insensitive comparison, if needed.
  • Hash key creation uses modulo division, which can be slow. Proposal: limit hash sizes to 2^n - the hash key is (hash & (2^n-1))

Possible bug in make install script

When I run make install, I get this error:

--- installing executable to /usr/local/bin
--- installing run-time files to /usr/local/lib
make[2]: *** No rule to make target '/usr/local/lib/netgen/python', needed by 'install-tcl'.  Stop.

Here's the installation log:

install.log
scripts/mkdirs /usr/local/bin
for dir in netgen python netgen lib doc ; do \
        (cd $dir && make install); done
make[2]: Entering directory '/home/lucca/netgen/netgen'
rm -f /usr/local/bin/netgen
cp netgen /usr/local/bin/netgen
rm -f /usr/local/bin/netcomp
cp netcomp /usr/local/bin/netcomp
rm -f /usr/local/bin/inetcomp
cp inetcomp /usr/local/bin/inetcomp
rm -f /usr/local/bin/ntk2adl
cp ntk2adl /usr/local/bin/ntk2adl
rm -f /usr/local/bin/ntk2xnf
cp ntk2xnf /usr/local/bin/ntk2xnf
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/python'
make[2]: Leaving directory '/home/lucca/netgen/python'
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/lib'
../scripts/mkdirs /usr/local/lib/netgen
mkdir /usr/local/lib/netgen
rm -f /usr/local/lib/netgen/ntk2adl.sh
cp ntk2adl.sh /usr/local/lib/netgen/ntk2adl.sh
../scripts/mkdirs /usr/local/lib/netgen
rm -f /usr/local/lib/netgen/spice
cp spice /usr/local/lib/netgen/spice
../scripts/mkdirs /usr/local/lib/netgen
rm -f /usr/local/lib/netgen/spice.bot
cp spice.bot /usr/local/lib/netgen/spice.bot
../scripts/mkdirs /usr/local/lib/netgen
rm -f /usr/local/lib/netgen/spice.top
cp spice.top /usr/local/lib/netgen/spice.top
make[2]: Leaving directory '/home/lucca/netgen/lib'
make[2]: Entering directory '/home/lucca/netgen/doc'
../scripts/mkdirs /usr/local/lib/netgen/doc
mkdir /usr/local/lib/netgen/doc
cp netgen.doc /usr/local/lib/netgen/doc/netgen.doc
make[2]: Leaving directory '/home/lucca/netgen/doc'
make[1]: Leaving directory '/home/lucca/netgen'
make[1]: Entering directory '/home/lucca/netgen'
./scripts/mkdirs /usr/local/bin
for dir in netgen python netgen lib doc ; do \
        (cd $dir && make install); done
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/python'
make[2]: Leaving directory '/home/lucca/netgen/python'
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/lib'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/lib'
make[2]: Entering directory '/home/lucca/netgen/doc'
../scripts/mkdirs /usr/local/lib/netgen/doc
make[2]: Leaving directory '/home/lucca/netgen/doc'
make[1]: Leaving directory '/home/lucca/netgen'
make[1]: Entering directory '/home/lucca/netgen'
./scripts/mkdirs /usr/local/bin
for dir in netgen python netgen lib doc ; do \
        (cd $dir && make install); done
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/python'
make[2]: Leaving directory '/home/lucca/netgen/python'
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/lib'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/lib'
make[2]: Entering directory '/home/lucca/netgen/doc'
../scripts/mkdirs /usr/local/lib/netgen/doc
make[2]: Leaving directory '/home/lucca/netgen/doc'
make[1]: Leaving directory '/home/lucca/netgen'
make[1]: Entering directory '/home/lucca/netgen'
./scripts/mkdirs /usr/local/bin
for dir in netgen python netgen lib doc ; do \
        (cd $dir && make install); done
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/python'
make[2]: Leaving directory '/home/lucca/netgen/python'
make[2]: Entering directory '/home/lucca/netgen/netgen'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/netgen'
make[2]: Entering directory '/home/lucca/netgen/lib'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/lucca/netgen/lib'
make[2]: Entering directory '/home/lucca/netgen/doc'
../scripts/mkdirs /usr/local/lib/netgen/doc
make[2]: Leaving directory '/home/lucca/netgen/doc'
make[1]: Leaving directory '/home/lucca/netgen'

When I run the netgen command, it still seems to work. Perhaps it's just the warning?

[1.6.3] warning: multiple unsequenced modifications to 'ActelIndex'

clang-8 complains:

actel.c:93:19: warning: multiple unsequenced modifications to 'ActelIndex' [-Wunsequenced]
    ActelIndex = (++ActelIndex) % ACTELNAMESIZE;
               ~  ^
actel.c:104:17: warning: multiple unsequenced modifications to 'ActelIndex' [-Wunsequenced]
  ActelIndex = (++ActelIndex) % ACTELNAMESIZE;
             ~  ^

The order of modifications is undefined and these lines are invalid.

Instance flattening (discussion)

Observations:

  • Prematching flattens cells that don't have a match in the other netlist. This may cause long run times when comparing fully extracted layout to blackbox srams, for example. Proposal: Eliminate initial flattening of subcircuits with no corresponding names. edited
  • After flattening an instance, the cell list for the parent cell is reprocessed from the beginning. O(n^2) Proposal: after flattening, reprocess cell list from last valid pointer. O(2n)
  • Reassigning node numbers for flattened instance is done once per signal for each subinstance. O(n^2) Proposal: node numbers for flattened instances can be increased by an offset. O(n)
  • Flattening a specific cell does a cell lookup for the same cell for each cell match. O(n) Proposal: Do one lookup for each subcircuit. O(1)

Unsymmetrical reduction of parameters causes size mismatch.

netgen 1.5.253

When the layout and source have differing hierarchy, the parallel/series parameters resulting from merging devices sometimes do not match. For example, from the gf180mcu SRAM macro, the layout is extracted totally flattened and the source is the calibre extracted cdl with hierarchy.

...
Flattening unmatched subcell Cell_array32x1 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(16 instances)
Flattening unmatched subcell ICV_5 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(64 instances)
Flattening unmatched subcell ICV_4 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(128 instances)
Flattening unmatched subcell 018SRAM_cell1_2x in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(256 instances)
Flattening unmatched subcell ICV_1 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(1 instance)
Flattening unmatched subcell ICV_2 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(8 instances)
Flattening unmatched subcell ICV_1 in circuit gf180mcu_fd_ip_sram__sram256x8m8wm1 (1)(16 instances)

Class gf180mcu_fd_ip_sram__sram256x8m8wm1 (0):  Merged 1 parallel devices.
Class gf180mcu_fd_ip_sram__sram256x8m8wm1 (1):  Merged 69 parallel devices.
Subcircuit summary:
Circuit 1: gf180mcu_fd_ip_sram__sram256x8m8wm1                          |Circuit 2: gf180mcu_fd_ip_sram__sram256x8m8wm1
------------------------------------------------------------------------|------------------------------------------------------------------------
pmos_6p0 (7198->6006)                                                   |pmos_6p0 (6223->6006)
nmos_6p0 (11107->10386)                                                 |nmos_6p0 (10445->10386)
Number of devices: 16392                                                |Number of devices: 16392
Number of nets: 6036                                                    |Number of nets: 6036
-------------------------------------------------------------------------------------------------------------------------------------------------
Resolving symmetries by property value.
Resolving symmetries by pin name.
Netlists match with 107 symmetries with property errors.
nmos_6p0:102 vs. nmos_6p0:M28:
 w circuit1: 0.0001474   circuit2: 0.001474   (delta=164%, cutoff=1%)
nmos_6p0:3241 vs. saout_R_m2:1267/sa:5/nmos_6p0:M1:
 w circuit1: 1.364e-05   circuit2: 6.82e-06   (delta=66.7%, cutoff=1%)
Circuit 1 parallel/series network does not match Circuit 2
Circuit 1 instance nmos_6p0:3241 network:
  M = 1
  l = 6e-07
  w = 1.364e-05
Circuit 2 instance saout_R_m2:1267/sa:5/nmos_6p0:M1 network:
  m = 1
  W = 6.82e-06
  L = 6e-07
  m = 2
  W = 3.41e-06
  L = 6e-07
nmos_6p0:1334 vs. saout_m2:1203/sa:5/nmos_6p0:M1:
 w circuit1: 1.364e-05   circuit2: 6.82e-06   (delta=66.7%, cutoff=1%)
Circuit 1 parallel/series network does not match Circuit 2
Circuit 1 instance nmos_6p0:1334 network:
  M = 1
  l = 6e-07
  w = 1.364e-05
Circuit 2 instance saout_m2:1203/sa:5/nmos_6p0:M1 network:
  m = 1
  W = 6.82e-06
  L = 6e-07
  m = 2
  W = 3.41e-06
  L = 6e-07
nmos_6p0:252 vs. saout_R_m2:1268/sa:5/nmos_6p0:M1:
 w circuit1: 1.364e-05   circuit2: 6.82e-06   (delta=66.7%, cutoff=1%)
Circuit 1 parallel/series network does not match Circuit 2
Circuit 1 instance nmos_6p0:252 network:
  M = 1
  l = 6e-07
  w = 1.364e-05
Circuit 2 instance saout_R_m2:1268/sa:5/nmos_6p0:M1 network:
  m = 1
  W = 6.82e-06
  L = 6e-07
  m = 1
  W = 6.82e-06
  L = 6e-07
nmos_6p0:213 vs. wen_v2:1327/nfet_05v0_I20:48/nmos_6p0:M0:
 w circuit1: 1.92e-06   circuit2: 1.92e-05   (delta=164%, cutoff=1%)
nmos_6p0:10836 vs. wen_v2:1327/nfet_05v0_I20:49/nmos_6p0:M0:
 w circuit1: 1.92e-06   circuit2: 1.92e-05   (delta=164%, cutoff=1%)
pmos_6p0:96 vs. pmos_6p0:M868:
 l circuit1: 3.94e-06   circuit2: 2.365e-06   (delta=50%, cutoff=1%)
 w circuit1: 0.00036234   circuit2: 0.0001638   (delta=75.5%, cutoff=1%)
pmos_6p0:96 vs. pmos_6p0:M868:
 l circuit1: 2.37e-06   circuit2: 3.94e-06   (delta=49.8%, cutoff=1%)
 w circuit1: 0.00016416   circuit2: 0.00036267   (delta=75.4%, cutoff=1%)
pmos_6p0:966 vs. pmos_6p0:M909:
 w circuit1: 0.000368   circuit2: 0.003674   (delta=164%, cutoff=1%)
pmos_6p0:185 vs. saout_m2:1200/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:2744 vs. saout_m2:1201/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:7483 vs. saout_R_m2:1265/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:649 vs. saout_R_m2:1266/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:241 vs. saout_m2:1202/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:6917 vs. saout_m2:1203/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:1625 vs. saout_R_m2:1267/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:72 vs. saout_R_m2:1268/sacntl_2:2/pmos_6p0:M16:
 w circuit1: 4.09e-06   circuit2: 4.09e-05   (delta=164%, cutoff=1%)
pmos_6p0:340 vs. saout_m2:1200/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:9407 vs. saout_m2:1201/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:1095 vs. saout_R_m2:1265/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:4898 vs. saout_R_m2:1266/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:396 vs. saout_m2:1202/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:79 vs. saout_m2:1203/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:9052 vs. saout_R_m2:1267/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:6276 vs. saout_R_m2:1268/sacntl_2:2/pmos_6p0:M22:
 w circuit1: 2.72e-06   circuit2: 2.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:1375 vs. pmos_6p0:M899:
 w circuit1: 1.25e-05   circuit2: 0.0001248   (delta=164%, cutoff=1%)
pmos_6p0:1690 vs. wen_v2:1327/pfet_05v0_I05:46/pmos_6p0:M0:
 w circuit1: 4.72e-06   circuit2: 4.72e-05   (delta=164%, cutoff=1%)
pmos_6p0:9362 vs. wen_v2:1327/pfet_05v0_I05:47/pmos_6p0:M0:
 w circuit1: 4.72e-06   circuit2: 4.72e-05   (delta=164%, cutoff=1%)

Most errors are off by a factor of 10, but some appear swapped.

pmos_6p0:96 vs. pmos_6p0:M868:
 l circuit1: 3.94e-06   circuit2: 2.365e-06   (delta=50%, cutoff=1%)
 w circuit1: 0.00036234   circuit2: 0.0001638   (delta=75.5%, cutoff=1%)
pmos_6p0:96 vs. pmos_6p0:M868:
 l circuit1: 2.37e-06   circuit2: 3.94e-06   (delta=49.8%, cutoff=1%)
 w circuit1: 0.00016416   circuit2: 0.00036267   (delta=75.4%, cutoff=1%)

Actually, that looks like there are 2 property records for the same devices 96 and M686.
Symmetrical nets appear to be matched by size and then by name, but sometimes it looks like there might be errors in both.

Test data is the same as RTimothyEdwards/magic#243
lvs.flatten.report will contain the size errors at the top level with no topology errors.
lvs.noflatten.report will contain size and port errors at the sram macro level.

This relates to the discussion here.

Parallel series mosfet matching depends on order of devices

Netgen 1.5.155

The matching of parallel series of mosfet appears to depend on the order of mosfets in the netlist.

The tarball contains 2 sample netlists. One extracted from the layout, with devices as mosfets, and the other a modified version of the cdl library. The cdl contains 2 cells that are equivalent: the only difference being the order of the MMPA1 and MMPA1x devices. The device connections are exactly the same. Only the order that they appear in the netlist is different.

I've attached a test case. Extract the tar file and then

run netgen -noc < lvsin2 to show that one subckt matches, but the other does not.

May be fixed by the recent symmetry changes.
o21a.tar.gz

Documentation for Comparing SPICE Netlists

From my understanding, netgen is supposed to be able to diff two SPICE netlists. The documentation is a bit unclear on how to do this.

For instance, netlist 0 is...

V1 1 0 1
R1 1 0 1

Netlist 1 is...

V1 1 0 1
R1 1 0 1
R2 1 0 1

I'm trying to get netgen to tell me, "Sorry, these are different netlists." Then when I remove "R2 1 0 1" from netlist 1, it should tell me that they're the same. It seems like this should be one command line call, no?

SIGSEGV during verilog read for mgmt_core_wrapper

See 67da250#commitcomment-102993180

Here's the gdb trace

Program received signal SIGSEGV, Segmentation fault.
__strncpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:298
298     ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
(gdb) bt
#0  __strncpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:298
#1  0x00007ffff76152db in ReadVerilogFile (fname=0x555575da1370 "/home/user/mpw-9/caravel_user_project2/mgmt_core_wrapper/verilog/gl/mgmt_core_wrapper.v", filenum=1,
    CellStackPtr=0x7fffffffd470, blackbox=0) at verilog.c:1593
#2  0x00007ffff7617e4e in ReadVerilogTop (fname=0x555575da1370 "/home/user/mpw-9/caravel_user_project2/mgmt_core_wrapper/verilog/gl/mgmt_core_wrapper.v",
    fnum=0x7fffffffd4e8, blackbox=0) at verilog.c:2478
#3  0x00007ffff7617f16 in ReadVerilog (fname=0x555575da1370 "/home/user/mpw-9/caravel_user_project2/mgmt_core_wrapper/verilog/gl/mgmt_core_wrapper.v",
    fnum=0x7fffffffd4e8) at verilog.c:2502
#4  0x00007ffff761b878 in _netgen_readnet (clientData=0x0, interp=0x555555566120, objc=3, objv=0x555555573cf0) at tclnetgen.c:817
#5  0x00007ffff7c1bfb7 in TclNRRunCallbacks () from /lib/x86_64-linux-gnu/libtcl8.6.so
#6  0x00007ffff7c1d3af in ?? () from /lib/x86_64-linux-gnu/libtcl8.6.so
#7  0x00007ffff7cd63f8 in Tcl_FSEvalFileEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#8  0x00007ffff7cd4d57 in Tcl_EvalFile () from /lib/x86_64-linux-gnu/libtcl8.6.so
#9  0x00007ffff7cddf6e in Tcl_SourceRCFile () from /lib/x86_64-linux-gnu/libtcl8.6.so
#10 0x00007ffff7cde4bd in Tcl_MainEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#11 0x0000555555555208 in main (argc=4, argv=0x7fffffffdb78) at netgenexec.c:82
(gdb) l
~      
293     in ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S
(gdb) up
#1  0x00007ffff76152db in ReadVerilogFile (fname=0x555575da1370 "/home/user/mpw-9/caravel_user_project2/mgmt_core_wrapper/verilog/gl/mgmt_core_wrapper.v", filenum=1,
    CellStackPtr=0x7fffffffd470, blackbox=0) at verilog.c:1593
1593                                strncpy(nodename, MAX_STR_LEN, lhs->name);
(gdb) p nodename
$1 = "FILLER_290_5647", '\000' <repeats 240 times>
(gdb) p lhs->name
$2 = 0x555578cfbae0 "debug_out"
(gdb) p MAX_STR_LEN
No symbol "MAX_STR_LEN" in current context.

Maybe constants don't print in gdb.

I'll add some debugging commands to check string lengths and report later.

Latest netgen tool hanging

I see latest netgen tool hanging after below messages

Circuits match with 11 symmetries.
Resolving automorphisms by property value.
Resolving automorphisms by pin name.
Netlists match with 9 symmetries.

Last working netgen checkout is : 7ee50a3
commit 7ee50a3
Author: Tim Edwards [email protected]
Date: Mon Mar 1 16:33:55 2021 -0500

Attached the example directory
Run command: run_cmd

exp6.tar.gz

noflatten option does not work for instance count mismatches

Specifying cells with the -noflatten option should prevent those cells from being flattened.

However, if there is a difference in the cell counts, netgen will flatten cells regardless of whether or not they're tagged noflatten.

Netgen 1.5.227

From the stdout:

Will not flatten these subcells: sky130_fd_sc_hd__decap_12 sky130_fd_sc_hd__decap_3 sky130_fd_sc_hd__decap_4 sky130_fd_sc_hd__decap_6 sky130_fd_sc_hd__decap_8 sky130_fd_sc_hd__diode_2

From the lvs report:

Flattening instances of sky130_fd_sc_hd__diode_2 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__diode_2 in cell uP16_efabless (1) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_12 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_12 in cell uP16_efabless (1) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_3 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_3 in cell uP16_efabless (1) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_4 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_4 in cell uP16_efabless (1) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_6 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_6 in cell uP16_efabless (1) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_8 in cell uP16_efabless (0) makes a better match
Flattening instances of sky130_fd_sc_hd__decap_8 in cell uP16_efabless (1) makes a better match

Unable to launch netgen

Using Ubuntu 20.04.
Installed with ./configure make sudo make install

$ sudo make install
./scripts/mkdirs /usr/local/bin
--- installing executable to /usr/local/bin
--- installing run-time files to /usr/local/lib

If I launch netgen, it is failing with below log:

$ netgen
application-specific initialization failed: Can't find a usable tk.tcl in the following directories: 
    /usr/local/lib/tcl8.6/tk8.6 /usr/local/lib/tk8.6 /usr/lib/tk8.6 /usr/lib/tk8.6 /lib/tk8.6 /usr/library



This probably means that tk wasn't installed properly.

Error in startup script: invalid command name "::tk::unsupported::ExposePrivateVariable"
    while executing
"::tk::unsupported::ExposePrivateVariable tkPriv"
    invoked from within
"if {![llength [info globals tkPriv]]} {
    ::tk::unsupported::ExposePrivateVariable tkPriv
}"
    (file "/usr/local/lib/netgen/tcl/tkcon.tcl" line 65)

I tried to install tcl-dev and tk-dev it says both or exist.

tcl8.6-dev is already the newest version (8.6.10+dfsg-1).
tk8.6-dev is already the newest version (8.6.10-1).

How to resolve that error.

Netgen runs out of memory when power connections are missing?

Running LVS on this test case gets netgen OOM-killed even on a machine with 64GB of memory:

[112623.274699] Out of memory: Killed process 21828 (netgenexec) total-vm:65585380kB, anon-rss:64542652kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:128364kB oom_score_adj:0
[112624.273960] oom_reaper: reaped process 21828 (netgenexec), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

spm.tar.gz

LVS issue when running on gf180mcu

I'm facing an LVS issue when running on any design technology gf180mcuC. The foundry gds has an extra layer 63/63 which has text related to the cell name/version/metrics, netgen treats those as pins and produces an LVS issue. Not sure if this is a netgen issue or a magic extraction issue, if it's a magic issue, I can move this issue there.

simple design for testing: mprj_io_buffer can be found here (branch: PnR)

Looks like python/lvs_manager.py may have been unintentionally added to the repo.

In commit 80947400487c6447bd42574cf383e6a0cce2244c, python/lvs_manager.py may have been inadvertently added to the repo. This file is automatically created in the python/Makefile here

lvs_manager.py: lvs_manager.py.in
        sed -e '/SUBST_SCRIPT_DIR/s#SUBST_SCRIPT_DIR#$(SCRIPTINSTALL)#' \
                lvs_manager.py.in > lvs_manager.py

It should probably be added to .gitignore with similar files already there such as tcltk/netgen.tcl

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.