mirror of https://github.com/VLSIDA/OpenRAM.git
Remove add_mod and add module whenever calling add_inst.
This commit is contained in:
parent
b94dd79125
commit
0c3ee643ab
|
|
@ -232,6 +232,7 @@ class layout():
|
|||
# Check that the instance name is unique
|
||||
debug.check(name not in self.inst_names, "Duplicate named instance in {0}: {1}".format(self.cell_name, name))
|
||||
|
||||
self.mods.add(mod)
|
||||
self.inst_names.add(name)
|
||||
self.insts.append(geometry.instance(name, mod, offset, mirror, rotate))
|
||||
debug.info(3, "adding instance {}".format(self.insts[-1]))
|
||||
|
|
@ -638,7 +639,6 @@ class layout():
|
|||
directions=directions,
|
||||
implant_type=implant_type,
|
||||
well_type=well_type)
|
||||
self.add_mod(via)
|
||||
inst = self.add_inst(name=via.name,
|
||||
mod=via,
|
||||
offset=offset)
|
||||
|
|
@ -664,7 +664,6 @@ class layout():
|
|||
corrected_offset = offset + vector(-0.5 * width,
|
||||
-0.5 * height)
|
||||
|
||||
self.add_mod(via)
|
||||
inst = self.add_inst(name=via.name,
|
||||
mod=via,
|
||||
offset=corrected_offset)
|
||||
|
|
@ -756,7 +755,6 @@ class layout():
|
|||
mos = ptx.ptx(width=width,
|
||||
mults=mults,
|
||||
tx_type=tx_type)
|
||||
self.add_mod(mos)
|
||||
inst = self.add_inst(name=mos.name,
|
||||
mod=mos,
|
||||
offset=offset,
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@ class spice():
|
|||
self.lvs_file = lvs_dir + cell_name + ".sp"
|
||||
else:
|
||||
self.lvs_file = self.sp_file
|
||||
|
||||
|
||||
self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "BIAS", "POWER", "GROUND"]
|
||||
# Holds subckts/mods for this module
|
||||
self.mods = []
|
||||
self.mods = set()
|
||||
# Holds the pins for this module (in order)
|
||||
self.pins = []
|
||||
# The type map of each pin: INPUT, OUTPUT, INOUT, POWER, GROUND
|
||||
|
|
@ -128,7 +128,7 @@ class spice():
|
|||
|
||||
new_list = [input_list[x] for x in self.pin_indices]
|
||||
return new_list
|
||||
|
||||
|
||||
def add_pin_types(self, type_list):
|
||||
"""
|
||||
Add pin types for all the cell's pins.
|
||||
|
|
@ -140,7 +140,7 @@ class spice():
|
|||
\n Module names={}\
|
||||
".format(self.name, self.pins, type_list), 1)
|
||||
self.pin_type = {pin: type for pin, type in zip(self.pins, type_list)}
|
||||
|
||||
|
||||
def get_pin_type(self, name):
|
||||
""" Returns the type of the signal pin. """
|
||||
pin_type = self.pin_type[name]
|
||||
|
|
@ -187,10 +187,6 @@ class spice():
|
|||
inout_list.append(pin)
|
||||
return inout_list
|
||||
|
||||
def add_mod(self, mod):
|
||||
"""Adds a subckt/submodule to the subckt hierarchy"""
|
||||
self.mods.append(mod)
|
||||
|
||||
def connect_inst(self, args, check=True):
|
||||
"""
|
||||
Connects the pins of the last instance added
|
||||
|
|
@ -199,13 +195,13 @@ class spice():
|
|||
where we dynamically generate groups of connections after a
|
||||
group of modules are generated.
|
||||
"""
|
||||
|
||||
|
||||
num_pins = len(self.insts[-1].mod.pins)
|
||||
num_args = len(args)
|
||||
|
||||
# Order the arguments if the hard cell has a custom port order
|
||||
ordered_args = self.get_ordered_inputs(args)
|
||||
|
||||
|
||||
if (check and num_pins != num_args):
|
||||
if num_pins < num_args:
|
||||
mod_pins = self.insts[-1].mod.pins + [""] * (num_args - num_pins)
|
||||
|
|
@ -372,15 +368,15 @@ class spice():
|
|||
# these are wires and paths
|
||||
if self.conns[i] == []:
|
||||
continue
|
||||
|
||||
|
||||
# Instance with no devices in it needs no subckt/instance
|
||||
if self.insts[i].mod.no_instances:
|
||||
continue
|
||||
|
||||
|
||||
# If this is a trimmed netlist, skip it by adding comment char
|
||||
if trim and self.insts[i].name in self.trim_insts:
|
||||
sp.write("* ")
|
||||
|
||||
|
||||
if lvs and hasattr(self.insts[i].mod, "lvs_device"):
|
||||
sp.write(self.insts[i].mod.lvs_device.format(self.insts[i].name,
|
||||
" ".join(self.conns[i])))
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ class dummy_pbitcell(design.design):
|
|||
def add_modules(self):
|
||||
self.prbc = factory.create(module_type="pbitcell",
|
||||
dummy_bitcell=True)
|
||||
self.add_mod(self.prbc)
|
||||
|
||||
self.height = self.prbc.height
|
||||
self.width = self.prbc.width
|
||||
|
|
|
|||
|
|
@ -179,26 +179,21 @@ class pbitcell(bitcell_base.bitcell_base):
|
|||
# create ptx for inverter transistors
|
||||
self.inverter_nmos = ptx(width=inverter_nmos_width,
|
||||
tx_type="nmos")
|
||||
self.add_mod(self.inverter_nmos)
|
||||
|
||||
self.inverter_pmos = ptx(width=inverter_pmos_width,
|
||||
tx_type="pmos")
|
||||
self.add_mod(self.inverter_pmos)
|
||||
|
||||
# create ptx for readwrite transitors
|
||||
self.readwrite_nmos = ptx(width=readwrite_nmos_width,
|
||||
tx_type="nmos")
|
||||
self.add_mod(self.readwrite_nmos)
|
||||
|
||||
# create ptx for write transitors
|
||||
self.write_nmos = ptx(width=write_nmos_width,
|
||||
tx_type="nmos")
|
||||
self.add_mod(self.write_nmos)
|
||||
|
||||
# create ptx for read transistors
|
||||
self.read_nmos = ptx(width=read_nmos_width,
|
||||
tx_type="nmos")
|
||||
self.add_mod(self.read_nmos)
|
||||
|
||||
def calculate_spacing(self):
|
||||
""" Calculate transistor spacings """
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ class replica_pbitcell(design.design):
|
|||
def add_modules(self):
|
||||
self.prbc = factory.create(module_type="pbitcell",
|
||||
replica_bitcell=True)
|
||||
self.add_mod(self.prbc)
|
||||
|
||||
self.height = self.prbc.height
|
||||
self.width = self.prbc.width
|
||||
|
|
@ -88,4 +87,3 @@ class replica_pbitcell(design.design):
|
|||
self.copy_layout_pin(self.prbc_inst, "wl{}".format(port))
|
||||
self.copy_layout_pin(self.prbc_inst, "vdd")
|
||||
self.copy_layout_pin(self.prbc_inst, "gnd")
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ class and2_dec(design.design):
|
|||
height=self.height,
|
||||
size=self.size)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
if "li" in layer:
|
||||
|
|
|
|||
|
|
@ -41,9 +41,6 @@ class and3_dec(design.design):
|
|||
height=self.height,
|
||||
size=self.size)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
if "li" in layer:
|
||||
self.route_layer = "li"
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ class and4_dec(design.design):
|
|||
height=self.height,
|
||||
size=self.size)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
if "li" in layer:
|
||||
self.route_layer = "li"
|
||||
|
|
@ -129,4 +126,3 @@ class and4_dec(design.design):
|
|||
offset=pin.center(),
|
||||
width=pin.width(),
|
||||
height=pin.height())
|
||||
|
||||
|
|
|
|||
|
|
@ -389,7 +389,6 @@ class bank(design.design):
|
|||
self.bitcell_array = factory.create(module_type="replica_bitcell_array",
|
||||
cols=self.num_cols + self.num_spare_cols,
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
self.port_address = []
|
||||
for port in self.all_ports:
|
||||
|
|
@ -397,7 +396,6 @@ class bank(design.design):
|
|||
cols=self.num_cols + self.num_spare_cols,
|
||||
rows=self.num_rows,
|
||||
port=port))
|
||||
self.add_mod(self.port_address[port])
|
||||
|
||||
self.port_data = []
|
||||
self.bit_offsets = self.get_column_offsets()
|
||||
|
|
@ -407,11 +405,9 @@ class bank(design.design):
|
|||
port=port,
|
||||
bit_offsets=self.bit_offsets)
|
||||
self.port_data.append(temp_pre)
|
||||
self.add_mod(self.port_data[port])
|
||||
|
||||
if(self.num_banks > 1):
|
||||
self.bank_select = factory.create(module_type="bank_select")
|
||||
self.add_mod(self.bank_select)
|
||||
|
||||
def create_bitcell_array(self):
|
||||
""" Creating Bitcell Array """
|
||||
|
|
@ -547,7 +543,6 @@ class bank(design.design):
|
|||
else:
|
||||
# No error checking before?
|
||||
debug.error("Invalid column decoder?", -1)
|
||||
self.add_mod(self.column_decoder)
|
||||
|
||||
self.column_decoder_inst = [None] * len(self.all_ports)
|
||||
for port in self.all_ports:
|
||||
|
|
|
|||
|
|
@ -78,20 +78,15 @@ class bank_select(design.design):
|
|||
|
||||
# 1x Inverter
|
||||
self.inv_sel = factory.create(module_type="pinv", height=height)
|
||||
self.add_mod(self.inv_sel)
|
||||
|
||||
# 4x Inverter
|
||||
self.inv4x = factory.create(module_type="pinv", height=height, size=4)
|
||||
self.add_mod(self.inv4x)
|
||||
|
||||
self.nor2 = factory.create(module_type="pnor2", height=height)
|
||||
self.add_mod(self.nor2)
|
||||
|
||||
self.inv4x_nor = factory.create(module_type="pinv", height=height, size=4)
|
||||
self.add_mod(self.inv4x_nor)
|
||||
|
||||
self.nand2 = factory.create(module_type="pnand2", height=height)
|
||||
self.add_mod(self.nand2)
|
||||
|
||||
def calculate_module_offsets(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class bitcell_array(bitcell_base_array):
|
|||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
self.add_mod(self.cell)
|
||||
|
||||
def create_instances(self):
|
||||
""" Create the module instances used in this design """
|
||||
|
|
@ -64,11 +63,11 @@ class bitcell_array(bitcell_base_array):
|
|||
self.cell_inst[row, col]=self.add_inst(name=name,
|
||||
mod=self.cell)
|
||||
self.connect_inst(self.get_bitcell_pins(row, col))
|
||||
|
||||
|
||||
# If it is a "core" cell, it could be trimmed for sim time
|
||||
if col>0 and col<self.column_size-1 and row>0 and row<self.row_size-1:
|
||||
self.trim_insts.add(name)
|
||||
|
||||
|
||||
def analytical_power(self, corner, load):
|
||||
"""Power of Bitcell array and bitline in nW."""
|
||||
|
||||
|
|
|
|||
|
|
@ -42,14 +42,13 @@ class col_cap_array(bitcell_base_array):
|
|||
|
||||
self.height = self.dummy_cell.height
|
||||
self.width = self.column_size * self.cell.width
|
||||
|
||||
|
||||
self.add_boundary()
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
self.dummy_cell = factory.create(module_type="col_cap_{}".format(OPTS.bitcell))
|
||||
self.add_mod(self.dummy_cell)
|
||||
|
||||
def create_instances(self):
|
||||
""" Create the module instances used in this design """
|
||||
|
|
@ -101,4 +100,3 @@ class col_cap_array(bitcell_base_array):
|
|||
for pin_name in ["vdd", "gnd"]:
|
||||
for pin in inst.get_pins(pin_name):
|
||||
self.copy_power_pin(pin)
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ class column_mux_array(design.design):
|
|||
self.mux = factory.create(module_type="column_mux",
|
||||
bitcell_bl=self.bitcell_bl,
|
||||
bitcell_br=self.bitcell_br)
|
||||
self.add_mod(self.mux)
|
||||
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,17 +91,13 @@ class control_logic(design.design):
|
|||
rows=self.num_control_signals,
|
||||
columns=1)
|
||||
|
||||
self.add_mod(self.ctrl_dff_array)
|
||||
|
||||
self.and2 = factory.create(module_type="pand2",
|
||||
size=12,
|
||||
height=dff_height)
|
||||
self.add_mod(self.and2)
|
||||
|
||||
self.rbl_driver = factory.create(module_type="pbuf",
|
||||
size=self.num_cols,
|
||||
height=dff_height)
|
||||
self.add_mod(self.rbl_driver)
|
||||
|
||||
# clk_buf drives a flop for every address
|
||||
addr_flops = math.log(self.num_words, 2) + math.log(self.words_per_row, 2)
|
||||
|
|
@ -114,8 +110,6 @@ class control_logic(design.design):
|
|||
fanout=clock_fanout,
|
||||
height=dff_height)
|
||||
|
||||
self.add_mod(self.clk_buf_driver)
|
||||
|
||||
# We will use the maximum since this same value is used to size the wl_en
|
||||
# and the p_en_bar drivers
|
||||
# max_fanout = max(self.num_rows, self.num_cols)
|
||||
|
|
@ -126,25 +120,21 @@ class control_logic(design.design):
|
|||
self.wl_en_driver = factory.create(module_type="pdriver",
|
||||
size_list=size_list,
|
||||
height=dff_height)
|
||||
self.add_mod(self.wl_en_driver)
|
||||
|
||||
# w_en drives every write driver
|
||||
self.wen_and = factory.create(module_type="pand3",
|
||||
size=self.word_size + 8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.wen_and)
|
||||
size=self.word_size + 8,
|
||||
height=dff_height)
|
||||
|
||||
# s_en drives every sense amp
|
||||
self.sen_and3 = factory.create(module_type="pand3",
|
||||
size=self.word_size + self.num_spare_cols,
|
||||
height=dff_height)
|
||||
self.add_mod(self.sen_and3)
|
||||
|
||||
# used to generate inverted signals with low fanout
|
||||
self.inv = factory.create(module_type="pinv",
|
||||
size=1,
|
||||
height=dff_height)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
# p_en_bar drives every column in the bitcell array
|
||||
# but it is sized the same as the wl_en driver with
|
||||
|
|
@ -152,17 +142,14 @@ class control_logic(design.design):
|
|||
self.p_en_bar_driver = factory.create(module_type="pdriver",
|
||||
fanout=self.num_cols,
|
||||
height=dff_height)
|
||||
self.add_mod(self.p_en_bar_driver)
|
||||
|
||||
self.nand2 = factory.create(module_type="pnand2",
|
||||
height=dff_height)
|
||||
self.add_mod(self.nand2)
|
||||
|
||||
debug.check(OPTS.delay_chain_stages % 2,
|
||||
"Must use odd number of delay chain stages for inverting delay chain.")
|
||||
self.delay_chain=factory.create(module_type="delay_chain",
|
||||
fanout_list = OPTS.delay_chain_stages * [ OPTS.delay_chain_fanout_per_stage ])
|
||||
self.add_mod(self.delay_chain)
|
||||
|
||||
def get_dynamic_delay_chain_size(self, previous_stages, previous_fanout):
|
||||
"""Determine the size of the delay chain used for the Sense Amp Enable using path delays"""
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class delay_chain(design.design):
|
|||
self.height = self.rows * self.inv.height
|
||||
# The width is determined by the largest fanout plus the driver
|
||||
self.width = (max(self.fanout_list) + 1) * self.inv.width
|
||||
|
||||
|
||||
self.place_inverters()
|
||||
self.route_inverters()
|
||||
self.route_supplies()
|
||||
|
|
@ -66,10 +66,9 @@ class delay_chain(design.design):
|
|||
|
||||
self.dff = factory.create(module_type="dff_buf")
|
||||
dff_height = self.dff.height
|
||||
|
||||
|
||||
self.inv = factory.create(module_type="pinv",
|
||||
height=dff_height)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_inverters(self):
|
||||
""" Create the inverters and connect them based on the stage list """
|
||||
|
|
@ -199,7 +198,7 @@ class delay_chain(design.design):
|
|||
to_layer="m2",
|
||||
offset=mid_loc)
|
||||
self.add_path(a_pin.layer, [a_pin.center(), mid_loc])
|
||||
|
||||
|
||||
self.add_layout_pin_rect_center(text="in",
|
||||
layer="m2",
|
||||
offset=mid_loc)
|
||||
|
|
@ -213,4 +212,3 @@ class delay_chain(design.design):
|
|||
self.add_layout_pin_rect_center(text="out",
|
||||
layer="m1",
|
||||
offset=a_pin.center())
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ class dff_array(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def add_pins(self):
|
||||
for row in range(self.rows):
|
||||
|
|
|
|||
|
|
@ -58,17 +58,14 @@ class dff_buf(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=self.inv1_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = factory.create(module_type="pinv",
|
||||
size=self.inv2_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
def add_pins(self):
|
||||
self.add_pin_list(["D", "Q", "Qb", "clk", "vdd", "gnd"],
|
||||
|
|
@ -110,7 +107,7 @@ class dff_buf(design.design):
|
|||
pass
|
||||
|
||||
well_spacing += 2 * self.well_extend_active
|
||||
|
||||
|
||||
self.inv1_inst.place(vector(self.dff_inst.rx() + well_spacing, 0))
|
||||
|
||||
# Add INV2 to the right
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ class dff_buf_array(design.design):
|
|||
self.dff = factory.create(module_type="dff_buf",
|
||||
inv1_size=self.inv1_size,
|
||||
inv2_size=self.inv2_size)
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def create_dff_array(self):
|
||||
self.dff_insts={}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
#
|
||||
import debug
|
||||
import design
|
||||
from tech import drc
|
||||
from math import log
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from pinv import pinv
|
||||
from sram_factory import factory
|
||||
|
||||
|
||||
class dff_inv(design.design):
|
||||
"""
|
||||
|
|
@ -66,12 +65,10 @@ class dff_inv(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.dff = dff_inv.dff_inv(self.inv_size)
|
||||
self.add_mod(self.dff)
|
||||
|
||||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=self.inv_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
def create_modules(self):
|
||||
self.dff_inst=self.add_inst(name="dff_inv_dff",
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class dff_inv_array(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def add_pins(self):
|
||||
for row in range(self.rows):
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class dummy_array(bitcell_base_array):
|
|||
|
||||
self.dummy_cell = factory.create(module_type=OPTS.dummy_bitcell)
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
self.add_mod(self.dummy_cell)
|
||||
|
||||
def create_instances(self):
|
||||
""" Create the module instances used in this design """
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class global_bitcell_array(bitcell_base_array.bitcell_base_array):
|
|||
rbl=self.rbl,
|
||||
left_rbl=[0],
|
||||
right_rbl=[1] if len(self.all_ports) > 1 else [])
|
||||
self.add_mod(la)
|
||||
self.local_mods.append(la)
|
||||
return
|
||||
|
||||
|
|
@ -90,7 +89,6 @@ class global_bitcell_array(bitcell_base_array.bitcell_base_array):
|
|||
cols=cols,
|
||||
rbl=self.rbl)
|
||||
|
||||
self.add_mod(la)
|
||||
self.local_mods.append(la)
|
||||
|
||||
def add_pins(self):
|
||||
|
|
@ -344,4 +342,3 @@ class global_bitcell_array(bitcell_base_array.bitcell_base_array):
|
|||
"""Exclude dffs from graph as they do not represent critical path"""
|
||||
|
||||
self.graph_inst_exclude.add(self.ctrl_dff_inst)
|
||||
|
||||
|
|
|
|||
|
|
@ -69,14 +69,11 @@ class hierarchical_decoder(design.design):
|
|||
def add_modules(self):
|
||||
self.and2 = factory.create(module_type="and2_dec",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.and2)
|
||||
|
||||
self.and3 = factory.create(module_type="and3_dec",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.and3)
|
||||
# TBD
|
||||
# self.and4 = factory.create(module_type="and4_dec")
|
||||
# self.add_mod(self.and4)
|
||||
|
||||
self.add_decoders()
|
||||
|
||||
|
|
@ -84,15 +81,12 @@ class hierarchical_decoder(design.design):
|
|||
""" Create the decoders based on the number of pre-decodes """
|
||||
self.pre2_4 = factory.create(module_type="hierarchical_predecode2x4",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.pre2_4)
|
||||
|
||||
self.pre3_8 = factory.create(module_type="hierarchical_predecode3x8",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.pre3_8)
|
||||
|
||||
self.pre4_16 = factory.create(module_type="hierarchical_predecode4x16",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.pre4_16)
|
||||
|
||||
def determine_predecodes(self, num_inputs):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class hierarchical_predecode(design.design):
|
|||
self.cell_height = b.height
|
||||
else:
|
||||
self.cell_height = height
|
||||
|
||||
|
||||
self.column_decoder = column_decoder
|
||||
self.input_and_rail_pos = []
|
||||
self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
|
||||
|
|
@ -59,13 +59,11 @@ class hierarchical_predecode(design.design):
|
|||
inv_type = "inv_dec"
|
||||
self.and_mod = factory.create(module_type=and_type,
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.and_mod)
|
||||
|
||||
# This uses the pinv_dec parameterized cell
|
||||
self.inv = factory.create(module_type=inv_type,
|
||||
height=self.cell_height,
|
||||
size=1)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
""" The general organization is from left to right:
|
||||
|
|
@ -189,13 +187,13 @@ class hierarchical_predecode(design.design):
|
|||
self.route_input_inverters()
|
||||
self.route_input_ands()
|
||||
self.route_output_inverters()
|
||||
self.route_inputs_to_rails()
|
||||
self.route_inputs_to_rails()
|
||||
self.route_output_ands()
|
||||
self.route_vdd_gnd()
|
||||
|
||||
def route_inputs_to_rails(self):
|
||||
""" Route the uninverted inputs to the second set of rails """
|
||||
|
||||
|
||||
top_and_gate = self.and_inst[-1]
|
||||
for num in range(self.number_of_inputs):
|
||||
if num == 0:
|
||||
|
|
@ -221,7 +219,7 @@ class hierarchical_predecode(design.design):
|
|||
to_layer=self.bus_layer,
|
||||
offset=[self.input_rails[in_pin].cx(), y_offset],
|
||||
directions= ("H", "H"))
|
||||
|
||||
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.decode_rails[a_pin].cx(), y_offset],
|
||||
|
|
@ -306,7 +304,7 @@ class hierarchical_predecode(design.design):
|
|||
else: # grow the stack down
|
||||
search_id = 2
|
||||
next_id = 0
|
||||
|
||||
|
||||
curr_stack = next(filter(lambda stack: stack[search_id] == cur_layer, layer_stacks), None)
|
||||
|
||||
via = factory.create(module_type="contact",
|
||||
|
|
@ -343,7 +341,7 @@ class hierarchical_predecode(design.design):
|
|||
"""
|
||||
Route the different permutations of the NAND/AND decocer cells.
|
||||
"""
|
||||
|
||||
|
||||
# This 2D array defines the connection mapping
|
||||
and_input_line_combination = self.get_and_input_line_combination()
|
||||
for k in range(self.number_of_outputs):
|
||||
|
|
@ -419,6 +417,3 @@ class hierarchical_predecode(design.design):
|
|||
self.and_inst[0].lx() - self.bus_space]:
|
||||
pin_pos = vector(xoffset, and_pin.cy())
|
||||
self.copy_power_pin(and_pin, loc=pin_pos)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -73,12 +73,10 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
|||
rbl=self.rbl,
|
||||
left_rbl=self.left_rbl,
|
||||
right_rbl=self.right_rbl)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
self.wl_array = factory.create(module_type="wordline_buffer_array",
|
||||
rows=self.rows + 1,
|
||||
cols=self.cols)
|
||||
self.add_mod(self.wl_array)
|
||||
|
||||
def add_pins(self):
|
||||
# Outputs from the wordline driver (by port)
|
||||
|
|
|
|||
|
|
@ -172,47 +172,36 @@ class multibank(design.design):
|
|||
|
||||
self.bitcell_array = self.mod_bitcell_array(cols=self.num_cols,
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
self.precharge_array = self.mod_precharge_array(columns=self.num_cols)
|
||||
self.add_mod(self.precharge_array)
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
self.column_mux_array = self.mod_column_mux_array(columns=self.num_cols,
|
||||
word_size=self.word_size)
|
||||
self.add_mod(self.column_mux_array)
|
||||
|
||||
|
||||
self.sense_amp_array = self.mod_sense_amp_array(word_size=self.word_size,
|
||||
words_per_row=self.words_per_row)
|
||||
self.add_mod(self.sense_amp_array)
|
||||
|
||||
if self.write_size:
|
||||
self.write_mask_driver_array = self.mod_write_mask_driver_array(columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
write_size=self.write_size)
|
||||
self.add_mod(self.write_mask_driver_array)
|
||||
else:
|
||||
self.write_driver_array = self.mod_write_driver_array(columns=self.num_cols,
|
||||
word_size=self.word_size)
|
||||
self.add_mod(self.write_driver_array)
|
||||
|
||||
self.row_decoder = self.mod_decoder(rows=self.num_rows)
|
||||
self.add_mod(self.row_decoder)
|
||||
|
||||
self.tri_gate_array = self.mod_tri_gate_array(columns=self.num_cols,
|
||||
word_size=self.word_size)
|
||||
self.add_mod(self.tri_gate_array)
|
||||
|
||||
self.wordline_driver = self.mod_wordline_driver(rows=self.num_rows)
|
||||
self.add_mod(self.wordline_driver)
|
||||
|
||||
self.inv = pinv()
|
||||
self.add_mod(self.inv)
|
||||
|
||||
if(self.num_banks > 1):
|
||||
self.bank_select = self.mod_bank_select()
|
||||
self.add_mod(self.bank_select)
|
||||
|
||||
|
||||
def add_bitcell_array(self):
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ class bitcell_array(bitcell_base_array):
|
|||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
self.add_mod(self.cell)
|
||||
|
||||
def create_instances(self):
|
||||
""" Create the module instances used in this design """
|
||||
|
|
|
|||
|
|
@ -145,12 +145,10 @@ class port_address(design.design):
|
|||
|
||||
self.row_decoder = factory.create(module_type="decoder",
|
||||
num_outputs=self.num_rows)
|
||||
self.add_mod(self.row_decoder)
|
||||
|
||||
self.wordline_driver_array = factory.create(module_type="wordline_driver_array",
|
||||
rows=self.num_rows,
|
||||
cols=self.num_cols)
|
||||
self.add_mod(self.wordline_driver_array)
|
||||
|
||||
local_array_size = OPTS.local_array_size
|
||||
if local_array_size > 0:
|
||||
|
|
@ -174,8 +172,6 @@ class port_address(design.design):
|
|||
size=driver_size,
|
||||
height=b.height)
|
||||
|
||||
self.add_mod(self.rbl_driver)
|
||||
|
||||
def create_row_decoder(self):
|
||||
""" Create the hierarchical row decoder """
|
||||
|
||||
|
|
@ -235,7 +231,7 @@ class port_address(design.design):
|
|||
# The wordline driver also had an extra gap on the right, so use this offset
|
||||
well_gap = 2 * drc("pwell_to_nwell") + drc("nwell_enclose_active")
|
||||
x_offset = self.wordline_driver_array_inst.rx() - well_gap - self.rbl_driver.width
|
||||
|
||||
|
||||
if self.port == 0:
|
||||
rbl_driver_offset = vector(x_offset,
|
||||
0)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class port_data(design.design):
|
|||
self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
||||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
|
||||
if num_spare_cols is not None:
|
||||
self.num_spare_cols = num_spare_cols + self.num_spare_cols
|
||||
if self.num_spare_cols is None:
|
||||
|
|
@ -215,7 +215,6 @@ class port_data(design.design):
|
|||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port],
|
||||
column_offset=self.port - 1)
|
||||
self.add_mod(self.precharge_array)
|
||||
|
||||
if self.port in self.read_ports:
|
||||
# RBLs don't get a sense amp
|
||||
|
|
@ -224,7 +223,6 @@ class port_data(design.design):
|
|||
offsets=self.bit_offsets,
|
||||
words_per_row=self.words_per_row,
|
||||
num_spare_cols=self.num_spare_cols)
|
||||
self.add_mod(self.sense_amp_array)
|
||||
else:
|
||||
self.sense_amp_array = None
|
||||
|
||||
|
|
@ -236,7 +234,6 @@ class port_data(design.design):
|
|||
offsets=self.bit_offsets,
|
||||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port])
|
||||
self.add_mod(self.column_mux_array)
|
||||
else:
|
||||
self.column_mux_array = None
|
||||
|
||||
|
|
@ -248,7 +245,6 @@ class port_data(design.design):
|
|||
offsets=self.bit_offsets,
|
||||
write_size=self.write_size,
|
||||
num_spare_cols=self.num_spare_cols)
|
||||
self.add_mod(self.write_driver_array)
|
||||
if self.write_size is not None:
|
||||
# RBLs don't get a write mask
|
||||
self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
|
||||
|
|
@ -256,7 +252,6 @@ class port_data(design.design):
|
|||
offsets=self.bit_offsets,
|
||||
word_size=self.word_size,
|
||||
write_size=self.write_size)
|
||||
self.add_mod(self.write_mask_and_array)
|
||||
else:
|
||||
self.write_mask_and_array = None
|
||||
|
||||
|
|
@ -858,10 +853,10 @@ class port_data(design.design):
|
|||
"""
|
||||
if self.column_mux_array:
|
||||
self.column_mux_array.graph_exclude_columns(column_include_num)
|
||||
|
||||
|
||||
def graph_clear_column_mux(self):
|
||||
"""
|
||||
Clear mux exclusions to allow different bit tests.
|
||||
"""
|
||||
if self.column_mux_array:
|
||||
self.column_mux_array.init_graph_params()
|
||||
self.column_mux_array.init_graph_params()
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ class precharge_array(design.design):
|
|||
size=self.size,
|
||||
bitcell_bl=self.bitcell_bl,
|
||||
bitcell_br=self.bitcell_br)
|
||||
|
||||
self.add_mod(self.pc_cell)
|
||||
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
|
||||
def add_layout_pins(self):
|
||||
|
|
@ -130,5 +129,3 @@ class precharge_array(design.design):
|
|||
|
||||
offset = vector(tempx, 0)
|
||||
self.local_insts[i].place(offset=offset, mirror=mirror)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
column_offset=1 + len(self.left_rbl),
|
||||
cols=self.column_size,
|
||||
rows=self.row_size)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
# Replica bitlines
|
||||
self.replica_columns = {}
|
||||
|
|
@ -138,7 +137,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
rbl=self.rbl,
|
||||
column_offset=column_offset,
|
||||
replica_bit=replica_bit)
|
||||
self.add_mod(self.replica_columns[port])
|
||||
|
||||
# Dummy row
|
||||
self.dummy_row = factory.create(module_type="dummy_array",
|
||||
|
|
@ -147,7 +145,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
# dummy column + left replica column
|
||||
column_offset=1 + len(self.left_rbl),
|
||||
mirror=0)
|
||||
self.add_mod(self.dummy_row)
|
||||
|
||||
# Dummy Row or Col Cap, depending on bitcell array properties
|
||||
col_cap_module_type = ("col_cap_array" if self.cell.end_caps else "dummy_array")
|
||||
|
|
@ -158,7 +155,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
column_offset=1 + len(self.left_rbl),
|
||||
mirror=0,
|
||||
location="top")
|
||||
self.add_mod(self.col_cap_top)
|
||||
|
||||
self.col_cap_bottom = factory.create(module_type=col_cap_module_type,
|
||||
cols=self.column_size,
|
||||
|
|
@ -167,7 +163,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
column_offset=1 + len(self.left_rbl),
|
||||
mirror=0,
|
||||
location="bottom")
|
||||
self.add_mod(self.col_cap_bottom)
|
||||
|
||||
# Dummy Col or Row Cap, depending on bitcell array properties
|
||||
row_cap_module_type = ("row_cap_array" if self.cell.end_caps else "dummy_array")
|
||||
|
|
@ -177,7 +172,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
column_offset=0,
|
||||
rows=self.row_size + self.extra_rows,
|
||||
mirror=(self.rbl[0] + 1) % 2)
|
||||
self.add_mod(self.row_cap_left)
|
||||
|
||||
self.row_cap_right = factory.create(module_type=row_cap_module_type,
|
||||
cols=1,
|
||||
|
|
@ -188,7 +182,6 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
column_offset=1 + len(self.left_rbl) + self.column_size + self.rbl[0],
|
||||
rows=self.row_size + self.extra_rows,
|
||||
mirror=(self.rbl[0] + 1) %2)
|
||||
self.add_mod(self.row_cap_right)
|
||||
|
||||
def add_pins(self):
|
||||
|
||||
|
|
@ -401,7 +394,7 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul()
|
||||
self.dummy_row_insts[1].place(offset=dummy_row_offset,
|
||||
mirror="MX" if flip_dummy else "R0")
|
||||
|
||||
|
||||
# Far bottom dummy row (first row below array IS flipped)
|
||||
flip_dummy = (self.rbl[0] + 1) % 2
|
||||
dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - 1 + flip_dummy) + self.unused_offset
|
||||
|
|
@ -411,7 +404,7 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
# Shifted down by the number of left RBLs even if we aren't adding replica column to this bitcell array
|
||||
dummy_col_offset = self.bitcell_offset.scale(-len(self.left_rbl) - 1, -self.rbl[0] - 1) + self.unused_offset
|
||||
self.dummy_col_insts[0].place(offset=dummy_col_offset)
|
||||
|
||||
|
||||
# Far right dummy col
|
||||
# Shifted down by the number of left RBLs even if we aren't adding replica column to this bitcell array
|
||||
dummy_col_offset = self.bitcell_offset.scale(len(self.right_rbl), -self.rbl[0] - 1) + self.bitcell_array_inst.lr()
|
||||
|
|
@ -430,7 +423,7 @@ class replica_bitcell_array(bitcell_base_array):
|
|||
offset=pin.ll().scale(0, 1),
|
||||
width=self.width,
|
||||
height=pin.height())
|
||||
|
||||
|
||||
# Replica wordlines (go by the row instead of replica column because we may have to add a pin
|
||||
# even though the column is in another local bitcell array)
|
||||
for (names, inst) in zip(self.rbl_wordline_names, self.dummy_row_replica_insts):
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class replica_column(bitcell_base_array):
|
|||
self.left_rbl = rbl[0]
|
||||
self.right_rbl = rbl[1]
|
||||
self.replica_bit = replica_bit
|
||||
|
||||
|
||||
# Total size includes the replica rows and column cap rows
|
||||
self.total_size = self.left_rbl + rows + self.right_rbl + 2
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ class replica_column(bitcell_base_array):
|
|||
|
||||
def create_layout(self):
|
||||
self.place_instances()
|
||||
|
||||
|
||||
self.height = self.cell_inst[-1].uy()
|
||||
self.width = self.cell_inst[0].rx()
|
||||
|
||||
|
|
@ -85,15 +85,14 @@ class replica_column(bitcell_base_array):
|
|||
|
||||
def add_modules(self):
|
||||
self.replica_cell = factory.create(module_type=OPTS.replica_bitcell)
|
||||
self.add_mod(self.replica_cell)
|
||||
|
||||
self.dummy_cell = factory.create(module_type=OPTS.dummy_bitcell)
|
||||
self.add_mod(self.dummy_cell)
|
||||
|
||||
try:
|
||||
edge_module_type = ("col_cap" if self.cell.end_caps else "dummy")
|
||||
except AttributeError:
|
||||
edge_module_type = "dummy"
|
||||
self.edge_cell = factory.create(module_type=edge_module_type + "_" + OPTS.bitcell)
|
||||
self.add_mod(self.edge_cell)
|
||||
|
||||
def create_instances(self):
|
||||
self.cell_inst = []
|
||||
|
|
@ -103,7 +102,7 @@ class replica_column(bitcell_base_array):
|
|||
real_row = row
|
||||
if self.cell.end_caps:
|
||||
real_row -= 1
|
||||
|
||||
|
||||
# Regular array cells are replica cells
|
||||
# Replic bit specifies which other bit (in the full range (0,total_size) to make a replica cell.
|
||||
if (row == 0 or row == self.total_size - 1):
|
||||
|
|
@ -238,4 +237,3 @@ class replica_column(bitcell_base_array):
|
|||
for row, cell in enumerate(self.cell_inst):
|
||||
if row != self.replica_bit:
|
||||
self.graph_inst_exclude.add(cell)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,13 @@ class row_cap_array(bitcell_base_array):
|
|||
|
||||
self.width = max([x.rx() for x in self.insts])
|
||||
self.height = max([x.uy() for x in self.insts])
|
||||
|
||||
|
||||
self.add_boundary()
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
self.dummy_cell = factory.create(module_type="row_cap_{}".format(OPTS.bitcell))
|
||||
self.add_mod(self.dummy_cell)
|
||||
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
|
||||
|
|
@ -114,4 +113,3 @@ class row_cap_array(bitcell_base_array):
|
|||
for pin_name in ["vdd", "gnd"]:
|
||||
for pin in inst.get_pins(pin_name):
|
||||
self.copy_power_pin(pin)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ class sense_amp_array(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.amp = factory.create(module_type="sense_amp")
|
||||
self.add_mod(self.amp)
|
||||
|
||||
# This is just used for measurements,
|
||||
# so don't add the module
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class tri_gate_array(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.tri = factory.create(module_type="tri_gate")
|
||||
self.add_mod(self.tri)
|
||||
|
||||
def add_pins(self):
|
||||
"""create the name of pins depend on the word size"""
|
||||
|
|
@ -120,4 +119,4 @@ class tri_gate_array(design.design):
|
|||
layer="m1",
|
||||
offset=enbar_pin.ll().scale(0, 1),
|
||||
width=width,
|
||||
height=drc("minwidth_m1"))
|
||||
height=drc("minwidth_m1"))
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class wordline_buffer_array(design.design):
|
|||
self.wl_driver = factory.create(module_type="inv_dec",
|
||||
size=self.cols,
|
||||
height=b.height)
|
||||
self.add_mod(self.wl_driver)
|
||||
|
||||
def route_vdd_gnd(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -65,8 +65,6 @@ class wordline_driver_array(design.design):
|
|||
self.wl_driver = factory.create(module_type="wordline_driver",
|
||||
cols=self.cols)
|
||||
|
||||
self.add_mod(self.wl_driver)
|
||||
|
||||
def route_vdd_gnd(self):
|
||||
"""
|
||||
Add a pin for each row of vdd/gnd which
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ class write_driver_array(design.design):
|
|||
|
||||
def add_modules(self):
|
||||
self.driver = factory.create(module_type="write_driver")
|
||||
self.add_mod(self.driver)
|
||||
|
||||
# This is just used for measurements,
|
||||
# so don't add the module
|
||||
|
|
@ -259,4 +258,3 @@ class write_driver_array(design.design):
|
|||
layer="m1",
|
||||
offset=inst.get_pin(inst.mod.en_name).ll().scale(0, 1),
|
||||
width=self.width)
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ class write_mask_and_array(design.design):
|
|||
# Assume stage effort of 3 to compute the size
|
||||
self.and2 = factory.create(module_type="pand2",
|
||||
size=max(self.write_size / 4.0, 1))
|
||||
self.add_mod(self.and2)
|
||||
|
||||
def create_and2_array(self):
|
||||
self.and2_insts = {}
|
||||
|
|
@ -146,7 +145,7 @@ class write_mask_and_array(design.design):
|
|||
self.add_via_stack_center(from_layer=supply_pin.layer,
|
||||
to_layer="m1",
|
||||
offset=supply_pin.center())
|
||||
|
||||
|
||||
for supply in ["gnd", "vdd"]:
|
||||
supply_pin = self.and2_insts[0].get_pin(supply)
|
||||
supply_pin_yoffset = supply_pin.cy()
|
||||
|
|
@ -158,4 +157,3 @@ class write_mask_and_array(design.design):
|
|||
to_layer="m1",
|
||||
offset=loc)
|
||||
self.copy_power_pin(supply_pin, loc=loc)
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ class column_mux(pgate.pgate):
|
|||
self.ptx_width = self.tx_size * drc("minwidth_tx")
|
||||
self.nmos = factory.create(module_type="ptx",
|
||||
width=self.ptx_width)
|
||||
self.add_mod(self.nmos)
|
||||
|
||||
# Space it in the center
|
||||
self.nmos_lower = self.add_inst(name="mux_tx1",
|
||||
|
|
|
|||
|
|
@ -39,9 +39,6 @@ class pand2(pgate.pgate):
|
|||
height=self.height,
|
||||
add_wells=self.add_wells)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
if self.vertical:
|
||||
self.height = 2 * self.nand.height
|
||||
|
|
@ -146,8 +143,8 @@ class pand2(pgate.pgate):
|
|||
offset=pin.center(),
|
||||
width=pin.width(),
|
||||
height=pin.height())
|
||||
|
||||
|
||||
def is_non_inverting(self):
|
||||
"""Return input to output polarity for module"""
|
||||
|
||||
return True
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ class pand3(pgate.pgate):
|
|||
height=self.height,
|
||||
add_wells=self.add_wells)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
if self.vertical:
|
||||
self.height = 2 * self.nand.height
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ class pand4(pgate.pgate):
|
|||
height=self.height,
|
||||
add_wells=self.add_wells)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_layout(self):
|
||||
if self.vertical:
|
||||
self.height = 2 * self.nand.height
|
||||
|
|
@ -162,4 +159,3 @@ class pand4(pgate.pgate):
|
|||
slew=nand_delay.slew,
|
||||
load=load)
|
||||
return nand_delay + inv_delay
|
||||
|
||||
|
|
|
|||
|
|
@ -52,13 +52,11 @@ class pbuf(pgate.pgate):
|
|||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=input_size,
|
||||
height=self.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = factory.create(module_type="pinv",
|
||||
size=self.size,
|
||||
height=self.height,
|
||||
add_wells=False)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
def create_insts(self):
|
||||
self.inv1_inst = self.add_inst(name="buf_inv1",
|
||||
|
|
@ -96,4 +94,3 @@ class pbuf(pgate.pgate):
|
|||
offset=a_pin.center(),
|
||||
width=a_pin.width(),
|
||||
height=a_pin.height())
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,10 @@ class pbuf_dec(pgate.pgate):
|
|||
self.inv1 = factory.create(module_type="pinv_dec",
|
||||
size=input_size,
|
||||
height=self.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = factory.create(module_type="pinv_dec",
|
||||
size=self.size,
|
||||
height=self.height)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
def create_insts(self):
|
||||
self.inv1_inst = self.add_inst(name="buf_inv1",
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ class pdriver(pgate.pgate):
|
|||
height=self.height,
|
||||
add_wells=self.add_wells)
|
||||
self.inv_list.append(temp_inv)
|
||||
self.add_mod(temp_inv)
|
||||
|
||||
def create_insts(self):
|
||||
self.inv_inst_list = []
|
||||
|
|
|
|||
|
|
@ -207,7 +207,6 @@ class pinv(pgate.pgate):
|
|||
add_drain_contact=self.route_layer,
|
||||
connect_poly=True,
|
||||
connect_drain_active=True)
|
||||
self.add_mod(self.nmos)
|
||||
|
||||
self.pmos = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -217,7 +216,6 @@ class pinv(pgate.pgate):
|
|||
add_drain_contact=self.route_layer,
|
||||
connect_poly=True,
|
||||
connect_drain_active=True)
|
||||
self.add_mod(self.pmos)
|
||||
|
||||
def create_ptx(self):
|
||||
"""
|
||||
|
|
@ -337,30 +335,29 @@ class pinv(pgate.pgate):
|
|||
Overrides base class function.
|
||||
"""
|
||||
self.add_graph_edges(graph, port_nets)
|
||||
|
||||
|
||||
def is_non_inverting(self):
|
||||
"""Return input to output polarity for module"""
|
||||
|
||||
return False
|
||||
return False
|
||||
|
||||
def get_on_resistance(self):
|
||||
"""On resistance of pinv, defined by single nmos"""
|
||||
is_nchannel = True
|
||||
stack = 1
|
||||
is_cell = False
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
|
||||
def get_input_capacitance(self):
|
||||
"""Input cap of input, passes width of gates to gate cap function"""
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
|
||||
def get_intrinsic_capacitance(self):
|
||||
"""Get the drain capacitances of the TXs in the gate."""
|
||||
nmos_stack = 1
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_stack,
|
||||
self.tx_mults)
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
1,
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
|
|
|
|||
|
|
@ -65,17 +65,14 @@ class pinvbuf(pgate.pgate):
|
|||
self.inv = factory.create(module_type="pinv",
|
||||
size=input_size,
|
||||
height=self.row_height)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=self.predriver_size,
|
||||
height=self.row_height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = factory.create(module_type="pinv",
|
||||
size=self.size,
|
||||
height=self.row_height)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
def create_insts(self):
|
||||
# Create INV1 (capacitance shield)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ class pnand2(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.nmos_left)
|
||||
|
||||
self.nmos_right = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -87,7 +86,6 @@ class pnand2(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.nmos_right)
|
||||
|
||||
self.pmos_left = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -95,7 +93,6 @@ class pnand2(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_left)
|
||||
|
||||
self.pmos_right = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -103,7 +100,6 @@ class pnand2(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_right)
|
||||
|
||||
def setup_layout_constants(self):
|
||||
""" Pre-compute some handy layout parameters. """
|
||||
|
|
@ -317,28 +313,26 @@ class pnand2(pgate.pgate):
|
|||
|
||||
def is_non_inverting(self):
|
||||
"""Return input to output polarity for module"""
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_on_resistance(self):
|
||||
"""On resistance of pnand, defined by stacked NMOS"""
|
||||
is_nchannel = True
|
||||
stack = 2
|
||||
is_cell = False
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
|
||||
def get_input_capacitance(self):
|
||||
"""Input cap of input, passes width of gates to gate cap function"""
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
|
||||
def get_intrinsic_capacitance(self):
|
||||
"""Get the drain capacitances of the TXs in the gate."""
|
||||
nmos_stack = 2
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_stack,
|
||||
self.tx_mults)
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
1,
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.nmos_center)
|
||||
|
||||
self.nmos_right = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -90,7 +89,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.nmos_right)
|
||||
|
||||
self.nmos_left = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -98,7 +96,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.nmos_left)
|
||||
|
||||
self.pmos_left = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -106,7 +103,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_left)
|
||||
|
||||
self.pmos_center = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -114,7 +110,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_center)
|
||||
|
||||
self.pmos_right = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -122,7 +117,6 @@ class pnand3(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_right)
|
||||
|
||||
def setup_layout_constants(self):
|
||||
""" Pre-compute some handy layout parameters. """
|
||||
|
|
@ -350,27 +344,26 @@ class pnand3(pgate.pgate):
|
|||
|
||||
def is_non_inverting(self):
|
||||
"""Return input to output polarity for module"""
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_on_resistance(self):
|
||||
"""On resistance of pnand, defined by stacked NMOS"""
|
||||
is_nchannel = True
|
||||
stack = 3
|
||||
is_cell = False
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
|
||||
return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell)
|
||||
|
||||
def get_input_capacitance(self):
|
||||
"""Input cap of input, passes width of gates to gate cap function"""
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
|
||||
return self.gate_c(self.nmos_width+self.pmos_width)
|
||||
|
||||
def get_intrinsic_capacitance(self):
|
||||
"""Get the drain capacitances of the TXs in the gate."""
|
||||
nmos_stack = 3
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
|
||||
nmos_stack,
|
||||
self.tx_mults)
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
|
||||
1,
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
self.tx_mults)
|
||||
return nmos_drain_c + pmos_drain_c
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.nmos_center)
|
||||
|
||||
self.nmos_right = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -90,7 +89,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.nmos_right)
|
||||
|
||||
self.nmos_left = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -98,7 +96,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.nmos_left)
|
||||
|
||||
self.pmos_left = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -106,7 +103,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_left)
|
||||
|
||||
self.pmos_center = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -114,7 +110,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_center)
|
||||
|
||||
self.pmos_right = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -122,7 +117,6 @@ class pnand4(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_right)
|
||||
|
||||
def setup_layout_constants(self):
|
||||
""" Pre-compute some handy layout parameters. """
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ class pnor2(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.nmos_left)
|
||||
|
||||
self.nmos_right = factory.create(module_type="ptx",
|
||||
width=self.nmos_width,
|
||||
|
|
@ -85,7 +84,6 @@ class pnor2(pgate.pgate):
|
|||
tx_type="nmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.nmos_right)
|
||||
|
||||
self.pmos_left = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -93,7 +91,6 @@ class pnor2(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact=self.route_layer,
|
||||
add_drain_contact="active")
|
||||
self.add_mod(self.pmos_left)
|
||||
|
||||
self.pmos_right = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
|
|
@ -101,7 +98,6 @@ class pnor2(pgate.pgate):
|
|||
tx_type="pmos",
|
||||
add_source_contact="active",
|
||||
add_drain_contact=self.route_layer)
|
||||
self.add_mod(self.pmos_right)
|
||||
|
||||
def setup_layout_constants(self):
|
||||
""" Pre-compute some handy layout parameters. """
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ class precharge(design.design):
|
|||
width=self.ptx_width,
|
||||
mults=self.ptx_mults,
|
||||
tx_type="pmos")
|
||||
self.add_mod(self.pmos)
|
||||
|
||||
def route_vdd_rail(self):
|
||||
"""
|
||||
|
|
@ -305,4 +304,3 @@ class precharge(design.design):
|
|||
self.add_path(self.bitline_layer,
|
||||
[left_pos, right_pos],
|
||||
width=pmos_pin.height())
|
||||
|
||||
|
|
|
|||
|
|
@ -85,13 +85,11 @@ class ptristate_inv(pgate.pgate):
|
|||
width=self.nmos_width,
|
||||
mults=1,
|
||||
tx_type="nmos")
|
||||
self.add_mod(self.nmos)
|
||||
|
||||
self.pmos = factory.create(module_type="ptx",
|
||||
width=self.pmos_width,
|
||||
mults=1,
|
||||
tx_type="pmos")
|
||||
self.add_mod(self.pmos)
|
||||
|
||||
def route_supply_rails(self):
|
||||
""" Add vdd/gnd rails to the top and bottom. """
|
||||
|
|
|
|||
|
|
@ -66,19 +66,16 @@ class pwrite_driver(design.design):
|
|||
|
||||
# Tristate inverter
|
||||
self.tri = factory.create(module_type="ptristate_inv", height="min")
|
||||
self.add_mod(self.tri)
|
||||
debug.check(self.tri.width<self.width,
|
||||
"Could not create tristate inverter to match bitcell width")
|
||||
|
||||
#self.tbuf = factory.create(module_type="ptristate_buf",
|
||||
#height="min")
|
||||
#self.add_mod(self.tbuf)
|
||||
#debug.check(self.tbuf.width<self.width,
|
||||
#"Could not create tristate buffer to match bitcell width")
|
||||
|
||||
# Inverter for din and en
|
||||
self.inv = factory.create(module_type="pinv", under_rail_vias=True)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_insts(self):
|
||||
# Enable inverter
|
||||
|
|
|
|||
|
|
@ -62,9 +62,6 @@ class wordline_driver(design.design):
|
|||
size=driver_size,
|
||||
height=self.nand.height)
|
||||
|
||||
self.add_mod(self.nand)
|
||||
self.add_mod(self.driver)
|
||||
|
||||
def create_layout(self):
|
||||
self.width = self.nand.width + self.driver.width
|
||||
if "li" in layer:
|
||||
|
|
|
|||
|
|
@ -468,11 +468,9 @@ class sram_base(design, verilog, lef):
|
|||
self.msb_address = dff_buf_array(name="msb_address",
|
||||
rows=1,
|
||||
columns=self.num_banks / 2)
|
||||
self.add_mod(self.msb_address)
|
||||
|
||||
if self.num_banks>2:
|
||||
self.msb_decoder = self.bank.decoder.pre2_4
|
||||
self.add_mod(self.msb_decoder)
|
||||
|
||||
def add_modules(self):
|
||||
self.bitcell = factory.create(module_type=OPTS.bitcell)
|
||||
|
|
@ -480,30 +478,24 @@ class sram_base(design, verilog, lef):
|
|||
|
||||
# Create the bank module (up to four are instantiated)
|
||||
self.bank = factory.create("bank", sram_config=self.sram_config, module_name="bank")
|
||||
self.add_mod(self.bank)
|
||||
|
||||
self.num_spare_cols = self.bank.num_spare_cols
|
||||
|
||||
# Create the address and control flops (but not the clk)
|
||||
self.row_addr_dff = factory.create("dff_array", module_name="row_addr_dff", rows=self.row_addr_size, columns=1)
|
||||
self.add_mod(self.row_addr_dff)
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
self.col_addr_dff = factory.create("dff_array", module_name="col_addr_dff", rows=1, columns=self.col_addr_size)
|
||||
self.add_mod(self.col_addr_dff)
|
||||
else:
|
||||
self.col_addr_dff = None
|
||||
|
||||
self.data_dff = factory.create("dff_array", module_name="data_dff", rows=1, columns=self.word_size + self.num_spare_cols)
|
||||
self.add_mod(self.data_dff)
|
||||
|
||||
if self.write_size:
|
||||
self.wmask_dff = factory.create("dff_array", module_name="wmask_dff", rows=1, columns=self.num_wmasks)
|
||||
self.add_mod(self.wmask_dff)
|
||||
|
||||
if self.num_spare_cols:
|
||||
self.spare_wen_dff = factory.create("dff_array", module_name="spare_wen_dff", rows=1, columns=self.num_spare_cols)
|
||||
self.add_mod(self.spare_wen_dff)
|
||||
|
||||
# Create bank decoder
|
||||
if(self.num_banks > 1):
|
||||
|
|
@ -515,30 +507,27 @@ class sram_base(design, verilog, lef):
|
|||
self.mod_control_logic = getattr(c, OPTS.control_logic)
|
||||
|
||||
# Create the control logic module for each port type
|
||||
if len(self.readwrite_ports)>0:
|
||||
if len(self.readwrite_ports) > 0:
|
||||
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="rw")
|
||||
self.add_mod(self.control_logic_rw)
|
||||
if len(self.writeonly_ports)>0:
|
||||
if len(self.writeonly_ports) > 0:
|
||||
self.control_logic_w = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="w")
|
||||
self.add_mod(self.control_logic_w)
|
||||
if len(self.readonly_ports)>0:
|
||||
if len(self.readonly_ports) > 0:
|
||||
self.control_logic_r = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="r")
|
||||
self.add_mod(self.control_logic_r)
|
||||
|
||||
def create_bank(self, bank_num):
|
||||
""" Create a bank """
|
||||
|
|
@ -779,13 +768,13 @@ class sram_base(design, verilog, lef):
|
|||
Clears the bit exclusions
|
||||
"""
|
||||
self.bank.clear_exclude_bits()
|
||||
|
||||
|
||||
def graph_exclude_column_mux(self, column_include_num, port):
|
||||
"""
|
||||
Excludes all columns muxes unrelated to the target bit being simulated.
|
||||
"""
|
||||
self.bank.graph_exclude_column_mux(column_include_num, port)
|
||||
|
||||
|
||||
def graph_clear_column_mux(self, port):
|
||||
"""
|
||||
Clear mux exclusions to allow different bit tests.
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ lv_ngate = ngate - vtg - thkox
|
|||
gv_ngate = ngate & vtg - vth - thkox
|
||||
hv_ngate = ngate - vtg - vth & thkox
|
||||
|
||||
cheat("cell_1rw", "dummy_cell_1rw", "replica_cell_1rw", "cell_2rw", "dummy_cell_2rw", "replica_cell_2rw", "pbitcell", "dummy_pbitcell", "replica_pbitcell", "dff", "wordline_driver*") {
|
||||
cheat("cell_1rw", "dummy_cell_1rw", "replica_cell_1rw", "cell_2rw", "dummy_cell_2rw", "replica_cell_2rw", "pbitcell*", "dummy_pbitcell*", "replica_pbitcell*", "dff", "wordline_driver*") {
|
||||
|
||||
# PMOS transistor device extraction
|
||||
extract_devices(mos4("PMOS_VTL"), { "SD" => psd, "G" => lv_pgate, "tS" => psd, "tD" => psd, "tG" => poly, "W" => nwell })
|
||||
|
|
|
|||
Loading…
Reference in New Issue