Skip to content

2018 12 31

Matthias Köfferlein edited this page Dec 31, 2018 · 5 revisions

2018-12-31 First functional implementation of a netlist extractor

As of today, the "dvb" branch contains a basic hierarchical netlist extraction feature. It can be used from Ruby and Python. The basic entry point is "db::LayoutToNetlist" aka "RBA::LayoutToNetlist".

Highlights are:

  • Customizable connectivity extraction with support for hierachical boolean operations.
  • Customizable device recognition and extraction. A device extractor is provided currently for three-terminal MOSFET devices.
  • Net extraction in device-less mode for net geometry extraction.
  • Hierarchical netlist extraction.
  • Netlist cleaning ("purge") and device combination.
  • Backannotation of layout to nets.
  • Net probing by location.

The current implementation is fairly tested and not performance-optimized. Advanced features are missing yet.

Here is a some code you can try:

Device-less extraction

The input for this sample is part of the sources:

ly = RBA::Layout::new
ly.read("testdata/algo/device_extract_l1.gds")

l2n = RBA::LayoutToNetlist::new(RBA::RecursiveShapeIterator::new(ly, ly.top_cell, []))

# only plain connectivity

ractive     = l2n.make_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) )

rsd         = ractive - rpoly

# Intra-layer
l2n.connect(rsd)
l2n.connect(rpoly)
l2n.connect(rdiff_cont)
l2n.connect(rpoly_cont)
l2n.connect(rmetal1)
l2n.connect(rvia1)
l2n.connect(rmetal2)

# Inter-layer
l2n.connect(rsd,        rdiff_cont)
l2n.connect(rpoly,      rpoly_cont)
l2n.connect(rpoly_cont, rmetal1)
l2n.connect(rdiff_cont, rmetal1)
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

# Perform netlist extraction 
l2n.extract_netlist

puts l2n.netlist.to_s

The output of this script is:

...

Net extraction with devices:

ly = RBA::Layout::new
ly.read("testdata/algo/device_extract_l1.gds")

l2n = RBA::LayoutToNetlist::new(RBA::RecursiveShapeIterator::new(ly, ly.top_cell, []))

rnwell      = l2n.make_layer(         ly.layer(1, 0) )
ractive     = l2n.make_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) )

rpactive    = ractive & rnwell
rpgate      = rpactive & rpoly
rpsd        = rpactive - rpgate

rnactive    = ractive - rnwell
rngate      = rnactive & rpoly
rnsd        = rnactive - rngate

# PMOS transistor device extraction
pmos_ex = RBA::DeviceExtractorMOS3Transistor::new("PMOS")
l2n.extract_devices(pmos_ex, { "SD" => rpsd, "G" => rpgate, "P" => rpoly })

# NMOS transistor device extraction
nmos_ex = RBA::DeviceExtractorMOS3Transistor::new("NMOS")
l2n.extract_devices(nmos_ex, { "SD" => rnsd, "G" => rngate, "P" => rpoly })

# Define connectivity for netlist extraction

# Intra-layer
l2n.connect(rpsd)
l2n.connect(rnsd)
l2n.connect(rpoly)
l2n.connect(rdiff_cont)
l2n.connect(rpoly_cont)
l2n.connect(rmetal1)
l2n.connect(rvia1)
l2n.connect(rmetal2)

# 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(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

# Perform netlist extraction 
l2n.extract_netlist

# Simplification
l2n.netlist.purge

puts l2n.netlist.to_s

The output of this script is:

...
Clone this wiki locally