Replica bitcell array working

This commit is contained in:
mrg 2019-06-19 16:03:21 -07:00
parent 5c4df2410e
commit 4523a7b9f6
18 changed files with 931 additions and 477 deletions

View File

@ -214,7 +214,13 @@ class layout():
return self.pin_map[text]
else:
return set()
def get_pin_names(self):
"""
Return a pin list of all pins
"""
return self.pin_map.keys()
def copy_layout_pin(self, instance, pin_name, new_name=""):
"""
Create a copied version of the layout pin at the current level.
@ -226,6 +232,16 @@ class layout():
new_name = pin.name
self.add_layout_pin(new_name, pin.layer, pin.ll(), pin.width(), pin.height())
def copy_layout_pins(self, instance, prefix=""):
"""
Create a copied version of the layout pin at the current level.
You can optionally rename the pin to a new name.
"""
for pin_name in self.pin_map.keys():
pins=instance.get_pins(pin_name)
for pin in pins:
self.add_layout_pin(prefix+pin_name, pin.layer, pin.ll(), pin.width(), pin.height())
def add_layout_pin_segment_center(self, text, layer, start, end):
"""
Creates a path like pin with center-line convention
@ -880,10 +896,10 @@ class layout():
"""
self.create_channel_route(netlist, offset, layer_stack, pitch, vertical=False)
def add_boundary(self):
def add_boundary(self, offset=vector(0,0)):
""" Add boundary for debugging dimensions """
self.add_rect(layer="boundary",
offset=vector(0,0),
offset=offset,
height=self.height,
width=self.width)

View File

@ -102,6 +102,10 @@ class spice():
output_list.append(pin)
return output_list
def copy_pins(self, other_module, suffix=""):
""" This will copy all of the pins from the other module and add an optional suffix."""
for pin in other_module.pins:
self.add_pin(pin+suffix, other_module.get_pin_type(pin))
def add_mod(self, mod):
"""Adds a subckt/submodule to the subckt hierarchy"""

View File

@ -38,15 +38,6 @@ class bitcell(design.design):
cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file.
return logical_effort.logical_effort('bitline', size, cin, load, parasitic_delay, False)
def list_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
bitcell_pins = ["bl_{0}".format(col),
"br_{0}".format(col),
"wl_{0}".format(row),
"vdd",
"gnd"]
return bitcell_pins
def list_all_wl_names(self):
""" Creates a list of all wordline pin names """
row_pins = ["wl"]

View File

@ -30,6 +30,14 @@ class replica_bitcell(design.design):
self.height = replica_bitcell.height
self.pin_map = replica_bitcell.pin_map
def analytical_power(self, corner, load):
"""Bitcell power in nW. Only characterizes leakage."""
from tech import spice
leakage = spice["bitcell_leakage"]
dynamic = 0 #temporary
total_power = self.return_power(dynamic, leakage)
return total_power
def get_wl_cin(self):
"""Return the relative capacitance of the access transistor gates"""
#This is a handmade cell so the value must be entered in the tech.py file or estimated.

View File

@ -270,13 +270,15 @@ class bank(design.design):
# the bitcell array.
# The decoder/driver logic is placed on the right and mirrored on Y-axis.
# The write/sense/precharge/mux is placed on the top and mirrored on the X-axis.
bitcell_array_top = self.bitcell_array.height + self.m2_gap + drc("well_enclosure_active") + self.m1_width
bitcell_array_right = self.bitcell_array.width + self.m1_width + self.m2_gap
# LOWER LEFT QUADRANT
# Bitcell array is placed at (0,0)
# UPPER LEFT QUADRANT
# Above the bitcell array
y_offset = self.bitcell_array.height + self.m2_gap
y_offset = bitcell_array_top
for i,p in enumerate(self.vertical_port_order[port]):
if p==None:
continue
@ -292,7 +294,7 @@ class bank(design.design):
# LOWER RIGHT QUADRANT
# To the left of the bitcell array
# The wordline driver is placed to the right of the main decoder width.
x_offset = self.bitcell_array.width + self.m2_gap + self.wordline_driver.width
x_offset = bitcell_array_right + self.wordline_driver.width
self.wordline_driver_offsets[port] = vector(x_offset,0)
x_offset += self.row_decoder.width + self.m2_gap
self.row_decoder_offsets[port] = vector(x_offset,0)
@ -300,12 +302,12 @@ class bank(design.design):
# UPPER RIGHT QUADRANT
# Place the col decoder right aligned with wordline driver plus halfway under row decoder
# Above the bitcell array with a well spacing
x_offset = self.bitcell_array.width + self.central_bus_width[port] + self.wordline_driver.width
x_offset = bitcell_array_right + self.central_bus_width[port] + self.wordline_driver.width
if self.col_addr_size > 0:
x_offset += self.column_decoder.width + self.col_addr_bus_width
y_offset = self.bitcell_array.height + self.column_decoder.height + self.m2_gap
y_offset = bitcell_array_height + self.column_decoder.height
else:
y_offset = self.bitcell_array.height
y_offset = bitcell_array_height
y_offset += 2*drc("well_to_well")
self.column_decoder_offsets[port] = vector(x_offset,y_offset)
@ -860,8 +862,8 @@ class bank(design.design):
# Port 1
if len(self.all_ports)==2:
# The other control bus is routed up to two pitches above the bitcell array
control_bus_length = self.max_y_offset - self.bitcell_array.height - 2*self.m1_pitch
control_bus_offset = vector(self.bitcell_array.width + self.m2_width,
control_bus_length = self.max_y_offset - bitcell_array_top - 2*self.m1_pitch
control_bus_offset = vector(bitcell_array_right,
self.max_y_offset - control_bus_length)
self.bus_xoffset[1] = self.create_bus(layer="metal2",

View File

@ -45,8 +45,8 @@ class bitcell_array(design.design):
def create_layout(self):
# We increase it by a well enclosure so the precharges don't overlap our wells
self.height = self.row_size*self.cell.height + drc("well_enclosure_active") + self.m1_width
self.width = self.column_size*self.cell.width + self.m1_width
self.height = self.row_size*self.cell.height
self.width = self.column_size*self.cell.width
xoffset = 0.0
for col in range(self.column_size):
@ -89,6 +89,24 @@ class bitcell_array(design.design):
self.cell = factory.create(module_type="bitcell")
self.add_mod(self.cell)
def list_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell,
indexed by column and row, for instance use in bitcell_array """
bitcell_pins = []
pin_names = self.cell.list_all_bitline_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(col))
pin_names = self.cell.list_all_wl_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(row))
bitcell_pins.append("vdd")
bitcell_pins.append("gnd")
return bitcell_pins
def create_instances(self):
""" Create the module instances used in this design """
self.cell_inst = {}
@ -97,7 +115,7 @@ class bitcell_array(design.design):
name = "bit_r{0}_c{1}".format(row, col)
self.cell_inst[row,col]=self.add_inst(name=name,
mod=self.cell)
self.connect_inst(self.cell.list_bitcell_pins(col, row))
self.connect_inst(self.list_bitcell_pins(col, row))
def add_layout_pins(self):
""" Add the layout pins """
@ -105,32 +123,24 @@ class bitcell_array(design.design):
row_list = self.cell.list_all_wl_names()
column_list = self.cell.list_all_bitline_names()
offset = vector(0.0, 0.0)
for col in range(self.column_size):
for cell_column in column_list:
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"_{0}".format(col),
layer="metal2",
offset=bl_pin.ll(),
layer=bl_pin.layer,
offset=bl_pin.ll().scale(1,0),
width=bl_pin.width(),
height=self.height)
# increments to the next column width
offset.x += self.cell.width
offset.x = 0.0
for row in range(self.row_size):
for cell_row in row_list:
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
self.add_layout_pin(text=cell_row+"_{0}".format(row),
layer="metal1",
offset=wl_pin.ll(),
layer=wl_pin.layer,
offset=wl_pin.ll().scale(0,1),
width=self.width,
height=wl_pin.height())
# increments to the next row height
offset.y += self.cell.height
# For every second row and column, add a via for gnd and vdd
for row in range(self.row_size):
for col in range(self.column_size):

View File

@ -0,0 +1,156 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import debug
import design
from tech import drc
import contact
from sram_factory import factory
from vector import vector
from globals import OPTS
class dummy_array(design.design):
"""
Generate a dummy row/column for the replica array.
"""
def __init__(self, cols, rows, name):
design.design.__init__(self, name)
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.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
def create_netlist(self):
""" Create and connect the netlist """
self.add_modules()
self.add_pins()
self.create_instances()
def create_layout(self):
# We increase it by a well enclosure so the precharges don't overlap our wells
self.height = self.row_size*self.dummy_cell.height
self.width = self.column_size*self.dummy_cell.width
xoffset = 0.0
for col in range(self.column_size):
yoffset = 0.0
for row in range(self.row_size):
name = "dummy_r{0}_c{1}".format(row, col)
if row % 2:
tempy = yoffset + self.dummy_cell.height
dir_key = "MX"
else:
tempy = yoffset
dir_key = ""
self.cell_inst[row,col].place(offset=[xoffset, tempy],
mirror=dir_key)
yoffset += self.dummy_cell.height
xoffset += self.dummy_cell.width
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_pins(self):
row_list = self.cell.list_all_wl_names()
column_list = self.cell.list_all_bitline_names()
for col in range(self.column_size):
for cell_column in column_list:
self.add_pin(cell_column+"_{0}".format(col))
for row in range(self.row_size):
for cell_row in row_list:
self.add_pin(cell_row+"_{0}".format(row))
self.add_pin("vdd")
self.add_pin("gnd")
def add_modules(self):
""" Add the modules used in this design """
self.dummy_cell = factory.create(module_type="dummy_bitcell")
self.add_mod(self.dummy_cell)
self.cell = factory.create(module_type="bitcell")
def list_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell,
indexed by column and row, for instance use in bitcell_array """
bitcell_pins = []
pin_names = self.cell.list_all_bitline_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(col))
pin_names = self.cell.list_all_wl_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(row))
bitcell_pins.append("vdd")
bitcell_pins.append("gnd")
return bitcell_pins
def create_instances(self):
""" Create the module instances used in this design """
self.cell_inst = {}
for col in range(self.column_size):
for row in range(self.row_size):
name = "bit_r{0}_c{1}".format(row, col)
self.cell_inst[row,col]=self.add_inst(name=name,
mod=self.dummy_cell)
self.connect_inst(self.list_bitcell_pins(col, row))
def add_layout_pins(self):
""" Add the layout pins """
row_list = self.cell.list_all_wl_names()
column_list = self.cell.list_all_bitline_names()
for col in range(self.column_size):
for cell_column in column_list:
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"_{0}".format(col),
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=self.height)
for row in range(self.row_size):
for cell_row in row_list:
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
self.add_layout_pin(text=cell_row+"_{0}".format(row),
layer="metal1",
offset=wl_pin.ll(),
width=self.width,
height=wl_pin.height())
# For every second row and column, add a via for gnd and vdd
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row,col]
for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin_name, loc=pin.center(), vertical=True, start_layer=pin.layer)
def input_load(self):
wl_wire = self.gen_wl_wire()
return wl_wire.return_input_cap()
def get_wordline_cin(self):
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
#A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
bitcell_wl_cin = self.cell.get_wl_cin()
total_cin = bitcell_wl_cin * self.column_size
return total_cin

View File

@ -1,133 +0,0 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import debug
import design
from tech import drc
import contact
from sram_factory import factory
from vector import vector
from globals import OPTS
class dummy_row(design.design):
"""
Generate a replica wordline row for the replica array.
"""
def __init__(self, name, cols):
design.design.__init__(self, name)
self.column_size = cols
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
def create_netlist(self):
self.add_modules()
self.add_pins()
self.create_instances()
def create_layout(self):
self.place_instances()
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_pins(self):
column_list = self.cell.list_all_bitline_names()
for col in range(self.column_size):
for cell_column in column_list:
self.add_pin("{0}_{1}".format(cell_column,col))
row_list = self.cell.list_all_wl_names()
for cell_row in row_list:
self.add_pin("{0}_{1}".format(cell_row,0))
self.add_pin("vdd")
self.add_pin("gnd")
def add_modules(self):
self.dummy_cell = factory.create(module_type="dummy_bitcell")
self.add_mod(self.dummy_cell)
# Used for pin names only
self.cell = factory.create(module_type="bitcell")
def create_instances(self):
self.cell_inst = {}
for col in range(self.column_size):
name="dummy_{0}".format(col)
self.cell_inst[col]=self.add_inst(name=name,
mod=self.dummy_cell)
self.connect_inst(self.list_bitcell_pins(col, 0))
def create_layout(self):
# We increase it by a well enclosure so the precharges don't overlap our wells
self.height = self.cell.height
self.width = self.column_size*self.cell.width
xoffset = 0.0
tempy = self.cell.height
dir_key = "MX"
for col in range(self.column_size):
name = "bit_{0}_c{1}".format("dummy",col)
self.cell_inst[col].place(offset=[xoffset, tempy],
mirror=dir_key)
xoffset += self.cell.width
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_layout_pins(self):
""" Add the layout pins """
row_list = self.cell.list_all_wl_names()
column_list = self.cell.list_all_bitline_names()
for col in range(self.column_size):
for cell_column in column_list:
bl_pin = self.cell_inst[col].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"_{0}".format(col),
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=self.height)
for cell_row in row_list:
wl_pin = self.cell_inst[0].get_pin(cell_row)
self.add_layout_pin(text=cell_row+"_{0}".format(0),
layer="metal1",
offset=wl_pin.ll(),
width=self.width,
height=wl_pin.height())
# For every second row and column, add a via for gnd and vdd
for col in range(self.column_size):
inst = self.cell_inst[col]
for pin_name in ["vdd", "gnd"]:
self.copy_layout_pin(inst, pin_name)
def list_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell,
indexed by column and row, for instance use in bitcell_array """
bitcell_pins = []
pin_names = self.cell.list_all_bitline_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(col))
pin_names = self.cell.list_all_wl_names()
for pin in pin_names:
bitcell_pins.append(pin+"_{0}".format(row))
bitcell_pins.append("vdd")
bitcell_pins.append("gnd")
return bitcell_pins

View File

@ -0,0 +1,366 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import debug
import design
from tech import drc, spice
from vector import vector
from globals import OPTS
from sram_factory import factory
import logical_effort
import bitcell_array
import replica_column
import dummy_array
class replica_bitcell_array(design.design):
"""
Creates a bitcell arrow of cols x rows and then adds the replica and dummy columns
and rows for one or two read ports. Replica columns are on the left and right, respectively.
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).
"""
def __init__(self, cols, rows, name):
design.design.__init__(self, name)
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.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
#self.offset_all_coordinates()
def create_netlist(self):
""" Create and connect the netlist """
self.add_modules()
self.add_pins()
self.create_instances()
def add_modules(self):
""" Array and dummy/replica columns
d or D = dummy cell (caps to distinguish grouping)
r or R = replica cell (caps to distinguish grouping)
b or B = bitcell
replica columns 1
v v
bdDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDrb <- Dummy row
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 for port names only
self.cell = factory.create(module_type="bitcell")
# Bitcell array
self.bitcell_array = factory.create(module_type="bitcell_array",
cols=self.column_size,
rows=self.row_size)
self.add_mod(self.bitcell_array)
# Replica bitline
self.replica_column = factory.create(module_type="replica_column",
rows=self.row_size + 4)
self.add_mod(self.replica_column)
# Dummy row
self.dummy_row = factory.create(module_type="dummy_array",
rows=1,
cols=self.column_size)
self.add_mod(self.dummy_row)
# Dummy col
self.dummy_col = factory.create(module_type="dummy_array",
cols=1,
rows=self.row_size + 4)
self.add_mod(self.dummy_col)
def add_pins(self):
self.wl_names = [x for x in self.bitcell_array.pins if x.startswith("w")]
self.bl_names = [x for x in self.bitcell_array.pins if x.startswith("b")]
# top/bottom rows (in the middle)
self.replica_wl_names = ["replica_"+x for x in self.cell.pins if x.startswith("w")]
self.dummy_wl_names = ["dummy_"+x for x in self.cell.pins if x.startswith("w")]
self.dummy_bl_names = ["dummy_"+x for x in self.cell.pins if x.startswith("b")]
self.dummy_row_bl_names = self.bl_names
# dummy row and replica on each side of the bitcell rows
self.replica_col_wl_names = [x+"_0" for x in self.dummy_wl_names] \
+ ["replica_"+x+"_0" for x in self.cell.list_all_wl_names()] \
+ self.wl_names \
+ ["replica_"+x+"_1" for x in self.cell.list_all_wl_names()] \
+ [x+"_1" for x in self.dummy_wl_names]
self.replica_bl_names = ["replica_"+x for x in self.cell.pins if x.startswith("b")]
# left/right rows
self.dummy_col_wl_names = self.replica_col_wl_names
self.add_pin_list(self.bl_names)
self.add_pin_list([x+"_0" for x in self.replica_bl_names])
self.add_pin_list([x+"_1" for x in self.replica_bl_names])
self.add_pin_list([x for x in self.replica_col_wl_names if not x.startswith("dummy")])
self.add_pin("vdd")
self.add_pin("gnd")
def create_instances(self):
""" Create the module instances used in this design """
supplies = ["vdd", "gnd"]
# Main array
self.bitcell_array_inst=self.add_inst(name="bitcell_array",
mod=self.bitcell_array)
self.connect_inst(self.bitcell_array.pins)
# Replica columns (two even if one port for now)
self.replica_col_left_inst=self.add_inst(name="replica_col_left",
mod=self.replica_column)
self.connect_inst([x+"_0" for x in self.replica_bl_names] + self.replica_col_wl_names + supplies)
self.replica_col_right_inst=self.add_inst(name="replica_col_right",
mod=self.replica_column)
self.connect_inst([x+"_1" for x in self.replica_bl_names] + self.replica_col_wl_names[::-1] + supplies)
# Replica rows with replica bitcell
self.dummy_row_bottop_inst=self.add_inst(name="dummy_row_bottop",
mod=self.dummy_row)
self.connect_inst(self.dummy_row_bl_names + [x+"_0" for x in self.replica_wl_names] + supplies)
self.dummy_row_topbot_inst=self.add_inst(name="dummy_row_topbot",
mod=self.dummy_row)
self.connect_inst(self.dummy_row_bl_names + [x+"_1" for x in self.replica_wl_names] + supplies)
# Dummy rows without replica bitcell
self.dummy_row_botbot_inst=self.add_inst(name="dummy_row_botbot",
mod=self.dummy_row)
self.connect_inst(self.dummy_row_bl_names + [x+"_0" for x in self.dummy_wl_names] + supplies)
self.dummy_row_toptop_inst=self.add_inst(name="dummy_row_toptop",
mod=self.dummy_row)
self.connect_inst(self.dummy_row_bl_names + [x+"_1" for x in self.dummy_wl_names] + supplies)
# Dummy columns
self.dummy_col_left_inst=self.add_inst(name="dummy_col_left",
mod=self.dummy_col)
self.connect_inst([x+"_0" for x in self.dummy_bl_names] + self.dummy_col_wl_names + supplies)
self.dummy_col_right_inst=self.add_inst(name="dummy_col_right",
mod=self.dummy_col)
self.connect_inst([x+"_1" for x in self.dummy_bl_names] + self.dummy_col_wl_names + supplies)
def create_layout(self):
self.height = (self.row_size+4)*self.dummy_row.height
self.width = (self.column_size+4)*self.replica_column.width
# This is a bitcell x bitcell offset to scale
offset = vector(self.replica_column.width, self.dummy_row.height)
self.bitcell_array_inst.place(offset=[0,0])
self.replica_col_left_inst.place(offset=offset.scale(-1,-2))
self.replica_col_right_inst.place(offset=offset.scale(0,2)+self.bitcell_array_inst.ur(),
mirror="MX")
self.dummy_row_toptop_inst.place(offset=offset.scale(0,2)+self.bitcell_array_inst.ul(),
mirror="MX")
self.dummy_row_topbot_inst.place(offset=offset.scale(0,0)+self.bitcell_array_inst.ul())
self.dummy_row_bottop_inst.place(offset=offset.scale(0,0),
mirror="MX")
self.dummy_row_botbot_inst.place(offset=offset.scale(0,-2))
self.dummy_col_left_inst.place(offset=offset.scale(-2,-2))
self.dummy_col_right_inst.place(offset=offset.scale(1,-2)+self.bitcell_array_inst.lr())
self.translate_all(offset.scale(-2,-2))
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_layout_pins(self):
""" Add the layout pins """
# Main array wl and bl/br
pin_names = self.bitcell_array.get_pin_names()
for pin_name in pin_names:
if pin_name.startswith("wl"):
pin_list = self.bitcell_array_inst.get_pins(pin_name)
for pin in pin_list:
self.add_layout_pin_rect_center(text=pin_name,
layer=pin.layer,
offset=pin.center(),
width=self.width,
height=pin.height())
elif pin_name.startswith("bl") or pin_name.startswith("br"):
pin_list = self.bitcell_array_inst.get_pins(pin_name)
for pin in pin_list:
self.add_layout_pin_rect_center(text=pin_name,
layer=pin.layer,
offset=pin.center(),
width=pin.width(),
height=self.height)
for index,(side1,side2) in enumerate([("bottop","left"),("topbot","right")]):
inst = getattr(self, "dummy_row_{}_inst".format(side1))
pin_names = inst.mod.get_pin_names()
for pin_name in pin_names:
if pin_name.startswith("wl"):
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
name = "replica_{0}_{1}".format(pin_name,index)
self.add_layout_pin_rect_center(text=name,
layer=pin.layer,
offset=pin.center(),
width=self.width,
height=pin.height())
# Replica columns
for index,side in enumerate(["left","right"]):
inst = getattr(self, "replica_col_{}_inst".format(side))
pin_names = inst.mod.get_pin_names()
for pin_name in pin_names:
if pin_name.startswith("bl") or pin_name.startswith("br"):
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
name = "replica_{0}_{1}".format(pin_name,index)
self.add_layout_pin(text=name,
layer=pin.layer,
offset=pin.ll().scale(1,0),
width=pin.width(),
height=self.height)
for pin_name in ["vdd","gnd"]:
for inst in [self.bitcell_array_inst,
self.replica_col_left_inst, self.replica_col_right_inst,
self.dummy_col_left_inst, self.dummy_col_right_inst,
self.dummy_row_toptop_inst, self.dummy_row_topbot_inst,
self.dummy_row_bottop_inst, self.dummy_row_botbot_inst]:
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
self.add_power_pin(name=pin_name, loc=pin.center(), vertical=True, start_layer=pin.layer)
# Non-pins
for side in ["botbot", "toptop"]:
inst = getattr(self, "dummy_row_{}_inst".format(side))
pin_names = inst.mod.get_pin_names()
for pin_name in pin_names:
if pin_name.startswith("wl"):
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
self.add_rect_center(layer=pin.layer,
offset=pin.center(),
width=self.width,
height=pin.height())
for side in ["left", "right"]:
inst = getattr(self, "dummy_col_{}_inst".format(side))
pin_names = inst.mod.get_pin_names()
for pin_name in pin_names:
if pin_name.startswith("b"):
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
self.add_rect_center(layer=pin.layer,
offset=pin.center(),
width=pin.width(),
height=self.height)
def analytical_delay(self, corner, slew, load):
"""Returns relative delay of the bitline in the bitcell array"""
from tech import parameter
#The load being driven/drained is mostly the bitline but could include the sense amp or the column mux.
#The load from the bitlines is due to the drain capacitances from all the other bitlines and wire parasitics.
drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])
wire_unit_load = .05 * drain_load #Wires add 5% to this.
bitline_load = (drain_load+wire_unit_load)*self.row_size
return [self.cell.analytical_delay(corner, slew, load+bitline_load)]
def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW."""
from tech import drc, parameter
# Dynamic Power from Bitline
bl_wire = self.gen_bl_wire()
cell_load = 2 * bl_wire.return_input_cap()
bl_swing = parameter["rbl_height_percentage"]
freq = spice["default_event_rate"]
bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing)
#Calculate the bitcell power which currently only includes leakage
cell_power = self.cell.analytical_power(corner, load)
#Leakage power grows with entire array and bitlines.
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_wl_wire(self):
if OPTS.netlist_only:
width = 0
else:
width = self.width
wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_metal1"))
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
return wl_wire
def gen_bl_wire(self):
if OPTS.netlist_only:
height = 0
else:
height = self.height
bl_pos = 0
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_metal1"))
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
return bl_wire
def output_load(self, bl_pos=0):
bl_wire = self.gen_bl_wire()
return bl_wire.wire_c # sense amp only need to charge small portion of the bl
# set as one segment for now
def input_load(self):
wl_wire = self.gen_wl_wire()
return wl_wire.return_input_cap()
def get_wordline_cin(self):
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
#A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
bitcell_wl_cin = self.cell.get_wl_cin()
total_cin = bitcell_wl_cin * self.column_size
return total_cin

View File

@ -19,8 +19,7 @@ class replica_column(design.design):
def __init__(self, name, rows):
design.design.__init__(self, name)
# One extra row for the dummy row
self.row_size = rows + 1
self.row_size = rows
self.create_netlist()
if not OPTS.netlist_only:
@ -35,6 +34,9 @@ class replica_column(design.design):
self.place_instances()
self.add_layout_pins()
self.height = self.row_size*self.cell.height
self.width = self.cell.width
self.add_boundary()
self.DRC_LVS()
@ -53,6 +55,8 @@ class replica_column(design.design):
def add_modules(self):
self.replica_cell = factory.create(module_type="replica_bitcell")
self.add_mod(self.replica_cell)
self.dummy_cell = factory.create(module_type="dummy_bitcell")
self.add_mod(self.dummy_cell)
# Used for pin names only
self.cell = factory.create(module_type="bitcell")
@ -60,37 +64,32 @@ class replica_column(design.design):
self.cell_inst = {}
for row in range(self.row_size):
name="rbc_{0}".format(row)
self.cell_inst[row]=self.add_inst(name=name,
mod=self.replica_cell)
if row>0 and row<self.row_size-2:
self.cell_inst[row]=self.add_inst(name=name,
mod=self.replica_cell)
else:
self.cell_inst[row]=self.add_inst(name=name,
mod=self.dummy_cell)
self.connect_inst(self.list_bitcell_pins(0, row))
def create_layout(self):
def place_instances(self):
# We increase it by a well enclosure so the precharges don't overlap our wells
self.height = self.row_size*self.cell.height
self.width = self.cell.width
yoffset = 0.0
yoffset = 0
for row in range(self.row_size):
name = "bit_r{0}_{1}".format(row,"rbl")
# This is opposite of a bitcell array since we will be 1 row off
if not row % 2:
tempy = yoffset + self.cell.height
dir_key = "MX"
else:
tempy = yoffset
dir_key = ""
else:
tempy = yoffset + self.cell.height
dir_key = "MX"
self.cell_inst[row].place(offset=[0.0, tempy],
mirror=dir_key)
yoffset += self.cell.height
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def add_layout_pins(self):
@ -99,7 +98,7 @@ class replica_column(design.design):
row_list = self.cell.list_all_wl_names()
column_list = self.cell.list_all_bitline_names()
col = "rbl"
col = "0"
for cell_column in column_list:
bl_pin = self.cell_inst[0].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"_{0}".format(col),

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import unittest
from testutils import *
import sys,os
sys.path.append(os.getenv("OPENRAM_HOME"))
import globals
from globals import OPTS
from sram_factory import factory
import debug
class dummy_row_test(openram_test):
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
debug.info(2, "Testing dummy row for 6t_cell")
a = factory.create(module_type="dummy_array", rows=1, cols=4)
self.local_check(a)
debug.info(2, "Testing dummy column for 6t_cell")
a = factory.create(module_type="dummy_array", rows=4, cols=1)
self.local_check(a)
globals.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -13,13 +13,13 @@ from globals import OPTS
from sram_factory import factory
import debug
class dummy_row_test(openram_test):
class replica_bitcell_array_test(openram_test):
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
debug.info(2, "Testing dummy row for 6t_cell")
a = factory.create(module_type="dummy_row", cols=4)
debug.info(2, "Testing 4x4 array for 6t_cell")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4)
self.local_check(a)
globals.end_openram()

View File

@ -1,117 +1,118 @@
magic
tech scmos
timestamp 1536091415
timestamp 1560809302
<< nwell >>
rect -8 29 42 51
rect -8 35 42 57
<< pwell >>
rect -8 -8 42 29
rect -8 -2 42 35
<< ntransistor >>
rect 7 10 9 18
rect 29 10 31 18
rect 10 3 14 5
rect 24 3 28 5
rect 7 16 9 24
rect 29 16 31 24
rect 10 9 14 11
rect 24 9 28 11
<< ptransistor >>
rect 7 37 11 40
rect 27 37 31 40
rect 7 43 11 46
rect 27 43 31 46
<< ndiffusion >>
rect -2 22 7 24
rect 2 18 7 22
rect -2 16 7 18
rect 2 12 7 16
rect -2 10 7 12
rect 9 14 10 18
rect 9 10 14 14
rect 28 14 29 18
rect 24 10 29 14
rect 9 20 10 24
rect 9 16 14 20
rect 28 20 29 24
rect 24 16 29 20
rect 31 22 36 24
rect 31 18 32 22
rect 31 16 36 18
rect 31 12 32 16
rect 31 10 36 12
rect 10 5 14 10
rect 24 5 28 10
rect 10 2 14 3
rect 24 2 28 3
rect 10 11 14 16
rect 24 11 28 16
rect 10 8 14 9
rect 24 8 28 9
<< pdiffusion >>
rect 2 37 7 40
rect 11 37 12 40
rect 26 37 27 40
rect 31 37 32 40
rect 2 43 7 46
rect 11 43 12 46
rect 26 43 27 46
rect 31 43 32 46
<< ndcontact >>
rect -2 12 2 16
rect 10 14 14 18
rect 24 14 28 18
rect 32 12 36 16
rect 10 -2 14 2
rect 24 -2 28 2
rect -2 18 2 22
rect 10 20 14 24
rect 24 20 28 24
rect 32 18 36 22
rect 10 4 14 8
rect 24 4 28 8
<< pdcontact >>
rect -2 36 2 40
rect 12 36 16 40
rect 22 36 26 40
rect 32 36 36 40
rect -2 42 2 46
rect 12 42 16 46
rect 22 42 26 46
rect 32 42 36 46
<< psubstratepcontact >>
rect -2 22 2 26
rect 32 22 36 26
rect -2 28 2 32
rect 32 28 36 32
<< nsubstratencontact >>
rect 32 44 36 48
rect 32 50 36 54
<< polysilicon >>
rect 7 40 11 42
rect 27 40 31 42
rect 7 35 11 37
rect 7 21 9 35
rect 27 34 31 37
rect 15 33 31 34
rect 19 32 31 33
rect 7 20 21 21
rect 7 19 24 20
rect 7 18 9 19
rect 29 18 31 32
rect 7 8 9 10
rect 17 5 21 6
rect 29 8 31 10
rect -2 3 10 5
rect 14 3 24 5
rect 28 3 36 5
rect 7 46 11 48
rect 27 46 31 48
rect 7 41 11 43
rect 7 27 9 41
rect 27 40 31 43
rect 15 39 31 40
rect 19 38 31 39
rect 7 26 21 27
rect 7 25 24 26
rect 7 24 9 25
rect 29 24 31 38
rect 7 14 9 16
rect 17 11 21 12
rect 29 14 31 16
rect -2 9 10 11
rect 14 9 24 11
rect 28 9 36 11
<< polycontact >>
rect 15 29 19 33
rect 21 20 25 24
rect 17 6 21 10
rect 15 35 19 39
rect 21 26 25 30
rect 17 12 21 16
<< metal1 >>
rect -2 44 15 48
rect 19 44 32 48
rect -2 40 2 44
rect 32 40 36 44
rect 11 36 12 40
rect 26 36 27 40
rect -2 26 2 29
rect -2 16 2 22
rect 11 18 15 36
rect 23 24 27 36
rect 25 20 27 24
rect 14 14 15 18
rect 23 18 27 20
rect 32 26 36 29
rect 23 14 24 18
rect 32 16 36 22
rect -2 6 17 9
rect 21 6 36 9
rect -2 5 36 6
rect -2 50 15 54
rect 19 50 32 54
rect -2 46 2 50
rect 32 46 36 50
rect 11 42 12 46
rect 26 42 27 46
rect -2 32 2 35
rect -2 22 2 28
rect 11 24 15 42
rect 23 30 27 42
rect 25 26 27 30
rect 14 20 15 24
rect 23 24 27 26
rect 32 32 36 35
rect 23 20 24 24
rect 32 22 36 28
rect -2 12 17 15
rect 21 12 36 15
rect -2 11 36 12
<< m2contact >>
rect 15 44 19 48
rect -2 29 2 33
rect 32 29 36 33
rect 6 -2 10 2
rect 20 -2 24 2
rect 15 50 19 54
rect -2 35 2 39
rect 32 35 36 39
rect 6 4 10 8
rect 20 4 24 8
<< metal2 >>
rect -2 33 2 48
rect -2 -2 2 29
rect 6 2 10 48
rect 24 -2 28 48
rect 32 33 36 48
rect 32 -2 36 29
rect -2 39 2 54
rect -2 0 2 35
rect 6 8 10 54
rect 6 0 10 4
rect 24 0 28 54
rect 32 39 36 54
rect 32 0 36 35
<< bb >>
rect 0 0 34 46
rect 0 0 34 52
<< labels >>
rlabel metal2 0 0 0 0 1 gnd
rlabel metal2 34 0 34 0 1 gnd
rlabel m2contact 17 46 17 46 5 vdd
rlabel metal2 8 43 8 43 1 bl
rlabel metal2 26 43 26 43 1 br
rlabel metal1 4 7 4 7 1 wl
rlabel metal2 0 6 0 6 1 gnd
rlabel metal2 34 6 34 6 1 gnd
rlabel m2contact 17 52 17 52 5 vdd
rlabel metal2 8 49 8 49 1 bl
rlabel metal2 26 49 26 49 1 br
rlabel metal1 4 13 4 13 1 wl
<< end >>

View File

@ -1,118 +1,115 @@
magic
tech scmos
timestamp 1560540221
timestamp 1560809362
<< nwell >>
rect -8 29 42 51
rect -8 35 42 57
<< pwell >>
rect -8 -8 42 29
rect -8 -2 42 35
<< ntransistor >>
rect 7 10 9 18
rect 29 10 31 18
rect 10 3 14 5
rect 24 3 28 5
rect 7 16 9 24
rect 29 16 31 24
rect 10 9 14 11
rect 24 9 28 11
<< ptransistor >>
rect 7 37 11 40
rect 27 37 31 40
rect 7 43 11 46
rect 27 43 31 46
<< ndiffusion >>
rect -2 22 7 24
rect 2 18 7 22
rect -2 16 7 18
rect 2 12 7 16
rect -2 10 7 12
rect 9 14 10 18
rect 9 10 14 14
rect 28 14 29 18
rect 24 10 29 14
rect 9 20 10 24
rect 9 16 14 20
rect 28 20 29 24
rect 24 16 29 20
rect 31 22 36 24
rect 31 18 32 22
rect 31 16 36 18
rect 31 12 32 16
rect 31 10 36 12
rect 10 5 14 10
rect 24 5 28 10
rect 10 2 14 3
rect 24 2 28 3
rect 10 11 14 16
rect 24 11 28 16
rect 10 8 14 9
rect 24 8 28 9
<< pdiffusion >>
rect 2 37 7 40
rect 11 37 12 40
rect 26 37 27 40
rect 31 37 32 40
rect 2 43 7 46
rect 11 43 12 46
rect 26 43 27 46
rect 31 43 32 46
<< ndcontact >>
rect -2 12 2 16
rect 10 14 14 18
rect 24 14 28 18
rect 32 12 36 16
rect 10 -2 14 2
rect 24 -2 28 2
rect -2 18 2 22
rect 10 20 14 24
rect 24 20 28 24
rect 32 18 36 22
rect 10 4 14 8
rect 24 4 28 8
<< pdcontact >>
rect -2 36 2 40
rect 12 36 16 40
rect 22 36 26 40
rect 32 36 36 40
rect -2 42 2 46
rect 12 42 16 46
rect 22 42 26 46
rect 32 42 36 46
<< psubstratepcontact >>
rect -2 22 2 26
rect 32 22 36 26
rect -2 28 2 32
rect 32 28 36 32
<< nsubstratencontact >>
rect 32 44 36 48
rect 32 50 36 54
<< polysilicon >>
rect 7 40 11 42
rect 27 40 31 42
rect 7 35 11 37
rect 7 21 9 35
rect 27 34 31 37
rect 15 33 31 34
rect 19 32 31 33
rect 7 20 21 21
rect 7 19 24 20
rect 7 18 9 19
rect 29 18 31 32
rect 7 8 9 10
rect 17 5 21 6
rect 29 8 31 10
rect -2 3 10 5
rect 14 3 24 5
rect 28 3 36 5
rect 7 46 11 48
rect 27 46 31 48
rect 7 41 11 43
rect 7 27 9 41
rect 27 40 31 43
rect 15 39 31 40
rect 19 38 31 39
rect 7 26 21 27
rect 7 25 24 26
rect 7 24 9 25
rect 29 24 31 38
rect 7 14 9 16
rect 17 11 21 12
rect 29 14 31 16
rect -2 9 10 11
rect 14 9 24 11
rect 28 9 36 11
<< polycontact >>
rect 15 29 19 33
rect 21 20 25 24
rect 17 6 21 10
rect 15 35 19 39
rect 21 26 25 30
rect 17 12 21 16
<< metal1 >>
rect -2 44 15 48
rect 19 44 32 48
rect -2 40 2 44
rect 32 40 36 44
rect 11 36 12 40
rect 26 36 27 40
rect -2 26 2 29
rect -2 16 2 22
rect 11 18 15 36
rect 23 24 27 36
rect 25 20 27 24
rect 14 14 15 18
rect 23 18 27 20
rect 32 26 36 29
rect 23 14 24 18
rect 32 16 36 22
rect -2 6 17 9
rect 21 6 36 9
rect -2 5 36 6
rect 6 -2 10 2
rect 20 -2 24 2
rect -2 50 15 54
rect 19 50 32 54
rect -2 46 2 50
rect 32 46 36 50
rect 11 42 12 46
rect 26 42 27 46
rect -2 32 2 35
rect -2 22 2 28
rect 11 24 15 42
rect 23 30 27 42
rect 25 26 27 30
rect 14 20 15 24
rect 23 24 27 26
rect 32 32 36 35
rect 23 20 24 24
rect 32 22 36 28
rect -2 12 17 15
rect 21 12 36 15
rect -2 11 36 12
<< m2contact >>
rect 15 44 19 48
rect -2 29 2 33
rect 32 29 36 33
rect 15 50 19 54
rect -2 35 2 39
rect 32 35 36 39
<< metal2 >>
rect -2 33 2 48
rect -2 -2 2 29
rect 6 -2 10 48
rect 24 2 28 48
rect 20 -2 28 2
rect 32 33 36 48
rect 32 -2 36 29
rect -2 39 2 54
rect -2 0 2 35
rect 6 0 10 54
rect 24 0 28 54
rect 32 39 36 54
rect 32 0 36 35
<< bb >>
rect 0 0 34 46
rect 0 0 34 52
<< labels >>
rlabel metal2 0 0 0 0 1 gnd
rlabel metal2 34 0 34 0 1 gnd
rlabel m2contact 17 46 17 46 5 vdd
rlabel metal2 8 43 8 43 1 bl
rlabel metal2 26 43 26 43 1 br
rlabel metal1 4 7 4 7 1 wl
rlabel metal2 0 6 0 6 1 gnd
rlabel metal2 34 6 34 6 1 gnd
rlabel m2contact 17 52 17 52 5 vdd
rlabel metal2 8 49 8 49 1 bl
rlabel metal2 26 49 26 49 1 br
rlabel metal1 4 13 4 13 1 wl
<< end >>

View File

@ -1,118 +1,119 @@
magic
tech scmos
timestamp 1541443051
timestamp 1560809329
<< nwell >>
rect -8 29 42 51
rect -8 35 42 57
<< pwell >>
rect -8 -8 42 29
rect -8 -2 42 35
<< ntransistor >>
rect 7 10 9 18
rect 29 10 31 18
rect 10 3 14 5
rect 24 3 28 5
rect 7 16 9 24
rect 29 16 31 24
rect 10 9 14 11
rect 24 9 28 11
<< ptransistor >>
rect 7 37 11 40
rect 27 37 31 40
rect 7 43 11 46
rect 27 43 31 46
<< ndiffusion >>
rect -2 22 7 24
rect 2 18 7 22
rect -2 16 7 18
rect 2 12 7 16
rect -2 10 7 12
rect 9 14 10 18
rect 9 10 14 14
rect 28 14 29 18
rect 24 10 29 14
rect 9 20 10 24
rect 9 16 14 20
rect 28 20 29 24
rect 24 16 29 20
rect 31 22 36 24
rect 31 18 32 22
rect 31 16 36 18
rect 31 12 32 16
rect 31 10 36 12
rect 10 5 14 10
rect 24 5 28 10
rect 10 2 14 3
rect 24 2 28 3
rect 10 11 14 16
rect 24 11 28 16
rect 10 8 14 9
rect 24 8 28 9
<< pdiffusion >>
rect 2 37 7 40
rect 11 37 12 40
rect 26 37 27 40
rect 31 37 32 40
rect 2 43 7 46
rect 11 43 12 46
rect 26 43 27 46
rect 31 43 32 46
<< ndcontact >>
rect -2 12 2 16
rect 10 14 14 18
rect 24 14 28 18
rect 32 12 36 16
rect 10 -2 14 2
rect 24 -2 28 2
rect -2 18 2 22
rect 10 20 14 24
rect 24 20 28 24
rect 32 18 36 22
rect 10 4 14 8
rect 24 4 28 8
<< pdcontact >>
rect -2 36 2 40
rect 12 36 16 40
rect 22 36 26 40
rect 32 36 36 40
rect -2 42 2 46
rect 12 42 16 46
rect 22 42 26 46
rect 32 42 36 46
<< psubstratepcontact >>
rect -2 22 2 26
rect 32 22 36 26
rect -2 28 2 32
rect 32 28 36 32
<< nsubstratencontact >>
rect 32 44 36 48
rect 32 50 36 54
<< polysilicon >>
rect 7 40 11 42
rect 27 40 31 42
rect 7 35 11 37
rect 7 21 9 35
rect 27 34 31 37
rect 15 33 31 34
rect 19 32 31 33
rect 7 20 21 21
rect 7 19 24 20
rect 7 18 9 19
rect 29 18 31 32
rect 7 8 9 10
rect 17 5 21 6
rect 29 8 31 10
rect -2 3 10 5
rect 14 3 24 5
rect 28 3 36 5
rect 7 46 11 48
rect 27 46 31 48
rect 7 41 11 43
rect 7 27 9 41
rect 27 40 31 43
rect 15 39 31 40
rect 19 38 31 39
rect 7 26 21 27
rect 7 25 24 26
rect 7 24 9 25
rect 29 24 31 38
rect 7 14 9 16
rect 17 11 21 12
rect 29 14 31 16
rect -2 9 10 11
rect 14 9 24 11
rect 28 9 36 11
<< polycontact >>
rect 15 29 19 33
rect 21 20 25 24
rect 17 6 21 10
rect 15 35 19 39
rect 21 26 25 30
rect 17 12 21 16
<< metal1 >>
rect -2 44 15 48
rect 19 44 32 48
rect -2 40 2 44
rect 22 40 26 44
rect 32 40 36 44
rect 11 36 12 40
rect 26 36 27 40
rect -2 26 2 29
rect -2 16 2 22
rect 11 18 15 36
rect 23 24 27 36
rect 25 20 27 24
rect 14 14 15 18
rect 23 18 27 20
rect 32 26 36 29
rect 23 14 24 18
rect 32 16 36 22
rect -2 6 17 9
rect 21 6 36 9
rect -2 5 36 6
rect -2 50 15 54
rect 19 50 32 54
rect -2 46 2 50
rect 22 46 26 50
rect 32 46 36 50
rect 11 42 12 46
rect 26 42 27 46
rect -2 32 2 35
rect -2 22 2 28
rect 11 24 15 42
rect 23 30 27 42
rect 25 26 27 30
rect 14 20 15 24
rect 23 24 27 26
rect 32 32 36 35
rect 23 20 24 24
rect 32 22 36 28
rect -2 12 17 15
rect 21 12 36 15
rect -2 11 36 12
<< m2contact >>
rect 15 44 19 48
rect -2 29 2 33
rect 32 29 36 33
rect 6 -2 10 2
rect 20 -2 24 2
rect 15 50 19 54
rect -2 35 2 39
rect 32 35 36 39
rect 6 4 10 8
rect 20 4 24 8
<< metal2 >>
rect -2 33 2 48
rect -2 -2 2 29
rect 6 2 10 48
rect 24 -2 28 48
rect 32 33 36 48
rect 32 -2 36 29
rect -2 39 2 54
rect -2 0 2 35
rect 6 8 10 54
rect 6 0 10 4
rect 24 0 28 54
rect 32 39 36 54
rect 32 0 36 35
<< bb >>
rect 0 0 34 46
rect 0 0 34 52
<< labels >>
rlabel metal2 0 0 0 0 1 gnd
rlabel metal2 34 0 34 0 1 gnd
rlabel m2contact 17 46 17 46 5 vdd
rlabel metal2 8 43 8 43 1 bl
rlabel metal2 26 43 26 43 1 br
rlabel metal1 4 7 4 7 1 wl
rlabel metal2 0 6 0 6 1 gnd
rlabel metal2 34 6 34 6 1 gnd
rlabel m2contact 17 52 17 52 5 vdd
rlabel metal2 8 49 8 49 1 bl
rlabel metal2 26 49 26 49 1 br
rlabel metal1 4 13 4 13 1 wl
<< end >>