Created 2019 01 07 (markdown)

Matthias Köfferlein 2019-01-08 00:40:03 +01:00
parent cf6964d484
commit 8276167015
1 changed files with 206 additions and 0 deletions

206
2019-01-07.md Normal file

@ -0,0 +1,206 @@
# 2019-01-07
The latest version (dvb branch) is fairly stable and has been tested on a medium-size SoC thoroughly. Here are some numbers: Extraction of all nets takes ~1hr/7GB memory. With the net tracer, the extraction of the VSS net alone was taking 5hrs and 10GB of memory. The VSS net alone has about 30M shapes. After taking the shapes of all nets and outputting them to an OASIS file, the original layout was reproduced (with the exception of a few text marker shapes). This means that all nets are captured and no shape is lost. The VSS net from this extracted netlist is XOR-identical to the one delived by the net tracer.
This was a pure backend extraction without devices.
The script used for this extraction was similar to this one:
```ruby
top_cell = nil
prefix = "xout"
ly = RBA::Layout::new
ly.read("layout.oas")
tc = ly.top_cell
l2n = RBA::LayoutToNetlist::new(RBA::RecursiveShapeIterator::new(ly, tc, []))
# only plain connectivity
puts "Making layers ..."
rpoly = l2n.make_polygon_layer( ly.layer(1, 0 ) ) # GDS #1 -> poly
rcont = l2n.make_polygon_layer( ly.layer(2, 0 ) ) # GDS #2 -> contact (poly or diff)
rmetal1 = l2n.make_polygon_layer( ly.layer(3, 0 ) ) # GDS #3 -> metal 1
rmetal1_lbl = l2n.make_text_layer( ly.layer(103,0 ) ) # GDS #103 -> metal 1 labels
rvia1 = l2n.make_polygon_layer( ly.layer(4, 0 ) ) # GDS #4 -> via 1
rmetal2 = l2n.make_polygon_layer( ly.layer(5, 0 ) ) # GDS #5 -> metal 2
rmetal2_lbl = l2n.make_text_layer( ly.layer(105,0 ) ) # GDS #105 -> metal 2 labels
rvia2 = l2n.make_polygon_layer( ly.layer(6, 0 ) ) # GDS #6 -> via 2
rmetal3 = l2n.make_polygon_layer( ly.layer(7, 0 ) ) # GDS #7 -> metal 3
rmetal3_lbl = l2n.make_text_layer( ly.layer(107,0 ) ) # GDS #107 -> metal 3 labels
rvia3 = l2n.make_polygon_layer( ly.layer(8, 0 ) ) # GDS #8 -> via 3
rmetal4 = l2n.make_polygon_layer( ly.layer(9, 0 ) ) # GDS #9 -> metal 4
rmetal4_lbl = l2n.make_text_layer( ly.layer(109,0 ) ) # GDS #109 -> metal 4 labels
rvia4 = l2n.make_polygon_layer( ly.layer(10, 0 ) ) # GDS #10 -> via 4
rmetal5 = l2n.make_polygon_layer( ly.layer(11, 0 ) ) # GDS #11 -> metal 5
rmetal5_lbl = l2n.make_text_layer( ly.layer(111,0 ) ) # GDS #111 -> metal 5 labels
puts "Connecting ..."
# Intra-layer
l2n.connect(rpoly)
l2n.connect(rcont)
l2n.connect(rmetal1)
l2n.connect(rvia1)
l2n.connect(rmetal2)
l2n.connect(rvia2)
l2n.connect(rmetal3)
l2n.connect(rvia3)
l2n.connect(rmetal4)
l2n.connect(rvia4)
l2n.connect(rmetal5)
# Inter-layer
l2n.connect(rpoly, rcont)
l2n.connect(rcont, rmetal1)
l2n.connect(rmetal1, rvia1)
l2n.connect(rvia1, rmetal2)
l2n.connect(rmetal2, rvia2)
l2n.connect(rvia2, rmetal3)
l2n.connect(rmetal3, rvia3)
l2n.connect(rvia3, rmetal4)
l2n.connect(rmetal4, rvia4)
l2n.connect(rvia4, rmetal5)
l2n.connect(rmetal1, rmetal1_lbl) # attaches labels
l2n.connect(rmetal2, rmetal2_lbl) # attaches labels
l2n.connect(rmetal3, rmetal3_lbl) # attaches labels
l2n.connect(rmetal4, rmetal4_lbl) # attaches labels
l2n.connect(rmetal5, rmetal5_lbl) # attaches labels
puts "Running netlist extraction ..."
# Perform netlist extraction
l2n.extract_netlist
out = {
1 => rpoly,
2 => rcont,
3 => rmetal1,
103 => rmetal1_lbl,
4 => rvia1,
5 => rmetal2,
105 => rmetal2_lbl,
6 => rvia2,
7 => rmetal3,
107 => rmetal3_lbl,
8 => rvia3,
9 => rmetal4,
109 => rmetal4_lbl,
10 => rvia4,
11 => rmetal5,
111 => rmetal5_lbl
}
# write an annotated layout - all nets are put into
# cells called "NET_" + net name. The nets are output
# hierarchically where the circuits are put into cells
# called "CIRCUIT_" + circuit name
ly2 = RBA::Layout::new
top2 = ly2.create_cell(net.expanded_name)
lmap = {}
out.each do |ln,r|
lmap[ly2.layer(ln, 0)] = r
end
l2n.build_all_nets(l2n.cell_mapping_into(ly2, top2), ly2, lmap, "NET_", "CIRCUIT_")
ly2.write("#{prefix}_all.oas.gz")
ly2._destroy
```
## Support for extracting four-terminal MOS devices and global nets
Four-terminal devices with a bulk connection require the concept of global nets. A specific
global net represents the bulk (p-body) of the wafer. n-type transistors will have their bulk terminal
connected to this virtual net. Such a net is represented by a global net. Global nets are inherited by
parent circuits automatically. Global nets can be included in a connectivity specification with
"connect_global". A MOS4 device extractor emits bulk terminal shapes as copies of the gate shape to
a specified layer. When connecting this layer to the global "BULK" net, the B terminal of the
MOS4 devices will be connected to this global net.
Here is code for such an extraction. It also recognizes tie-down diodes for substrate and well connections:
```ruby
ly = RBA::Layout::new
ly.read(File.join($ut_testsrc, "testdata", "algo", "device_extract_l3.gds"))
l2n = RBA::LayoutToNetlist::new(RBA::RecursiveShapeIterator::new(ly, ly.top_cell, []))
rbulk = l2n.make_polygon_layer( ly.layer )
rnwell = l2n.make_polygon_layer( ly.layer(1, 0) )
ractive = l2n.make_polygon_layer( ly.layer(2, 0) )
rpoly = l2n.make_polygon_layer( ly.layer(3, 0) )
rpoly_lbl = l2n.make_text_layer( ly.layer(3, 1) )
rdiff_cont = l2n.make_polygon_layer( ly.layer(4, 0) )
rpoly_cont = l2n.make_polygon_layer( ly.layer(5, 0) )
rmetal1 = l2n.make_polygon_layer( ly.layer(6, 0) )
rmetal1_lbl = l2n.make_text_layer( ly.layer(6, 1) )
rvia1 = l2n.make_polygon_layer( ly.layer(7, 0) )
rmetal2 = l2n.make_polygon_layer( ly.layer(8, 0) )
rmetal2_lbl = l2n.make_text_layer( ly.layer(8, 1) )
rpplus = l2n.make_polygon_layer( ly.layer(10, 0) )
rnplus = l2n.make_polygon_layer( ly.layer(11, 0) )
ractive_in_nwell = ractive & rnwell
rpactive = ractive_in_nwell & rpplus
rntie = ractive_in_nwell & rnplus
rpgate = rpactive & rpoly
rpsd = rpactive - rpgate
ractive_outside_nwell = ractive - rnwell
rnactive = ractive_outside_nwell & rnplus
rptie = ractive_outside_nwell & rpplus
rngate = rnactive & rpoly
rnsd = rnactive - rngate
# PMOS transistor device extraction
pmos_ex = RBA::DeviceExtractorMOS4Transistor::new("PMOS")
l2n.extract_devices(pmos_ex, { "SD" => rpsd, "G" => rpgate, "P" => rpoly, "W" => rnwell })
# NMOS transistor device extraction
nmos_ex = RBA::DeviceExtractorMOS4Transistor::new("NMOS")
l2n.extract_devices(nmos_ex, { "SD" => rnsd, "G" => rngate, "P" => rpoly, "W" => rbulk })
# Define connectivity for netlist extraction
# Intra-layer
l2n.connect(rpsd)
l2n.connect(rnsd)
l2n.connect(rnwell)
l2n.connect(rpoly)
l2n.connect(rdiff_cont)
l2n.connect(rpoly_cont)
l2n.connect(rmetal1)
l2n.connect(rvia1)
l2n.connect(rmetal2)
l2n.connect(rptie)
l2n.connect(rntie)
# Inter-layer
l2n.connect(rpsd, rdiff_cont)
l2n.connect(rnsd, rdiff_cont)
l2n.connect(rpoly, rpoly_cont)
l2n.connect(rpoly_cont, rmetal1)
l2n.connect(rdiff_cont, rmetal1)
l2n.connect(rdiff_cont, rntie)
l2n.connect(rdiff_cont, rptie)
l2n.connect(rnwell, rntie)
l2n.connect(rmetal1, rvia1)
l2n.connect(rvia1, rmetal2)
l2n.connect(rpoly, rpoly_lbl) # attaches labels
l2n.connect(rmetal1, rmetal1_lbl) # attaches labels
l2n.connect(rmetal2, rmetal2_lbl) # attaches labels
# Global connections
l2n.connect_global(rptie, "BULK")
l2n.connect_global(rbulk, "BULK")
# Perform netlist extraction
l2n.extract_netlist
puts l2n.netlist.to_s
```