Fix pbitcell erros

This commit is contained in:
mrg 2020-11-13 15:55:55 -08:00
parent c472a94f1e
commit 8021430122
32 changed files with 236 additions and 500 deletions

View File

@ -5,9 +5,49 @@
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from globals import OPTS
class _cell:
def __init__(self, port_order, port_types, port_map=None, hard_cell=True, boundary_layer="boundary"):
# Specifies if this is a hard (i.e. GDS) cell
self._hard_cell = hard_cell
# Specifies the order in the spice modules
self._port_order = port_order
# Specifies the port directions
self._port_types = port_types
# Specifies a map from OpenRAM names to cell names
# by default it is 1:1
if not port_map:
port_map = {}
for pin in port_order:
port_map[pin] = pin
self._pins = _pins(port_map)
else:
self._pins = _pins(port_map)
self._port_names = [getattr(self._pins, x) for x in self._port_order]
self._boundary_layer = boundary_layer
@property
def pin(self):
return self._pins
@property
def hard_cell(self):
return self._hard_cell
@property
def port_names(self):
return self._port_names
@property
def port_types(self):
return self._port_types
@property
def boundary_layer(self):
return self._boundary_layer
class _pins:
def __init__(self, pin_dict):
# make the pins elements of the class to allow "." access.
@ -16,20 +56,6 @@ class _pins:
self.__dict__[k] = v
class _cell:
def __init__(self, pin_dict):
pin_dict.update(self._default_power_pins())
self._pins = _pins(pin_dict)
@property
def pin(self):
return self._pins
def _default_power_pins(self):
return {'vdd': 'vdd',
'gnd': 'gnd'}
class _mirror_axis:
def __init__(self, x, y):
self.x = x
@ -47,65 +73,38 @@ class _pgate:
self.add_implants = add_implants
class _bitcell:
def __init__(self, mirror, cell_1port, cell_2port):
self.mirror = mirror
self._1rw = cell_1port
self._2rw = cell_2port
class _bitcell(_cell):
def __init__(self, port_order, port_types, port_map=None, storage_nets=["Q", "Q_bar"], mirror=None, end_caps=False):
super().__init__(port_order, port_types, port_map)
def _default():
axis = _mirror_axis(True, False)
cell_1port = _cell({'bl': 'bl',
'br': 'br',
'wl': 'wl'})
cell_2port = _cell({'bl0': 'bl0',
'br0': 'br0',
'bl1': 'bl1',
'br1': 'br1',
'wl0': 'wl0',
'wl1': 'wl1'})
return _bitcell(cell_1port=cell_1port,
cell_2port=cell_2port,
mirror=axis)
self._end_caps = end_caps
if not mirror:
self._mirror = _mirror_axis(True, False)
else:
self._mirror = mirror
self._storage_nets = storage_nets
@property
def cell_1port(self):
return self._1rw
def end_caps(self):
return self._end_caps
@property
def cell_2port(self):
return self._2rw
def mirror(self):
return self._mirror
@property
def storage_nets(self):
return self._storage_nets
class _dff:
def __init__(self, use_custom_ports, custom_port_list, custom_type_list, clk_pin):
self.use_custom_ports = use_custom_ports
self.custom_port_list = custom_port_list
self.custom_type_list = custom_type_list
class _dff(_cell):
def __init__(self, clk_pin, port_order, port_types, port_map=None, hard_cell=True):
super().__init__(port_order, port_types, port_map, hard_cell)
self.clk_pin = clk_pin
class _dff_buff:
def __init__(self, use_custom_ports, custom_buff_ports, add_body_contacts):
self.use_custom_ports = use_custom_ports
self.buf_ports = custom_buff_ports
self.add_body_contacts = add_body_contacts
class _dff_buff_array:
def __init__(self, use_custom_ports, add_body_contacts):
self.use_custom_ports = use_custom_ports
self.add_body_contacts = add_body_contacts
class _bitcell_array:
def __init__(self, use_custom_cell_arrangement):
self.use_custom_cell_arrangement = use_custom_cell_arrangement
class cell_properties():
"""
This contains meta information about the custom designed cells. For
@ -125,41 +124,41 @@ class cell_properties():
self.names["col_cap_bitcell_2port"] = "col_cap_cell_2rw"
self.names["row_cap_bitcell_1port"] = "row_cap_cell_1rw"
self.names["row_cap_bitcell_2port"] = "row_cap_cell_2rw"
self._bitcell = _bitcell._default()
self._ptx = _ptx(model_is_subckt=False,
bin_spice_models=False)
self._pgate = _pgate(add_implants=False)
self._dff = _dff(use_custom_ports=False,
custom_port_list=["D", "Q", "clk", "vdd", "gnd"],
custom_type_list=["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"],
clk_pin="clk")
self._nand2_dec = _cell(["A", "B", "Z", "vdd", "gnd"],
["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
self._nand2_dec = _cell(["A", "B", "C", "Z", "vdd", "gnd"],
["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
self._nand2_dec = _cell(["A", "B", "C", "D", "Z", "vdd", "gnd"],
["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
self._dff = _dff("clk",
["D", "Q", "clk", "vdd", "gnd"],
["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
self._dff_buff = _dff_buff(use_custom_ports=False,
custom_buff_ports=["D", "qint", "clk", "vdd", "gnd"],
add_body_contacts=False)
self._dff_buf = _dff("clk",
["D", "Q", "Qb", "clk", "vdd", "gnd"],
["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"],
hard_cell=False)
self._write_driver = _cell(['din', 'bl', 'br', 'en', 'vdd', 'gnd'],
["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
self._dff_buff_array = _dff_buff_array(use_custom_ports=False,
add_body_contacts=False)
self._sense_amp = _cell(['bl', 'br', 'dout', 'en', 'vdd', 'gnd'],
["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
self._write_driver = _cell({'din': 'din',
'bl': 'bl',
'br': 'br',
'en': 'en'})
self._bitcell_1port = _bitcell(["bl", "br", "wl", "vdd", "gnd"],
["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
self._sense_amp = _cell({'bl': 'bl',
'br': 'br',
'dout': 'dout',
'en': 'en'})
self._bitcell_array = _bitcell_array(use_custom_cell_arrangement=[])
@property
def bitcell(self):
return self._bitcell
self._bitcell_2port = _bitcell(["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"],
["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"])
@property
def ptx(self):
@ -174,13 +173,9 @@ class cell_properties():
return self._dff
@property
def dff_buff(self):
return self._dff_buff
@property
def dff_buff_array(self):
return self._dff_buff_array
def dff_buf(self):
return self._dff_buf
@property
def write_driver(self):
return self._write_driver
@ -190,13 +185,10 @@ class cell_properties():
return self._sense_amp
@property
def bitcell_array(self):
return self._bitcell_array
def bitcell_1port(self):
return self._bitcell_1port
@property
def bitcell_2port(self):
return self._bitcell_2port
def compare_ports(self, port_list):
use_custom_arrangement = False
for ports in port_list:
if ports == "{}R_{}W_{}RW".format(OPTS.num_r_ports, OPTS.num_w_ports, OPTS.num_rw_ports):
use_custom_arrangement = True
break
return use_custom_arrangement

View File

@ -6,8 +6,9 @@
# All rights reserved.
#
from hierarchy_design import hierarchy_design
from utils import round_to_grid
import utils
import contact
from tech import GDS, layer
from tech import preferred_directions
from tech import cell_properties as props
from globals import OPTS
@ -31,6 +32,26 @@ class design(hierarchy_design):
cell_name = name
super().__init__(name, cell_name)
# This means it is a custom cell...
if hasattr(props, name):
prop = getattr(props, name)
if prop.hard_cell:
# The pins get added from the spice file
debug.check(prop.port_names == self.pins,
"Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins))
self.add_pin_types(prop.port_types)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[prop.boundary_layer])
self.pin_map = utils.get_libcell_pins(self.pins,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.setup_multiport_constants()
def check_pins(self):
@ -232,8 +253,7 @@ class design(hierarchy_design):
#print(contact1)
pitch = contact_width + layer_space
return round_to_grid(pitch)
return utils.round_to_grid(pitch)
def setup_multiport_constants(self):
"""

View File

@ -78,6 +78,7 @@ class spice():
""" Adds a pin_list to the pins list """
# The type list can be a single type for all pins
# or a list that is the same length as the pin list.
if type(pin_type)==str:
for pin in pin_list:
debug.check(pin_type in self.valid_signal_types,
@ -100,12 +101,12 @@ class spice():
Typically, should only be used for handmade cells.
"""
# This only works if self.pins == bitcell.pin_names
if self.pin_names != self.pins:
debug.error("{} spice subcircuit port names do not match pin_names\
if len(type_list) != len(self.pins):
debug.error("{} spice subcircuit number of port types does not match number of pins\
\n SPICE names={}\
\n Module names={}\
".format(self.name, self.pins, self.pin_names), 1)
self.pin_type = {pin: type for pin, type in zip(self.pin_names, type_list)}
".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. """

View File

@ -18,53 +18,43 @@ class bitcell_1port(bitcell_base.bitcell_base):
library.
"""
pin_names = [props.bitcell.cell_1port.pin.bl,
props.bitcell.cell_1port.pin.br,
props.bitcell.cell_1port.pin.wl,
props.bitcell.cell_1port.pin.vdd,
props.bitcell.cell_1port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
storage_nets = ['Q', 'Q_bar']
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcell_1port)
debug.info(2, "Create bitcell")
self.nets_match = self.do_nets_exist(self.storage_nets)
def get_all_wl_names(self):
""" Creates a list of all wordline pin names """
row_pins = [props.bitcell.cell_1port.pin.wl]
row_pins = [props.bitcell_1port.pin.wl]
return row_pins
def get_all_bitline_names(self):
""" Creates a list of all bitline pin names (both bl and br) """
pin = props.bitcell.cell_1port.pin
pin = props.bitcell_1port.pin
column_pins = [pin.bl, pin.br]
return column_pins
def get_all_bl_names(self):
""" Creates a list of all bl pins names """
return [props.bitcell.cell_1port.pin.bl]
return [props.bitcell_1port.pin.bl]
def get_all_br_names(self):
""" Creates a list of all br pins names """
return [props.bitcell.cell_1port.pin.br]
return [props.bitcell_1port.pin.br]
def get_bl_name(self, port=0):
"""Get bl name"""
debug.check(port == 0, "One port for bitcell only.")
return props.bitcell.cell_1port.pin.bl
return props.bitcell_1port.pin.bl
def get_br_name(self, port=0):
"""Get bl name"""
debug.check(port == 0, "One port for bitcell only.")
return props.bitcell.cell_1port.pin.br
return props.bitcell_1port.pin.br
def get_wl_name(self, port=0):
"""Get wl name"""
debug.check(port == 0, "One port for bitcell only.")
return props.bitcell.cell_1port.pin.wl
return props.bitcell_1port.pin.wl
def build_graph(self, graph, inst_name, port_nets):
"""

View File

@ -18,35 +18,20 @@ class bitcell_2port(bitcell_base.bitcell_base):
library.
"""
pin_names = [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.bl1,
props.bitcell.cell_2port.pin.br1,
props.bitcell.cell_2port.pin.wl0,
props.bitcell.cell_2port.pin.wl1,
props.bitcell.cell_2port.pin.vdd,
props.bitcell.cell_2port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT",
"INPUT", "INPUT", "POWER", "GROUND"]
storage_nets = ['Q', 'Q_bar']
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcell_2port)
debug.info(2, "Create bitcell with 2 ports")
self.nets_match = self.do_nets_exist(self.storage_nets)
pin_names = self.pin_names
self.bl_names = [pin_names[0], pin_names[2]]
self.br_names = [pin_names[1], pin_names[3]]
self.wl_names = [pin_names[4], pin_names[5]]
self.bl_names = [props.bitcell_2port.pin.bl0, props.bitcell_2port.pin.bl1]
self.br_names = [props.bitcell_2port.pin.br0, props.bitcell_2port.pin.br1]
self.wl_names = [props.bitcell_2port.pin.wl0, props.bitcell_2port.pin.wl1]
def get_bitcell_pins(self, col, row):
"""
Creates a list of connections in the bitcell,
indexed by column and row, for instance use in bitcell_array
"""
pin_name = props.bitcell.cell_2port.pin
pin_name = props.bitcell_2port.pin
bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col),
"{0}_{1}".format(pin_name.br0, col),
"{0}_{1}".format(pin_name.bl1, col),
@ -59,43 +44,43 @@ class bitcell_2port(bitcell_base.bitcell_base):
def get_all_wl_names(self):
""" Creates a list of all wordline pin names """
return [props.bitcell.cell_2port.pin.wl0,
props.bitcell.cell_2port.pin.wl1]
return [props.bitcell_2port.pin.wl0,
props.bitcell_2port.pin.wl1]
def get_all_bitline_names(self):
""" Creates a list of all bitline pin names (both bl and br) """
return [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.bl1,
props.bitcell.cell_2port.pin.br1]
return [props.bitcell_2port.pin.bl0,
props.bitcell_2port.pin.br0,
props.bitcell_2port.pin.bl1,
props.bitcell_2port.pin.br1]
def get_all_bl_names(self):
""" Creates a list of all bl pins names """
return [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.bl1]
return [props.bitcell_2port.pin.bl0,
props.bitcell_2port.pin.bl1]
def get_all_br_names(self):
""" Creates a list of all br pins names """
return [props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.br1]
return [props.bitcell_2port.pin.br0,
props.bitcell_2port.pin.br1]
def get_read_bl_names(self):
""" Creates a list of bl pin names associated with read ports """
return [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.bl1]
return [props.bitcell_2port.pin.bl0,
props.bitcell_2port.pin.bl1]
def get_read_br_names(self):
""" Creates a list of br pin names associated with read ports """
return [props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.br1]
return [props.bitcell_2port.pin.br0,
props.bitcell_2port.pin.br1]
def get_write_bl_names(self):
""" Creates a list of bl pin names associated with write ports """
return [props.bitcell.cell_2port.pin.bl0]
return [props.bitcell_2port.pin.bl0]
def get_write_br_names(self):
""" Creates a list of br pin names asscociated with write ports"""
return [props.bitcell.cell_2port.pin.br1]
return [props.bitcell_2port.pin.br1]
def get_bl_name(self, port=0):
"""Get bl name by port"""
@ -118,7 +103,7 @@ class bitcell_2port(bitcell_base.bitcell_base):
pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
# Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
pins = props.bitcell.cell_2port.pin
pins = props.bitcell_2port.pin
graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.bl0], self)
graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.br0], self)
# Port 1 edges

View File

@ -18,19 +18,22 @@ class bitcell_base(design.design):
"""
Base bitcell parameters to be over-riden.
"""
cell_size_layer = "boundary"
def __init__(self, name, hard_cell=True):
def __init__(self, name, prop=None):
design.design.__init__(self, name)
if hard_cell:
if prop:
self.pins = prop.port_names
self.add_pin_types(prop.port_types)
self.nets_match = self.do_nets_exist(prop.storage_nets)
self.mirror = prop.mirror
self.end_caps = prop.end_caps
(self.width, self.height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
self.pin_map = utils.get_libcell_pins(self.pin_names,
layer[prop.boundary_layer])
self.pin_map = utils.get_libcell_pins(self.pins,
self.cell_name,
GDS["unit"])
self.add_pin_types(self.type_list)
def get_stage_effort(self, load):
parasitic_delay = 1

View File

@ -17,15 +17,8 @@ class dummy_bitcell_1port(bitcell_base.bitcell_base):
the layout and netlist should be available in the technology
library.
"""
pin_names = [props.bitcell.cell_1port.pin.bl,
props.bitcell.cell_1port.pin.br,
props.bitcell.cell_1port.pin.wl,
props.bitcell.cell_1port.pin.vdd,
props.bitcell.cell_1port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcell_1port)
debug.info(2, "Create dummy bitcell")

View File

@ -17,19 +17,8 @@ class dummy_bitcell_2port(bitcell_base.bitcell_base):
is a hand-made cell, so the layout and netlist should be available in
the technology library. """
pin_names = [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.bl1,
props.bitcell.cell_2port.pin.br1,
props.bitcell.cell_2port.pin.wl0,
props.bitcell.cell_2port.pin.wl1,
props.bitcell.cell_2port.pin.vdd,
props.bitcell.cell_2port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT",
"INPUT", "INPUT", "POWER", "GROUND"]
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcel_2port)
debug.info(2, "Create dummy bitcell 2 port object")

View File

@ -8,6 +8,7 @@
import contact
import debug
from tech import drc, parameter, layer
from tech import cell_properties as props
from vector import vector
from ptx import ptx
from globals import OPTS
@ -29,8 +30,9 @@ class pbitcell(bitcell_base.bitcell_base):
self.replica_bitcell = replica_bitcell
self.dummy_bitcell = dummy_bitcell
self.mirror = props.bitcell_1port.mirror
bitcell_base.bitcell_base.__init__(self, name, hard_cell=False)
bitcell_base.bitcell_base.__init__(self, name)
fmt_str = "{0} rw ports, {1} w ports and {2} r ports"
info_string = fmt_str.format(self.num_rw_ports,
self.num_w_ports,

View File

@ -19,15 +19,8 @@ class replica_bitcell_1port(bitcell_base.bitcell_base):
is a hand-made cell, so the layout and netlist should be available in
the technology library. """
pin_names = [props.bitcell.cell_1port.pin.bl,
props.bitcell.cell_1port.pin.br,
props.bitcell.cell_1port.pin.wl,
props.bitcell.cell_1port.pin.vdd,
props.bitcell.cell_1port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcell_1port)
debug.info(2, "Create replica bitcell object")
def get_stage_effort(self, load):

View File

@ -19,18 +19,8 @@ class replica_bitcell_2port(bitcell_base.bitcell_base):
is a hand-made cell, so the layout and netlist should be available in
the technology library. """
pin_names = [props.bitcell.cell_2port.pin.bl0,
props.bitcell.cell_2port.pin.br0,
props.bitcell.cell_2port.pin.bl1,
props.bitcell.cell_2port.pin.br1,
props.bitcell.cell_2port.pin.wl0,
props.bitcell.cell_2port.pin.wl1,
props.bitcell.cell_2port.pin.vdd,
props.bitcell.cell_2port.pin.gnd]
type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"]
def __init__(self, name):
super().__init__(name)
super().__init__(name, props.bitcell_2port)
debug.info(2, "Create replica bitcell 2 port object")
def get_stage_effort(self, load):

View File

@ -6,40 +6,19 @@
# All rights reserved.
#
import design
from tech import GDS, layer, spice
from tech import spice
from tech import cell_properties as props
import utils
class dff(design.design):
"""
Memory address flip-flop
"""
if not props.dff.use_custom_ports:
pin_names = ["D", "Q", "clk", "vdd", "gnd"]
type_list = ["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
clk_pin = "clk"
else:
pin_names = props.dff.custom_port_list
type_list = props.dff.custom_type_list
clk_pin = props.dff.clk_pin
cell_size_layer = "boundary"
def __init__(self, name="dff"):
super().__init__(name)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
self.clk_pin = props.dff.clk_pin
def analytical_power(self, corner, load):
"""Returns dynamic and leakage power. Results in nW"""
@ -54,9 +33,9 @@ class dff(design.design):
def calculate_effective_capacitance(self, load):
"""Computes effective capacitance. Results in fF"""
c_load = load
c_para = spice["dff_out_cap"]#ff
c_para = spice["dff_out_cap"] # ff
transition_prob = 0.5
return transition_prob*(c_load + c_para)
return transition_prob * (c_load + c_para)
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges based on inputs/outputs. Overrides base class function."""

View File

@ -6,9 +6,8 @@
# All rights reserved.
#
import design
from tech import GDS, layer, spice, parameter
import logical_effort
import utils
from tech import spice, parameter
class inv_dec(design.design):
@ -16,26 +15,9 @@ class inv_dec(design.design):
INV for address decoders.
"""
pin_names = ["A", "Z", "vdd", "gnd"]
type_list = ["INPUT", "OUTPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name="inv_dec", height=None):
super().__init__(name)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
def analytical_power(self, corner, load):
"""Returns dynamic and leakage power. Results in nW"""
c_eff = self.calculate_effective_capacitance(load)
@ -52,7 +34,7 @@ class inv_dec(design.design):
# In fF
c_para = spice["min_tx_drain_c"] * (self.nmos_size / parameter["min_tx_size"])
return transition_prob * (c_load + c_para)
return 0.5 * (c_load + c_para)
def input_load(self):
"""

View File

@ -6,9 +6,8 @@
# All rights reserved.
#
import design
from tech import GDS, layer, spice, parameter, drc
from tech import spice, parameter, drc
import logical_effort
import utils
class nand2_dec(design.design):
@ -16,26 +15,9 @@ class nand2_dec(design.design):
2-input NAND decoder for address decoders.
"""
pin_names = ["A", "B", "Z", "vdd", "gnd"]
type_list = ["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name="nand2_dec", height=None):
super().__init__(name)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
# FIXME: For now...
size = 1
self.size = size

View File

@ -6,9 +6,8 @@
# All rights reserved.
#
import design
from tech import GDS, layer, spice, parameter, drc
from tech import spice, parameter, drc
import logical_effort
import utils
class nand3_dec(design.design):
@ -16,26 +15,9 @@ class nand3_dec(design.design):
3-input NAND decoder for address decoders.
"""
pin_names = ["A", "B", "C", "Z", "vdd", "gnd"]
type_list = ["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name="nand3_dec", height=None):
super().__init__(name)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
# FIXME: For now...
size = 1
self.size = size

View File

@ -6,36 +6,18 @@
# All rights reserved.
#
import design
from tech import GDS, layer, spice, parameter, drc
from tech import spice, parameter, drc
import logical_effort
import utils
class nand4_dec(design.design):
"""
2-input NAND decoder for address decoders.
4-input NAND decoder for address decoders.
"""
pin_names = ["A", "B", "C", "D", "Z", "vdd", "gnd"]
type_list = ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name="nand4_dec", height=None):
super().__init__(name)
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
# FIXME: For now...
size = 1
self.size = size

View File

@ -7,8 +7,7 @@
#
import design
import debug
import utils
from tech import GDS, layer, parameter, drc
from tech import parameter, drc
from tech import cell_properties as props
import logical_effort
@ -20,32 +19,11 @@ class sense_amp(design.design):
the technology library.
Sense amplifier to read a pair of bit-lines.
"""
pin_names = [props.sense_amp.pin.bl,
props.sense_amp.pin.br,
props.sense_amp.pin.dout,
props.sense_amp.pin.en,
props.sense_amp.pin.vdd,
props.sense_amp.pin.gnd]
type_list = ["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name="sense_amp"):
super().__init__(name)
debug.info(2, "Create sense_amp")
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
def get_bl_names(self):
return props.sense_amp.pin.bl

View File

@ -7,8 +7,7 @@
#
import debug
import design
import utils
from tech import GDS, layer
from tech import spice
class tri_gate(design.design):
@ -18,10 +17,6 @@ class tri_gate(design.design):
netlist should be available in the technology library.
"""
pin_names = ["in", "out", "en", "en_bar", "vdd", "gnd"]
type_list = ["INPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
unique_id = 1
def __init__(self, name=""):
@ -31,19 +26,6 @@ class tri_gate(design.design):
super().__init__(self, name)
debug.info(2, "Create tri_gate")
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
def analytical_power(self, corner, load):
"""Returns dynamic and leakage power. Results in nW"""
#Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
@ -51,7 +33,7 @@ class tri_gate(design.design):
return total_power
def get_cin(self):
return 9*spice["min_tx_gate_c"]
return 9 * spice["min_tx_gate_c"]
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges based on inputs/outputs. Overrides base class function."""

View File

@ -7,8 +7,6 @@
#
import debug
import design
import utils
from tech import GDS, layer
from tech import cell_properties as props
@ -20,33 +18,10 @@ class write_driver(design.design):
the technology library.
"""
pin_names = [props.write_driver.pin.din,
props.write_driver.pin.bl,
props.write_driver.pin.br,
props.write_driver.pin.en,
props.write_driver.pin.vdd,
props.write_driver.pin.gnd]
type_list = ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
cell_size_layer = "boundary"
def __init__(self, name):
super().__init__(name)
debug.info(2, "Create write_driver")
(width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"],
layer[self.cell_size_layer])
pin_map = utils.get_libcell_pins(self.pin_names,
self.cell_name,
GDS["unit"])
self.width = width
self.height = height
self.pin_map = pin_map
self.add_pin_types(self.type_list)
def get_bl_names(self):
return props.write_driver.pin.bl
@ -64,7 +39,7 @@ class write_driver(design.design):
def get_w_en_cin(self):
"""Get the relative capacitance of a single input"""
# This is approximated from SCMOS. It has roughly 5 3x transistor gates.
return 5*3
return 5 * 3
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges based on inputs/outputs. Overrides base class function."""

View File

@ -7,7 +7,6 @@
#
import debug
import design
from tech import cell_properties
from sram_factory import factory
from globals import OPTS
@ -174,7 +173,7 @@ class bitcell_base_array(design.design):
tempx = xoffset
dir_y = False
# If we mirror the current cell on the y axis adjust the x position
if cell_properties.bitcell.mirror.y and (col + col_offset) % 2:
if self.cell.mirror.y and (col + col_offset) % 2:
tempx = xoffset + self.cell.width
dir_y = True
return (tempx, dir_y)
@ -183,7 +182,7 @@ class bitcell_base_array(design.design):
tempy = yoffset
dir_x = False
# If we mirror the current cell on the x axis adjust the y position
if cell_properties.bitcell.mirror.x and (row + row_offset) % 2:
if self.cell.mirror.x and (row + row_offset) % 2:
tempy = yoffset + self.cell.height
dir_x = True
return (tempy, dir_x)

View File

@ -26,12 +26,9 @@ class col_cap_array(bitcell_base_array):
def create_netlist(self):
""" Create and connect the netlist """
# This will create a default set of bitline/wordline names
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
self.cell = factory.create(module_type=OPTS.bitcell)
if not end_caps_enabled:
if not self.cell.end_caps:
self.create_all_wordline_names()
self.create_all_bitline_names()
@ -51,8 +48,6 @@ class col_cap_array(bitcell_base_array):
self.dummy_cell = factory.create(module_type="col_cap_{}".format(OPTS.bitcell))
self.add_mod(self.dummy_cell)
self.cell = factory.create(module_type=OPTS.bitcell)
def create_instances(self):
""" Create the module instances used in this design """
self.cell_inst = {}

View File

@ -662,9 +662,6 @@ class control_logic(design.design):
self.ctrl_dff_inst=self.add_inst(name="ctrl_dffs",
mod=self.ctrl_dff_array)
inst_pins = self.input_list + self.dff_output_list + ["clk_buf"] + self.supply_list
if props.dff_buff_array.add_body_contacts:
inst_pins.append("vpb")
inst_pins.append("vnb")
self.connect_inst(inst_pins)
def place_dffs(self):

View File

@ -70,7 +70,7 @@ class dff_array(design.design):
mod=self.dff)
instance_ports = [self.get_din_name(row, col),
self.get_dout_name(row, col)]
for port in self.dff.pin_names:
for port in self.dff.pins:
if port != 'D' and port != 'Q':
instance_ports.append(port)
self.connect_inst(instance_ports)

View File

@ -72,30 +72,22 @@ class dff_buf(design.design):
self.add_mod(self.inv2)
def add_pins(self):
self.add_pin("D", "INPUT")
self.add_pin("Q", "OUTPUT")
self.add_pin("Qb", "OUTPUT")
self.add_pin("clk", "INPUT")
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
if props.dff_buff.add_body_contacts:
self.add_pin("vpb", "INPUT")
self.add_pin("vpn", "INPUT")
self.add_pin_list(props.dff_buf.port_names,
props.dff_buf.port_types)
def create_instances(self):
self.dff_inst=self.add_inst(name="dff_buf_dff",
mod=self.dff)
self.connect_inst(["D", "qint", "clk", "vdd", "gnd"])
self.connect_inst([props.dff_buf.pin.D, "qint", props.dff_buf.pin.clk, props.dff_buf.pin.vdd, props.dff_buf.pin.gnd])
self.inv1_inst=self.add_inst(name="dff_buf_inv1",
mod=self.inv1)
self.connect_inst(["qint", "Qb", "vdd", "gnd"])
self.connect_inst(["qint", "Qb", props.dff_buf.pin.vdd, props.dff_buf.pin.gnd])
self.inv2_inst=self.add_inst(name="dff_buf_inv2",
mod=self.inv2)
self.connect_inst(["Qb", "Q", "vdd", "gnd"])
self.connect_inst(["Qb", props.dff_buf.pin.Q, props.dff_buf.pin.vdd, props.dff_buf.pin.gnd])
def place_instances(self):
# Add the DFF
@ -129,7 +121,7 @@ class dff_buf(design.design):
self.route_layer = "m1"
# Route dff q to inv1 a
q_pin = self.dff_inst.get_pin("Q")
q_pin = self.dff_inst.get_pin(props.dff.pin.Q)
a1_pin = self.inv1_inst.get_pin("A")
mid1 = vector(a1_pin.cx(), q_pin.cy())
self.add_path(q_pin.layer, [q_pin.center(), mid1, a1_pin.center()], width=q_pin.height())
@ -146,30 +138,30 @@ class dff_buf(design.design):
def add_layout_pins(self):
# Continous vdd rail along with label.
vdd_pin=self.dff_inst.get_pin("vdd")
self.add_layout_pin(text="vdd",
vdd_pin=self.dff_inst.get_pin(props.dff.pin.vdd)
self.add_layout_pin(text=props.dff_buf.pin.vdd,
layer=vdd_pin.layer,
offset=vdd_pin.ll(),
width=self.width,
height=vdd_pin.height())
# Continous gnd rail along with label.
gnd_pin=self.dff_inst.get_pin("gnd")
self.add_layout_pin(text="gnd",
gnd_pin=self.dff_inst.get_pin(props.dff.pin.gnd)
self.add_layout_pin(text=props.dff_buf.pin.gnd,
layer=gnd_pin.layer,
offset=gnd_pin.ll(),
width=self.width,
height=vdd_pin.height())
clk_pin = self.dff_inst.get_pin("clk")
self.add_layout_pin(text="clk",
clk_pin = self.dff_inst.get_pin(props.dff.pin.clk)
self.add_layout_pin(text=props.dff_buf.pin.clk,
layer=clk_pin.layer,
offset=clk_pin.ll(),
width=clk_pin.width(),
height=clk_pin.height())
din_pin = self.dff_inst.get_pin("D")
self.add_layout_pin(text="D",
din_pin = self.dff_inst.get_pin(props.dff_buf.pin.D)
self.add_layout_pin(text=props.dff_buf.pin.D,
layer=din_pin.layer,
offset=din_pin.ll(),
width=din_pin.width(),
@ -178,7 +170,7 @@ class dff_buf(design.design):
dout_pin = self.inv2_inst.get_pin("Z")
mid_pos = dout_pin.center() + vector(self.m2_nonpref_pitch, 0)
q_pos = mid_pos - vector(0, 2 * self.m2_nonpref_pitch)
self.add_layout_pin_rect_center(text="Q",
self.add_layout_pin_rect_center(text=props.dff_buf.pin.Q,
layer="m2",
offset=q_pos)
self.add_path(self.route_layer, [dout_pin.center(), mid_pos, q_pos])

View File

@ -65,10 +65,6 @@ class dff_buf_array(design.design):
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
if props.dff_buff_array.add_body_contacts:
self.add_pin("vpb", "INPUT")
self.add_pin("vnb", "INPUT")
def add_modules(self):
self.dff = factory.create(module_type="dff_buf",
inv1_size=self.inv1_size,
@ -88,9 +84,6 @@ class dff_buf_array(design.design):
"clk",
"vdd",
"gnd"]
if props.dff_buff_array.add_body_contacts:
inst_ports.append("vpb")
inst_ports.append("vnb")
self.connect_inst(inst_ports)
def place_dff_array(self):
@ -155,7 +148,7 @@ class dff_buf_array(design.design):
def route_supplies(self):
for row in range(self.rows):
vdd0_pin=self.dff_insts[row, 0].get_pin("vdd")
vdd0_pin=self.dff_insts[row, 0].get_pin(props.dff.pin.vdd)
vddn_pin=self.dff_insts[row, self.columns - 1].get_pin("vdd")
self.add_path(vdd0_pin.layer, [vdd0_pin.lc(), vddn_pin.rc()], width=vdd0_pin.height())

View File

@ -10,7 +10,6 @@ import debug
from vector import vector
from sram_factory import factory
from globals import OPTS
from tech import cell_properties
class precharge_array(design.design):
@ -79,6 +78,8 @@ class precharge_array(design.design):
bitcell_br=self.bitcell_br)
self.add_mod(self.pc_cell)
self.cell = factory.create(module_type=OPTS.bitcell)
def add_layout_pins(self):
en_pin = self.pc_cell.get_pin("en_bar")
@ -120,7 +121,7 @@ class precharge_array(design.design):
self.offsets = [n * self.pc_cell.width for n in range(self.columns)]
for i, xoffset in enumerate(self.offsets):
if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2:
if self.cell.mirror.y and (i + self.column_offset) % 2:
mirror = "MY"
tempx = xoffset + self.pc_cell.width
else:

View File

@ -63,13 +63,8 @@ class replica_bitcell_array(bitcell_base_array):
# Two dummy cols plus replica if we add the column
self.extra_cols = len(self.left_rbl) + len(self.right_rbl)
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# If we aren't using row/col caps, then we need to use the bitcell
if not end_caps_enabled:
if not self.cell.end_caps:
self.extra_rows += 2
self.extra_cols += 2
@ -144,10 +139,6 @@ class replica_bitcell_array(bitcell_base_array):
column_offset=column_offset,
replica_bit=replica_bit)
self.add_mod(self.replica_columns[port])
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# Dummy row
self.dummy_row = factory.create(module_type="dummy_array",
@ -159,7 +150,7 @@ class replica_bitcell_array(bitcell_base_array):
self.add_mod(self.dummy_row)
# Dummy Row or Col Cap, depending on bitcell array properties
col_cap_module_type = ("col_cap_array" if end_caps_enabled else "dummy_array")
col_cap_module_type = ("col_cap_array" if self.cell.end_caps else "dummy_array")
self.col_cap_top = factory.create(module_type=col_cap_module_type,
cols=self.column_size,
rows=1,
@ -179,7 +170,7 @@ class replica_bitcell_array(bitcell_base_array):
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 end_caps_enabled else "dummy_array")
row_cap_module_type = ("row_cap_array" if self.cell.end_caps else "dummy_array")
self.row_cap_left = factory.create(module_type=row_cap_module_type,
cols=1,
@ -240,11 +231,6 @@ class replica_bitcell_array(bitcell_base_array):
self.add_pin_list(self.rbl_bitline_names[port], "INOUT")
def add_wordline_pins(self):
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# Wordlines to ground
self.gnd_wordline_names = []
@ -385,14 +371,10 @@ class replica_bitcell_array(bitcell_base_array):
def add_replica_columns(self):
""" Add replica columns on left and right of array """
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# Grow from left to right, toward the array
for bit, port in enumerate(self.left_rbl):
if not end_caps_enabled:
if not self.cell.end_caps:
offset = self.bitcell_offset.scale(-len(self.left_rbl) + bit, -self.rbl[0] - 1) + self.strap_offset.scale(-len(self.left_rbl) + bit, 0) + self.unused_offset
else:
offset = self.bitcell_offset.scale(-len(self.left_rbl) + bit, -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.strap_offset.scale(-len(self.left_rbl) + bit, 0) + self.unused_offset
@ -400,7 +382,7 @@ class replica_bitcell_array(bitcell_base_array):
self.replica_col_insts[bit].place(offset)
# Grow to the right of the bitcell array, array outward
for bit, port in enumerate(self.right_rbl):
if not end_caps_enabled:
if not self.cell.end_caps:
offset = self.bitcell_array_inst.lr() + self.bitcell_offset.scale(bit, -self.rbl[0] - 1) + self.strap_offset.scale(bit, -self.rbl[0] - 1)
else:
offset = self.bitcell_array_inst.lr() + self.bitcell_offset.scale(bit, -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.strap_offset.scale(bit, -self.rbl[0] - 1)
@ -422,15 +404,11 @@ class replica_bitcell_array(bitcell_base_array):
def add_end_caps(self):
""" Add dummy cells or end caps around the array """
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
# FIXME: These depend on the array size itself
# Far top dummy row (first row above array is NOT flipped)
flip_dummy = self.rbl[1] % 2
if not end_caps_enabled:
if not self.cell.end_caps:
dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul()
else:
dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul()
@ -440,7 +418,7 @@ class replica_bitcell_array(bitcell_base_array):
# FIXME: These depend on the array size itself
# Far bottom dummy row (first row below array IS flipped)
flip_dummy = (self.rbl[0] + 1) % 2
if not end_caps_enabled:
if not self.cell.end_caps:
dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - 1 + flip_dummy) + self.unused_offset
else:
dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - (self.col_end_offset.y/self.cell.height) + flip_dummy) + self.unused_offset
@ -448,7 +426,7 @@ class replica_bitcell_array(bitcell_base_array):
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
if not end_caps_enabled:
if not self.cell.end_caps:
dummy_col_offset = self.bitcell_offset.scale(-len(self.left_rbl) - 1, -self.rbl[0] - 1) + self.unused_offset
else:
dummy_col_offset = self.bitcell_offset.scale(-(len(self.left_rbl)*(1+self.strap_offset.x/self.cell.width)) - (self.row_end_offset.x/self.cell.width), -len(self.left_rbl) - (self.col_end_offset.y/self.cell.height))
@ -456,7 +434,7 @@ class replica_bitcell_array(bitcell_base_array):
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
if not end_caps_enabled:
if not self.cell.end_caps:
dummy_col_offset = self.bitcell_offset.scale(len(self.right_rbl), -self.rbl[0] - 1) + self.bitcell_array_inst.lr()
else:
dummy_col_offset = self.bitcell_offset.scale(len(self.right_rbl)*(1+self.strap_offset.x/self.cell.width), -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.bitcell_array_inst.lr()

View File

@ -5,7 +5,7 @@
#
import debug
from bitcell_base_array import bitcell_base_array
from tech import cell_properties
from tech import cell_properties as props
from sram_factory import factory
from vector import vector
from globals import OPTS
@ -30,11 +30,9 @@ class replica_column(bitcell_base_array):
self.replica_bit = replica_bit
# left, right, regular rows plus top/bottom dummy cells
self.total_size = self.left_rbl + rows + self.right_rbl
try:
if not cell_properties.bitcell.end_caps:
self.total_size += 2
except AttributeError:
self.total_size += 2
# For end caps
self.total_size += 2
self.column_offset = column_offset
@ -82,20 +80,17 @@ class replica_column(bitcell_base_array):
self.dummy_cell = factory.create(module_type=OPTS.dummy_bitcell)
self.add_mod(self.dummy_cell)
try:
edge_module_type = ("col_cap" if cell_properties.bitcell.end_caps else "dummy")
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)
# Used for pin names only
self.cell = factory.create(module_type=OPTS.bitcell)
def create_instances(self):
self.cell_inst = {}
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
for row in range(self.total_size):
name="rbc_{0}".format(row)
@ -113,7 +108,7 @@ class replica_column(bitcell_base_array):
elif (row == 0 or row == self.total_size - 1):
self.cell_inst[row]=self.add_inst(name=name,
mod=self.edge_cell)
if end_caps_enabled:
if self.cell.end_caps:
self.connect_inst(self.get_bitcell_pins_col_cap(row, 0))
else:
self.connect_inst(self.get_bitcell_pins(row, 0))
@ -131,13 +126,13 @@ class replica_column(bitcell_base_array):
# column that needs to be flipped.
dir_y = False
xoffset = 0
if cell_properties.bitcell.mirror.y and self.column_offset % 2:
if self.replica_cell.mirror.y and self.column_offset % 2:
dir_y = True
xoffset = self.replica_cell.width
for row in range(self.total_size):
# name = "bit_r{0}_{1}".format(row, "rbl")
dir_x = cell_properties.bitcell.mirror.x and (row + rbl_offset) % 2
dir_x = self.replica_cell.mirror.x and (row + rbl_offset) % 2
offset = vector(xoffset, self.cell.height * (row + (row + rbl_offset) % 2))
@ -169,12 +164,7 @@ class replica_column(bitcell_base_array):
width=bl_pin.width(),
height=self.height)
try:
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
end_caps_enabled = False
if end_caps_enabled:
if self.cell.end_caps:
row_range_max = self.total_size - 1
row_range_min = 1
else:

View File

@ -10,7 +10,6 @@ from vector import vector
from sram_factory import factory
import debug
from globals import OPTS
from tech import cell_properties
class sense_amp_array(design.design):
@ -92,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,
@ -122,7 +120,7 @@ class sense_amp_array(design.design):
self.offsets.append(i * self.bitcell.width)
for i, xoffset in enumerate(self.offsets[0:self.num_cols:self.words_per_row]):
if cell_properties.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2:
if self.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2:
mirror = "MY"
xoffset = xoffset + self.amp_spacing
else:
@ -134,7 +132,7 @@ class sense_amp_array(design.design):
# place spare sense amps (will share the same enable as regular sense amps)
for i, xoffset in enumerate(self.offsets[self.num_cols:]):
index = self.word_size + i
if cell_properties.bitcell.mirror.y and (index + self.column_offset) % 2:
if self.bitcell.mirror.y and (index + self.column_offset) % 2:
mirror = "MY"
xoffset = xoffset + self.amp_width
else:

View File

@ -12,7 +12,6 @@ from tech import drc
from sram_factory import factory
from vector import vector
from globals import OPTS
from tech import cell_properties
class write_driver_array(design.design):
@ -161,7 +160,7 @@ class write_driver_array(design.design):
self.offsets.append(i * self.driver_spacing)
for i, xoffset in enumerate(self.offsets[0:self.columns:self.words_per_row]):
if cell_properties.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2:
if self.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2:
mirror = "MY"
xoffset = xoffset + self.driver.width
else:
@ -174,7 +173,7 @@ class write_driver_array(design.design):
for i, xoffset in enumerate(self.offsets[self.columns:]):
index = self.word_size + i
if cell_properties.bitcell.mirror.y and (index + self.column_offset) % 2:
if self.bitcell.mirror.y and (index + self.column_offset) % 2:
mirror = "MY"
xoffset = xoffset + self.driver.width
else:

View File

@ -31,11 +31,8 @@ tech_modules = module_type()
# Custom cell properties
###################################################
cell_properties = cell_properties()
cell_properties.bitcell.mirror.x = True
cell_properties.bitcell.mirror.y = False
cell_properties.bitcell_power_pin_directions = ("V", "V")
###################################################
# Custom cell properties
###################################################

View File

@ -30,9 +30,6 @@ tech_modules = module_type()
# Custom cell properties
###################################################
cell_properties = cell_properties()
cell_properties.bitcell.mirror.x = True
cell_properties.bitcell.mirror.y = False
###################################################
# Custom cell properties