OpenRAM/compiler/modules/replica_bitcell_array.py

541 lines
25 KiB
Python
Raw Normal View History

2019-06-20 01:03:21 +02:00
# See LICENSE for licensing information.
#
2020-05-28 05:03:11 +02:00
# Copyright (c) 2016-2019 Regents of the University of California
2019-06-20 01:03:21 +02:00
# All rights reserved.
#
import debug
2020-08-06 20:17:49 +02:00
import bitcell_base_array
2020-05-28 05:03:11 +02:00
from tech import drc, spice, cell_properties
2019-06-20 01:03:21 +02:00
from vector import vector
from globals import OPTS
from sram_factory import factory
2019-06-20 01:03:21 +02:00
2020-08-06 20:17:49 +02:00
class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
2019-06-20 01:03:21 +02:00
"""
Creates a bitcell arrow of cols x rows and then adds the replica
and dummy columns and rows. Replica columns are on the left and
right, respectively and connected to the given bitcell ports.
2019-06-20 01:03:21 +02:00
Dummy are the outside columns/rows with WL and BL tied to gnd.
Requires a regular bitcell array, replica bitcell, and dummy
bitcell (Bl/BR disconnected).
2019-06-20 01:03:21 +02:00
"""
def __init__(self, rows, cols, left_rbl, right_rbl, bitcell_ports, name, add_replica=True):
2020-08-06 20:17:49 +02:00
super().__init__(name, rows, cols, column_offset=0)
2019-06-20 01:03:21 +02:00
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
self.column_size = cols
self.row_size = rows
self.left_rbl = left_rbl
self.right_rbl = right_rbl
self.bitcell_ports = bitcell_ports
# If set to false, we increase the height for the replica wordline row, but don't
# actually add the column to this array. This is so the height matches other
# banks that have the replica columns.
# Number of replica columns to actually add
if add_replica:
self.add_left_rbl = self.left_rbl
self.add_right_rbl = self.right_rbl
else:
self.add_left_rbl = 0
self.add_right_rbl = 0
2020-08-12 00:00:29 +02:00
debug.check(left_rbl + right_rbl <= len(self.all_ports),
2020-06-05 22:49:32 +02:00
"Invalid number of RBLs for port configuration.")
2020-08-12 00:00:29 +02:00
debug.check(left_rbl + right_rbl <= len(self.bitcell_ports),
2020-06-05 22:49:32 +02:00
"Bitcell ports must match total RBLs.")
2020-05-28 05:03:11 +02:00
# Two dummy rows plus replica even if we don't add the column
self.extra_rows = 2 + self.left_rbl + self.right_rbl
# Two dummy cols plus replica if we add the column
self.extra_cols = 2 + self.add_left_rbl + self.add_right_rbl
2020-05-28 05:03:11 +02:00
2019-06-20 01:03:21 +02:00
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
# We don't offset this because we need to align
# the replica bitcell in the control logic
2020-06-05 22:49:32 +02:00
# self.offset_all_coordinates()
2020-05-28 05:03:11 +02:00
2019-06-20 01:03:21 +02:00
def create_netlist(self):
""" Create and connect the netlist """
self.add_modules()
self.add_pins()
self.create_instances()
def add_modules(self):
2020-05-28 05:03:11 +02:00
""" Array and dummy/replica columns
2019-06-20 01:03:21 +02:00
d or D = dummy cell (caps to distinguish grouping)
r or R = replica cell (caps to distinguish grouping)
2020-05-28 05:03:11 +02:00
b or B = bitcell
replica columns 1
2019-06-20 01:03:21 +02:00
v v
2020-05-28 05:03:11 +02:00
bdDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDrb <- Dummy row
2019-06-20 01:03:21 +02:00
br--------------rb
br| Array |rb
br| row x col |rb
br--------------rb
brDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDdb <- Dummy row
^^^^^^^^^^^^^^^
dummy rows cols x 1
^ dummy columns ^
1 x (rows + 4)
"""
# Bitcell array
self.bitcell_array = factory.create(module_type="bitcell_array",
column_offset=1 + self.add_left_rbl,
2019-06-20 01:03:21 +02:00
cols=self.column_size,
rows=self.row_size)
self.add_mod(self.bitcell_array)
# Replica bitlines
self.replica_columns = {}
for bit in range(self.add_left_rbl + self.add_right_rbl):
# Creating left_rbl
if bit<self.add_left_rbl:
2020-06-05 22:49:32 +02:00
replica_bit = bit + 1
# dummy column
column_offset = self.add_left_rbl - bit
# Creating right_rbl
else:
2020-06-05 22:49:32 +02:00
replica_bit = bit + self.row_size + 1
# dummy column + replica column + bitcell colums
column_offset = self.add_left_rbl - bit + self.row_size
self.replica_columns[bit] = factory.create(module_type="replica_column",
rows=self.row_size,
left_rbl=self.add_left_rbl,
right_rbl=self.add_right_rbl,
column_offset=column_offset,
replica_bit=replica_bit)
self.add_mod(self.replica_columns[bit])
2020-05-28 05:03:11 +02:00
2019-06-20 01:03:21 +02:00
# Dummy row
self.dummy_row = factory.create(module_type="dummy_array",
cols=self.column_size,
rows=1,
# dummy column + left replica column
column_offset=1 + self.add_left_rbl,
mirror=0)
2019-06-20 01:03:21 +02:00
self.add_mod(self.dummy_row)
2020-05-28 05:03:11 +02:00
# If there are bitcell end caps, replace the dummy cells on the edge of the bitcell array with end caps.
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# Dummy Row or Col Cap, depending on bitcell array properties
2020-08-12 00:00:29 +02:00
col_cap_module_type = ("col_cap_array" if end_caps_enabled else "dummy_array")
self.col_cap = factory.create(module_type=col_cap_module_type,
2020-06-05 22:49:32 +02:00
cols=self.column_size,
rows=1,
# dummy column + left replica column(s)
column_offset=1 + self.add_left_rbl,
2020-06-05 22:49:32 +02:00
mirror=0)
2020-08-12 00:00:29 +02:00
self.add_mod(self.col_cap)
2020-05-28 05:03:11 +02:00
# Dummy Col or Row Cap, depending on bitcell array properties
2020-08-12 00:00:29 +02:00
row_cap_module_type = ("row_cap_array" if end_caps_enabled else "dummy_array")
2020-05-28 05:03:11 +02:00
2020-08-12 00:00:29 +02:00
self.row_cap_left = factory.create(module_type=row_cap_module_type,
cols=1,
column_offset=0,
rows=self.row_size + self.extra_rows,
mirror=(self.left_rbl + 1) % 2)
2020-08-12 00:00:29 +02:00
self.add_mod(self.row_cap_left)
2020-08-12 00:00:29 +02:00
self.row_cap_right = factory.create(module_type=row_cap_module_type,
cols=1,
# dummy column
2020-06-05 22:49:32 +02:00
# + left replica column(s)
# + bitcell columns
2020-06-05 22:49:32 +02:00
# + right replica column(s)
column_offset = 1 + self.add_left_rbl + self.column_size + self.add_right_rbl,
rows=self.row_size + self.extra_rows,
2020-06-05 22:49:32 +02:00
mirror=(self.left_rbl + 1) %2)
2020-08-12 00:00:29 +02:00
self.add_mod(self.row_cap_right)
2019-06-20 01:03:21 +02:00
def add_pins(self):
2020-08-12 00:00:29 +02:00
self.add_bitline_pins()
self.add_wordline_pins()
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
def add_bitline_pins(self):
# Regular bitline names for all ports
2020-08-12 00:00:29 +02:00
self.bitline_names = []
# Bitline names for each port
self.bitline_names_by_port = [[] for x in self.all_ports]
# Replica wordlines by port
self.replica_bitline_names = [[] for x in self.all_ports]
# Replica wordlines by port (bl only)
self.replica_bl_names = [[] for x in self.all_ports]
# Dummy wordlines by port
self.dummy_bitline_names = []
2020-08-12 00:00:29 +02:00
# Regular array bitline names
self.bitcell_array_bitline_names = self.bitcell_array.get_all_bitline_names()
2019-06-20 01:03:21 +02:00
# These are the non-indexed names
2020-08-12 00:00:29 +02:00
dummy_bitline_names = ["dummy_" + x for x in self.cell.get_all_bitline_names()]
self.dummy_bitline_names.append([x + "_left" for x in dummy_bitline_names])
self.dummy_bitline_names.append([x + "_right" for x in dummy_bitline_names])
2019-06-20 01:03:21 +02:00
2020-08-12 00:00:29 +02:00
# Array of all port bitline names
for port in range(self.add_left_rbl + self.add_right_rbl):
left_names=["rbl_{0}_{1}".format(self.cell.get_bl_name(x), port) for x in range(len(self.all_ports))]
right_names=["rbl_{0}_{1}".format(self.cell.get_br_name(x), port) for x in range(len(self.all_ports))]
# Keep track of the left pins that are the RBL
self.replica_bl_names[port]=left_names[self.bitcell_ports[port]]
# Interleave the left and right lists
bitline_names = [x for t in zip(left_names, right_names) for x in t]
self.replica_bitline_names[port] = bitline_names
2020-05-28 05:03:11 +02:00
2020-08-12 00:00:29 +02:00
# Dummy bitlines are not connected to anything
self.bitline_names.extend(self.bitcell_array_bitline_names)
for port in self.all_ports:
self.add_pin_list(self.replica_bitline_names[port], "INOUT")
2020-08-12 00:00:29 +02:00
self.add_pin_list(self.bitline_names, "INOUT")
def add_wordline_pins(self):
# All wordline names for all ports
self.wordline_names = []
# Wordline names for each port
self.wordline_names_by_port = [[] for x in self.all_ports]
# Replica wordlines by port
self.replica_wordline_names = [[] for x in self.all_ports]
# Dummy wordlines
self.dummy_wordline_names = {}
# Regular array wordline names
self.bitcell_array_wordline_names = self.bitcell_array.get_all_wordline_names()
# These are the non-indexed names
dummy_cell_wl_names = ["dummy_" + x for x in self.cell.get_all_wl_names()]
# Create the full WL names include dummy, replica, and regular bit cells
2020-08-12 00:00:29 +02:00
self.wordline_names = []
self.dummy_wordline_names["bot"] = ["{0}_bot".format(x) for x in dummy_cell_wl_names]
self.wordline_names.extend(self.dummy_wordline_names["bot"])
# Left port WLs
for port in range(self.left_rbl):
# Make names for all RBLs
wl_names=["rbl_{0}_{1}".format(x, port) for x in self.cell.get_all_wl_names()]
# Keep track of the pin that is the RBL
2020-08-12 00:00:29 +02:00
self.replica_wordline_names[port] = wl_names
self.wordline_names.extend(wl_names)
# Regular WLs
2020-08-12 00:00:29 +02:00
self.wordline_names.extend(self.bitcell_array_wordline_names)
# Right port WLs
for port in range(self.left_rbl, self.left_rbl + self.right_rbl):
# Make names for all RBLs
wl_names=["rbl_{0}_{1}".format(x, port) for x in self.cell.get_all_wl_names()]
# Keep track of the pin that is the RBL
2020-08-12 00:00:29 +02:00
self.replica_wordline_names[port] = wl_names
self.wordline_names.extend(wl_names)
self.dummy_wordline_names["top"] = ["{0}_top".format(x) for x in dummy_cell_wl_names]
self.wordline_names.extend(self.dummy_wordline_names["top"])
2019-07-12 23:39:56 +02:00
# Array of all port wl names
for port in range(self.left_rbl + self.right_rbl):
2020-06-05 22:49:32 +02:00
wl_names = ["rbl_{0}_{1}".format(x, port) for x in self.cell.get_all_wl_names()]
2020-08-12 00:00:29 +02:00
self.replica_wordline_names[port] = wl_names
2019-06-20 01:03:21 +02:00
2020-08-12 00:00:29 +02:00
self.add_pin_list(self.wordline_names, "INPUT")
2019-06-20 01:03:21 +02:00
def create_instances(self):
""" Create the module instances used in this design """
supplies = ["vdd", "gnd"]
2020-05-28 05:03:11 +02:00
# Used for names/dimensions only
self.cell = factory.create(module_type="bitcell")
2020-05-28 05:03:11 +02:00
2019-06-20 01:03:21 +02:00
# Main array
self.bitcell_array_inst=self.add_inst(name="bitcell_array",
mod=self.bitcell_array)
2020-08-12 00:00:29 +02:00
self.connect_inst(self.bitcell_array_bitline_names + self.bitcell_array_wordline_names + supplies)
2019-06-20 01:03:21 +02:00
# Replica columns
self.replica_col_inst = {}
for port in range(self.add_left_rbl + self.add_right_rbl):
2019-07-12 23:39:56 +02:00
self.replica_col_inst[port]=self.add_inst(name="replica_col_{}".format(port),
2020-06-05 22:49:32 +02:00
mod=self.replica_columns[port])
2020-08-12 00:00:29 +02:00
self.connect_inst(self.replica_bitline_names[port] + self.wordline_names + supplies)
2019-07-12 23:39:56 +02:00
# Dummy rows under the bitcell array (connected with with the replica cell wl)
self.dummy_row_replica_inst = {}
# Note, this is the number of left and right even if we aren't adding the columns to this bitcell array!
2020-06-05 22:49:32 +02:00
for port in range(self.left_rbl + self.right_rbl):
2019-07-12 23:39:56 +02:00
self.dummy_row_replica_inst[port]=self.add_inst(name="dummy_row_{}".format(port),
mod=self.dummy_row)
2020-08-12 00:00:29 +02:00
self.connect_inst(self.bitcell_array_bitline_names + self.replica_wordline_names[port] + supplies)
2020-05-28 05:03:11 +02:00
# Top/bottom dummy rows or col caps
self.dummy_row_bot_inst=self.add_inst(name="dummy_row_bot",
2020-08-12 00:00:29 +02:00
mod=self.col_cap)
self.connect_inst(self.bitcell_array_bitline_names
+ self.dummy_wordline_names["bot"]
+ supplies)
self.dummy_row_top_inst=self.add_inst(name="dummy_row_top",
2020-08-12 00:00:29 +02:00
mod=self.col_cap)
self.connect_inst(self.bitcell_array_bitline_names
+ self.dummy_wordline_names["top"]
+ supplies)
2019-06-20 01:03:21 +02:00
# Left/right Dummy columns
2019-06-20 01:03:21 +02:00
self.dummy_col_left_inst=self.add_inst(name="dummy_col_left",
2020-08-12 00:00:29 +02:00
mod=self.row_cap_left)
self.connect_inst(self.dummy_bitline_names[0] + self.wordline_names + supplies)
2019-06-20 01:03:21 +02:00
self.dummy_col_right_inst=self.add_inst(name="dummy_col_right",
2020-08-12 00:00:29 +02:00
mod=self.row_cap_right)
self.connect_inst(self.dummy_bitline_names[-1] + self.wordline_names + supplies)
2019-06-20 01:03:21 +02:00
def create_layout(self):
2020-06-05 22:49:32 +02:00
self.height = (self.row_size + self.extra_rows) * self.dummy_row.height
self.width = (self.column_size + self.extra_cols) * self.cell.width
2019-06-20 01:03:21 +02:00
# This is a bitcell x bitcell offset to scale
self.bitcell_offset = vector(self.cell.width, self.cell.height)
2020-05-28 05:03:11 +02:00
# Everything is computed with the main array at (0, 0) to start
2020-06-05 22:49:32 +02:00
self.bitcell_array_inst.place(offset=[0, 0])
self.add_replica_columns()
self.add_end_caps()
# Array was at (0, 0) but move everything so it is at the lower left
# We move DOWN the number of left RBL even if we didn't add the column to this bitcell array
self.translate_all(self.bitcell_offset.scale(-1 - self.add_left_rbl, -1 - self.left_rbl))
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_replica_columns(self):
""" Add replica columns on left and right of array """
# To the left of the bitcell array
for bit in range(self.add_left_rbl):
self.replica_col_inst[bit].place(offset=self.bitcell_offset.scale(-bit - 1, -self.add_left_rbl - 1))
# To the right of the bitcell array
for bit in range(self.add_right_rbl):
self.replica_col_inst[self.add_left_rbl + bit].place(offset=self.bitcell_offset.scale(bit, -self.add_left_rbl - 1) + self.bitcell_array_inst.lr())
# Replica dummy rows
# Add the dummy rows even if we aren't adding the replica column to this bitcell array
for bit in range(self.left_rbl):
self.dummy_row_replica_inst[bit].place(offset=self.bitcell_offset.scale(0, -bit - bit % 2),
mirror="R0" if bit % 2 else "MX")
for bit in range(self.right_rbl):
self.dummy_row_replica_inst[self.left_rbl + bit].place(offset=self.bitcell_offset.scale(0, bit + bit % 2) + self.bitcell_array_inst.ul(),
mirror="MX" if bit % 2 else "R0")
def add_end_caps(self):
""" Add dummy cells or end caps around the array """
2020-06-05 22:49:32 +02:00
# FIXME: These depend on the array size itself
# Far top dummy row (first row above array is NOT flipped)
2020-06-05 22:49:32 +02:00
flip_dummy = self.right_rbl % 2
dummy_row_offset = self.bitcell_offset.scale(0, self.right_rbl + flip_dummy) + self.bitcell_array_inst.ul()
self.dummy_row_top_inst.place(offset=dummy_row_offset,
mirror="MX" if flip_dummy else "R0")
2020-06-05 22:49:32 +02:00
# FIXME: These depend on the array size itself
# Far bottom dummy row (first row below array IS flipped)
2020-06-05 22:49:32 +02:00
flip_dummy = (self.left_rbl + 1) % 2
dummy_row_offset = self.bitcell_offset.scale(0, -self.left_rbl - 1 + flip_dummy)
self.dummy_row_bot_inst.place(offset=dummy_row_offset,
mirror="MX" if flip_dummy else "R0")
# Far left 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(-self.add_left_rbl - 1, -self.left_rbl - 1)
self.dummy_col_left_inst.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(self.add_right_rbl, -self.left_rbl - 1) + self.bitcell_array_inst.lr()
self.dummy_col_right_inst.place(offset=dummy_col_offset)
2019-06-20 01:03:21 +02:00
def add_layout_pins(self):
""" Add the layout pins """
2020-08-12 00:00:29 +02:00
# All wordlines
2019-06-20 01:03:21 +02:00
# Main array wl and bl/br
pin_names = self.bitcell_array.get_pin_names()
for pin_name in pin_names:
2020-08-12 00:00:29 +02:00
for wl in self.bitcell_array_wordline_names:
if wl in pin_name:
pin_list = self.bitcell_array_inst.get_pins(pin_name)
for pin in pin_list:
self.add_layout_pin(text=pin_name,
2020-08-12 00:00:29 +02:00
layer=pin.layer,
2020-06-05 22:49:32 +02:00
offset=pin.ll().scale(0, 1),
width=self.width,
height=pin.height())
2020-08-12 00:00:29 +02:00
for bitline in self.bitcell_array_bitline_names:
if bitline in pin_name:
pin_list = self.bitcell_array_inst.get_pins(pin_name)
for pin in pin_list:
self.add_layout_pin(text=pin_name,
layer=pin.layer,
2020-06-05 22:49:32 +02:00
offset=pin.ll().scale(1, 0),
width=pin.width(),
height=self.height)
2020-08-12 00:00:29 +02:00
# Dummy wordlines
for (name, inst) in [("bot", self.dummy_row_bot_inst), ("top", self.dummy_row_top_inst)]:
for (pin_name, wl_name) in zip(self.cell.get_all_wl_names(), self.dummy_wordline_names[name]):
# It's always a single row
pin = inst.get_pin(pin_name + "_0")
self.add_layout_pin(text=wl_name,
layer=pin.layer,
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 (port, inst) in list(self.dummy_row_replica_inst.items()):
for (pin_name, wl_name) in zip(self.cell.get_all_wl_names(), self.replica_wordline_names[port]):
pin = inst.get_pin(pin_name + "_0")
self.add_layout_pin(text=wl_name,
layer=pin.layer,
offset=pin.ll().scale(0, 1),
width=self.width,
height=pin.height())
# Replica bitlines
for port in range(self.add_left_rbl + self.add_right_rbl):
2019-07-12 23:39:56 +02:00
inst = self.replica_col_inst[port]
2020-08-12 00:00:29 +02:00
for (pin_name, bl_name) in zip(self.cell.get_all_bitline_names(), self.replica_bitline_names[port]):
pin = inst.get_pin(pin_name)
2020-08-12 00:00:29 +02:00
if bl_name in self.replica_bl_names:
name = bl_name
else:
name = "rbl_{0}_{1}".format(pin_name, port)
self.add_layout_pin(text=name,
layer=pin.layer,
offset=pin.ll().scale(1, 0),
width=pin.width(),
height=self.height)
2020-05-28 05:03:11 +02:00
2020-06-29 19:03:24 +02:00
# vdd/gnd are only connected in the perimeter cells
# replica column should only have a vdd/gnd in the dummy cell on top/bottom
supply_insts = [self.dummy_col_left_inst, self.dummy_col_right_inst,
self.dummy_row_top_inst, self.dummy_row_bot_inst]
for pin_name in ["vdd", "gnd"]:
for inst in supply_insts:
2019-06-20 01:03:21 +02:00
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
self.add_power_pin(name=pin_name,
loc=pin.center(),
directions=("V", "V"),
start_layer=pin.layer)
2020-08-12 00:00:29 +02:00
for inst in list(self.replica_col_inst.values()):
self.copy_layout_pin(inst, pin_name)
2019-07-12 23:39:56 +02:00
def get_rbl_wordline_names(self, port=None):
"""
Return the ACTIVE WL for the given RBL port.
Inactive will be set to gnd.
"""
if port == None:
temp = []
for port in self.all_ports:
temp.extend(self.replica_wordline_names[port])
return temp
else:
wl_names = self.replica_wordline_names[port]
return wl_names[port]
2020-05-28 05:03:11 +02:00
def get_rbl_bitline_names(self, port=None):
""" Return the BL for the given RBL port """
if port == None:
temp = []
for port in self.all_ports:
temp.extend(self.replica_bitline_names[port])
return temp
else:
bl_names = self.replica_bitline_names[port]
return bl_names[2 * port:2 * port + 2]
def get_wordline_names(self):
""" Return the wordline names """
return self.wordline_names
def get_bitline_names(self):
""" Return the bitline names """
return self.bitline_names
2019-06-20 01:03:21 +02:00
def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW."""
# Dynamic Power from Bitline
bl_wire = self.gen_bl_wire()
cell_load = 2 * bl_wire.return_input_cap()
2019-07-25 23:18:08 +02:00
bl_swing = OPTS.rbl_delay_percentage
freq = spice["default_event_frequency"]
2019-06-20 01:03:21 +02:00
bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing)
2020-05-28 05:03:11 +02:00
2020-06-05 22:49:32 +02:00
# Calculate the bitcell power which currently only includes leakage
2019-06-20 01:03:21 +02:00
cell_power = self.cell.analytical_power(corner, load)
2020-05-28 05:03:11 +02:00
2020-06-05 22:49:32 +02:00
# Leakage power grows with entire array and bitlines.
2019-06-20 01:03:21 +02:00
total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size,
cell_power.leakage * self.column_size * self.row_size)
return total_power
def gen_bl_wire(self):
if OPTS.netlist_only:
height = 0
else:
height = self.height
bl_pos = 0
2020-06-05 22:49:32 +02:00
bl_wire = self.generate_rc_net(int(self.row_size - bl_pos), height, drc("minwidth_m1"))
2019-06-20 01:03:21 +02:00
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
return bl_wire
def get_wordline_cin(self):
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
2020-06-05 22:49:32 +02:00
# A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
2019-06-20 01:03:21 +02:00
bitcell_wl_cin = self.cell.get_wl_cin()
total_cin = bitcell_wl_cin * self.column_size
return total_cin
2019-07-12 17:42:36 +02:00
def graph_exclude_bits(self, targ_row, targ_col):
"""Excludes bits in column from being added to graph except target"""
self.bitcell_array.graph_exclude_bits(targ_row, targ_col)
2020-05-28 05:03:11 +02:00
def graph_exclude_replica_col_bits(self):
"""Exclude all replica/dummy cells in the replica columns except the replica bit."""
2020-05-28 05:03:11 +02:00
2020-06-05 22:49:32 +02:00
for port in range(self.left_rbl + self.right_rbl):
self.replica_columns[port].exclude_all_but_replica()
def get_cell_name(self, inst_name, row, col):
"""Gets the spice name of the target bitcell."""
2020-06-05 22:49:32 +02:00
return self.bitcell_array.get_cell_name(inst_name + '.x' + self.bitcell_array_inst.name, row, col)