mirror of https://github.com/VLSIDA/OpenRAM.git
Merge pull request #304 from ThVerg/fix-sky130-narrow-nfet-model
sky130: use special_nfet_01v8 model for sub-0.42um nfets
This commit is contained in:
commit
b2b069ce11
|
|
@ -116,12 +116,32 @@ class ptx(design):
|
||||||
# but this may be uncommented for debug purposes
|
# but this may be uncommented for debug purposes
|
||||||
# self.DRC()
|
# self.DRC()
|
||||||
|
|
||||||
|
def get_model_name(self):
|
||||||
|
"""
|
||||||
|
Return the device model name for this transistor's width.
|
||||||
|
|
||||||
|
Some technologies model narrow devices with a separate model. In
|
||||||
|
sky130, an nfet narrower than 0.42um is extracted as
|
||||||
|
sky130_fd_pr__special_nfet_01v8 rather than sky130_fd_pr__nfet_01v8
|
||||||
|
(see the "device msubcircuit" rules in sky130A.tech), so the netlist
|
||||||
|
must use the same name or LVS reports a device class mismatch on
|
||||||
|
every gate built from a minimum-width device.
|
||||||
|
"""
|
||||||
|
narrow_model = spice.get("{}_narrow".format(self.tx_type))
|
||||||
|
narrow_width = spice.get("{}_narrow_max_width".format(self.tx_type))
|
||||||
|
if narrow_model and narrow_width and self.tx_width < narrow_width:
|
||||||
|
return narrow_model
|
||||||
|
|
||||||
|
return spice[self.tx_type]
|
||||||
|
|
||||||
def create_netlist(self):
|
def create_netlist(self):
|
||||||
pin_list = ["D", "G", "S", "B"]
|
pin_list = ["D", "G", "S", "B"]
|
||||||
if self.tx_type == "nmos":
|
if self.tx_type == "nmos":
|
||||||
body_dir = "GROUND"
|
body_dir = "GROUND"
|
||||||
else:
|
else:
|
||||||
body_dir = "POWER"
|
body_dir = "POWER"
|
||||||
|
|
||||||
|
self.model_name = self.get_model_name()
|
||||||
dir_list = ["INOUT", "INPUT", "INOUT", body_dir]
|
dir_list = ["INOUT", "INPUT", "INOUT", body_dir]
|
||||||
self.add_pin_list(pin_list, dir_list)
|
self.add_pin_list(pin_list, dir_list)
|
||||||
|
|
||||||
|
|
@ -133,7 +153,7 @@ class ptx(design):
|
||||||
self.channel_length = drc("minlength_channel")
|
self.channel_length = drc("minlength_channel")
|
||||||
if cell_props.ptx.model_is_subckt:
|
if cell_props.ptx.model_is_subckt:
|
||||||
# sky130
|
# sky130
|
||||||
main_str = "X{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type],
|
main_str = "X{{0}} {{1}} {0} m={1} w={2} l={3} ".format(self.model_name,
|
||||||
self.mults,
|
self.mults,
|
||||||
self.tx_width,
|
self.tx_width,
|
||||||
self.channel_length)
|
self.channel_length)
|
||||||
|
|
@ -142,7 +162,7 @@ class ptx(design):
|
||||||
area_str = "pd={0:.2f} ps={0:.2f} as={1:.2f}u ad={1:.2f}u".format(perimeter_sd,
|
area_str = "pd={0:.2f} ps={0:.2f} as={1:.2f}u ad={1:.2f}u".format(perimeter_sd,
|
||||||
area_sd)
|
area_sd)
|
||||||
else:
|
else:
|
||||||
main_str = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(spice[self.tx_type],
|
main_str = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(self.model_name,
|
||||||
self.mults,
|
self.mults,
|
||||||
self.tx_width,
|
self.tx_width,
|
||||||
self.channel_length)
|
self.channel_length)
|
||||||
|
|
@ -164,12 +184,12 @@ class ptx(design):
|
||||||
self.tx_width,
|
self.tx_width,
|
||||||
self.channel_length)
|
self.channel_length)
|
||||||
elif cell_props.ptx.model_is_subckt:
|
elif cell_props.ptx.model_is_subckt:
|
||||||
self.lvs_device = "X{{0}} {{1}} {0} m={1} w={2}u l={3}u".format(spice[self.tx_type],
|
self.lvs_device = "X{{0}} {{1}} {0} m={1} w={2}u l={3}u".format(self.model_name,
|
||||||
self.mults,
|
self.mults,
|
||||||
self.tx_width,
|
self.tx_width,
|
||||||
self.channel_length)
|
self.channel_length)
|
||||||
else:
|
else:
|
||||||
self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(spice[self.tx_type],
|
self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(self.model_name,
|
||||||
self.mults,
|
self.mults,
|
||||||
self.tx_width,
|
self.tx_width,
|
||||||
self.channel_length)
|
self.channel_length)
|
||||||
|
|
|
||||||
|
|
@ -711,6 +711,14 @@ drc.add_enclosure("m5",
|
||||||
spice = {}
|
spice = {}
|
||||||
spice["nmos"] = "sky130_fd_pr__nfet_01v8"
|
spice["nmos"] = "sky130_fd_pr__nfet_01v8"
|
||||||
spice["pmos"] = "sky130_fd_pr__pfet_01v8"
|
spice["pmos"] = "sky130_fd_pr__pfet_01v8"
|
||||||
|
|
||||||
|
# An nfet narrower than 0.42um is a different device in sky130: magic
|
||||||
|
# extracts it as sky130_fd_pr__special_nfet_01v8, so the netlist has to use
|
||||||
|
# that name below the threshold or netgen reports a device class mismatch.
|
||||||
|
# See the "device msubcircuit" lines in sky130A.tech. There is no equivalent
|
||||||
|
# split for pfets, so only the nmos is declared here.
|
||||||
|
spice["nmos_narrow"] = "sky130_fd_pr__special_nfet_01v8"
|
||||||
|
spice["nmos_narrow_max_width"] = 0.42
|
||||||
spice["power"]="vccd1"
|
spice["power"]="vccd1"
|
||||||
spice["ground"]="vssd1"
|
spice["ground"]="vssd1"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue