Added RBA tests for four-terminal MOS extraction plus global nets.

This commit is contained in:
Matthias Koefferlein 2019-01-08 00:17:58 +01:00
parent 294f1701b5
commit fb4048d317
3 changed files with 169 additions and 0 deletions

View File

@ -106,6 +106,12 @@ template<> struct type_traits<db::NetlistDeviceExtractorMOS3Transistor> : public
typedef tl::false_tag has_default_constructor;
};
template<> struct type_traits<db::NetlistDeviceExtractorMOS4Transistor> : public tl::type_traits<void>
{
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
}
#endif

View File

@ -415,4 +415,39 @@ Class<db::NetlistDeviceExtractorMOS3Transistor> decl_NetlistDeviceExtractorMOS3T
"This class has been introduced in version 0.26."
);
db::NetlistDeviceExtractorMOS4Transistor *make_mos4_extractor (const std::string &name)
{
return new db::NetlistDeviceExtractorMOS4Transistor (name);
}
Class<db::NetlistDeviceExtractorMOS4Transistor> decl_NetlistDeviceExtractorMOS4Transistor (decl_dbNetlistDeviceExtractor, "db", "DeviceExtractorMOS4Transistor",
gsi::constructor ("new", &make_mos4_extractor, gsi::arg ("name"),
"@brief Creates a new device extractor with the given name."
),
"@brief A device extractor for a four-terminal MOS transistor\n"
"\n"
"This class supplies the generic extractor for a MOS device.\n"
"The device is defined by two basic input layers: the diffusion area\n"
"(source and drain) and the gate area. It requires a third layer\n"
"(poly) to put the gate terminals on and a forth layer to put the bulk\n"
"terminal an. The separation between poly\n"
"and allows separating the device recognition layer (gate) from the\n"
"conductive layer.\n"
"\n"
"The bulk terminal layer can be an empty layer representing the substrate.\n"
"In this use mode the bulk terminal shapes will be produced there. This\n"
"layer then needs to be connected to a global net to establish the net.\n"
"\n"
"The device class produced by this extractor is \\DeviceClassMOS4Transistor.\n"
"The extractor extracts the four parameters of this class: L, W, AS and AD.\n"
"\n"
"The diffusion area is distributed on the number of gates connecting to\n"
"the particular source or drain area.\n"
"\n"
"This class is a closed one and methods cannot be reimplemented. To reimplement "
"specific methods, see \\DeviceExtractor.\n"
"\n"
"This class has been introduced in version 0.26."
);
}

View File

@ -290,6 +290,134 @@ END
end
def test_12_LayoutToNetlistExtractionWithDevicesAndGlobalNets
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
assert_equal(l2n.netlist.to_s, <<END)
Circuit RINGO ():
XINV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD)
XINV2PAIR $2 (BULK='BULK,VSS',$2=$I22,$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD)
XINV2PAIR $3 (BULK='BULK,VSS',$2=$I23,$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD)
XINV2PAIR $4 (BULK='BULK,VSS',$2=$I24,$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD)
XINV2PAIR $5 (BULK='BULK,VSS',$2=$I25,$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD)
Circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1):
XINV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK)
XINV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK)
Circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK):
DPMOS $1 (S=$3,G=IN,D=VDD,B=$1) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]
DPMOS $2 (S=VDD,G=$3,D=OUT,B=$1) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]
DNMOS $3 (S=$3,G=IN,D=VSS,B=BULK) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]
DNMOS $4 (S=VSS,G=$3,D=OUT,B=BULK) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]
XTRANS $1 ($1=$3,$2=VSS,$3=IN)
XTRANS $2 ($1=$3,$2=VDD,$3=IN)
XTRANS $3 ($1=VDD,$2=OUT,$3=$3)
XTRANS $4 ($1=VSS,$2=OUT,$3=$3)
Circuit TRANS ($1=$1,$2=$2,$3=$3):
END
l2n.netlist.combine_devices
l2n.netlist.make_top_level_pins
l2n.netlist.purge
puts l2n.netlist.to_s
assert_equal(l2n.netlist.to_s, <<END)
Circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS'):
XINV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD)
XINV2PAIR $2 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD)
XINV2PAIR $3 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD)
XINV2PAIR $4 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD)
XINV2PAIR $5 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD)
Circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1):
XINV2 $1 ($1=$I1,IN=$I3,$3=(null),OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK)
XINV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK)
Circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK):
DPMOS $1 (S=$3,G=IN,D=VDD,B=$1) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]
DPMOS $2 (S=VDD,G=$3,D=OUT,B=$1) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]
DNMOS $3 (S=$3,G=IN,D=VSS,B=BULK) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]
DNMOS $4 (S=VSS,G=$3,D=OUT,B=BULK) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]
END
# cleanup now
l2n._destroy
end
end
load("test_epilogue.rb")