mirror of https://github.com/VLSIDA/OpenRAM.git
singleport bitcell array laying out
This commit is contained in:
parent
9ac894e2ef
commit
5a6c78865d
|
|
@ -41,7 +41,6 @@ from .local_bitcell_array import *
|
|||
from .nand2_dec import *
|
||||
from .nand3_dec import *
|
||||
from .nand4_dec import *
|
||||
from .orig_bitcell_array import *
|
||||
from .pand2 import *
|
||||
from .pand3 import *
|
||||
from .pand4 import *
|
||||
|
|
|
|||
|
|
@ -1,116 +0,0 @@
|
|||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2023 Regents of the University of California and The Board
|
||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
#
|
||||
from openram.sram_factory import factory
|
||||
from openram.tech import drc, spice
|
||||
from openram import OPTS
|
||||
from .bitcell_base_array import bitcell_base_array
|
||||
|
||||
|
||||
class bitcell_array(bitcell_base_array):
|
||||
"""
|
||||
Creates a rows x cols array of memory cells. Assumes bit-lines
|
||||
and word line is connected by abutment.
|
||||
Connects the word lines and bit lines.
|
||||
"""
|
||||
def __init__(self, cols, rows, name, column_offset=0):
|
||||
super().__init__(cols, rows, name, column_offset)
|
||||
|
||||
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 create_layout(self):
|
||||
|
||||
self.place_array("bit_r{0}_c{1}")
|
||||
|
||||
self.add_layout_pins()
|
||||
|
||||
self.add_boundary()
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||
|
||||
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.cell)
|
||||
self.connect_inst(self.get_bitcell_pins(col, row))
|
||||
|
||||
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()
|
||||
bl_swing = OPTS.rbl_delay_percentage
|
||||
freq = spice["default_event_frequency"]
|
||||
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_m1"))
|
||||
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_m1"))
|
||||
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"""
|
||||
# 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
|
||||
|
||||
def graph_exclude_bits(self, targ_row, targ_col):
|
||||
"""Excludes bits in column from being added to graph except target"""
|
||||
# Function is not robust with column mux configurations
|
||||
for row in range(self.row_size):
|
||||
for col in range(self.column_size):
|
||||
if row == targ_row and col == targ_col:
|
||||
continue
|
||||
self.graph_inst_exclude.add(self.cell_inst[row, col])
|
||||
|
||||
def get_cell_name(self, inst_name, row, col):
|
||||
"""Gets the spice name of the target bitcell."""
|
||||
return inst_name + "{}x".format(OPTS.hier_seperator) + self.cell_inst[row, col].name, self.cell_inst[row, col]
|
||||
|
|
@ -9,7 +9,9 @@ from typing import List
|
|||
from typing import Optional
|
||||
from openram.base import design
|
||||
from openram.globals import OPTS
|
||||
from math import ceil
|
||||
from math import ceil, floor
|
||||
from copy import deepcopy
|
||||
|
||||
class pattern():
|
||||
"""
|
||||
This class is used to desribe the internals of a bitcell array. It describes
|
||||
|
|
@ -68,6 +70,8 @@ class pattern():
|
|||
self.initial_y_block = initial_y_block
|
||||
self.final_x_block = final_x_block
|
||||
self.final_y_block = final_y_block
|
||||
self.bits_per_row = ceil(self.num_rows/self.num_cores_x)
|
||||
self.bits_per_col = ceil(self.num_cols/self.num_cores_y)
|
||||
if not OPTS.netlist_only:
|
||||
self.verify_interblock_dimensions()
|
||||
|
||||
|
|
@ -113,23 +117,39 @@ class pattern():
|
|||
|
||||
def connect_block(self, block: block, col: int, row: int):
|
||||
for dr in range(len(block)):
|
||||
row_done = False
|
||||
for dc in range(len(block[0])):
|
||||
if(self.bit_rows.count(self.num_rows) != self.num_cols and self.bit_cols.count(self.bit_cols) != self.num_rows):
|
||||
if(self.bit_rows.count(self.num_rows) <= self.num_cols and self.bit_cols.count(self.bit_cols) <= self.num_rows):
|
||||
inst = block[dr][dc]
|
||||
if(len(self.bit_rows) <= col + dc):
|
||||
self.bit_rows.append(0)
|
||||
if(len(self.bit_cols) <= row + dr):
|
||||
self.bit_cols.append(0)
|
||||
if(self.bit_rows[col+dc] < self.num_rows and self.bit_cols[row+dr] < self.num_cols):
|
||||
if(row_done or self.bit_cols[row+dr] >= self.num_cols):
|
||||
row_done = True
|
||||
continue
|
||||
if((self.bit_rows[col+dc] < self.num_rows) and (self.bit_cols[row+dr] < self.num_cols)):
|
||||
print(row+dr, col+dc)
|
||||
if(inst.is_bitcell):
|
||||
#x_bit = sum(bit > 0 for bit in self.bit_rows)
|
||||
#y_bit = sum(bit > 0 for bit in self.bit_cols)
|
||||
#print(x_bit, y_bit)
|
||||
self.parent_design.cell_inst[self.bit_rows[col+dc], self.bit_cols[row+dr]] = self.parent_design.add_existing_inst(inst,self.name_template.format(row +dr, col+dc))
|
||||
self.parent_design.all_inst[row + dr, col + dc] = self.parent_design.cell_inst[self.bit_rows[col+dc], self.bit_cols[row+dr]]
|
||||
self.parent_design.connect_inst(self.parent_design.get_bitcell_pins(self.bit_rows[col+dc], self.bit_cols[row+dr]))
|
||||
self.bit_rows[col+dc] += 1
|
||||
self.bit_cols[row+dr] += 1
|
||||
self.parent_design.cell_inst[row + dr, col + dc] = self.parent_design.add_existing_inst(inst,self.name_template.format(row +dr, col+dc))
|
||||
self.parent_design.connect_inst(self.parent_design.get_bitcell_pins(row+dr, col+dc))
|
||||
|
||||
else:
|
||||
self.parent_design.all_inst[row + dr, col + dc] = self.parent_design.add_existing_inst(inst,self.name_template.format(row +dr, col+dc))
|
||||
self.parent_design.connect_inst(self.parent_design.get_strap_pins(self.bit_rows[col+dc], self.bit_cols[row+dr]))
|
||||
else:
|
||||
row_done = True
|
||||
|
||||
def connect_array(self) -> None:
|
||||
self.bit_rows = []
|
||||
self.bit_cols = []
|
||||
#debug_array = [[None]*12 for _ in range(6)]
|
||||
row = 0
|
||||
col = 0
|
||||
for i in range(self.num_cores_y):
|
||||
|
|
@ -138,7 +158,7 @@ class pattern():
|
|||
col += len(self.core_block[0])
|
||||
col = 0
|
||||
row += len(self.core_block)
|
||||
|
||||
|
||||
def place_inst(self, inst, offset) -> None:
|
||||
x = offset[0]
|
||||
y = offset[1]
|
||||
|
|
@ -148,55 +168,27 @@ class pattern():
|
|||
x += inst.width
|
||||
inst.place((x, y), inst.mirror, inst.rotate)
|
||||
|
||||
|
||||
|
||||
def place_block(self, block: block, row: int, col: int, place_x: float, place_y: float, bx, by):
|
||||
x_offset = 0
|
||||
y_offset = 0
|
||||
bounding_x = bx
|
||||
bounding_y = by
|
||||
for dr in range(len(block)):
|
||||
for dc in range(len(block[0])):
|
||||
if(self.bit_rows.count(self.num_rows) != self.num_cols and self.bit_cols.count(self.bit_cols) != self.num_rows):
|
||||
if(len(self.bit_rows) <= col + dc):
|
||||
self.bit_rows.append(0)
|
||||
if(len(self.bit_cols) <= row + dr):
|
||||
self.bit_cols.append(0)
|
||||
if(self.bit_rows[col+dc] < self.num_rows and self.bit_cols[row+dr] < self.num_cols):
|
||||
inst = self.parent_design.cell_inst[row + dr, col +dc]
|
||||
if(inst.is_bitcell):
|
||||
self.bit_rows[col+dc] += 1
|
||||
self.bit_cols[row+dr] += 1
|
||||
self.place_inst(inst, (place_x + x_offset, place_y + y_offset))
|
||||
if(place_x + x_offset + inst.width > bounding_x):
|
||||
bounding_x = place_x + x_offset + inst.width
|
||||
if(place_y + y_offset + inst.height > bounding_y):
|
||||
bounding_y = place_y + y_offset + inst.height
|
||||
x_offset += inst.width
|
||||
x_offset = 0
|
||||
y_offset += inst.height
|
||||
return bounding_x, bounding_y
|
||||
|
||||
def place_array(self):
|
||||
self.bit_rows = []
|
||||
self.bit_cols = []
|
||||
|
||||
row = 0
|
||||
col = 0
|
||||
place_x = 0
|
||||
place_y = 0
|
||||
bounding_x = 0
|
||||
bounding_y = 0
|
||||
for i in range(self.num_cores_y):
|
||||
col = 0
|
||||
place_x = 0
|
||||
for j in range(self.num_cores_x):
|
||||
self.parent_design.width, self.parent_design.height= self.place_block(self.core_block, row, col, place_x, place_y, bounding_x, bounding_y)
|
||||
if(self.bit_rows.count(self.num_rows) == self.num_cols and self.bit_cols.count(self.bit_cols) == self.num_rows):
|
||||
return
|
||||
(row_max, col_max) = list(self.parent_design.all_inst.keys())[-1]
|
||||
y = 0
|
||||
for row in range(row_max+1):
|
||||
x = 0
|
||||
for col in range(col_max+1):
|
||||
inst = self.parent_design.all_inst[row, col]
|
||||
self.place_inst(inst, (x, y))
|
||||
x += inst.width
|
||||
y += inst.height
|
||||
|
||||
place_x += self.core_block_width
|
||||
col += len(self.core_block[0])
|
||||
row += len(self.core_block)
|
||||
place_y += self.core_block_height
|
||||
self.parent_design.width = max([x.rx() for x in self.parent_design.insts])
|
||||
self.parent_design.height = max([x.uy() for x in self.parent_design.insts])
|
||||
|
||||
def append_row_to_block(block, row):
|
||||
block.append(row)
|
||||
|
||||
def append_block_under_block(base_block, under_block):
|
||||
base_block = base_block + under_block
|
||||
|
||||
def append_block_right_block(base_block, right_block):
|
||||
for row in base_block:
|
||||
row = row + right_block
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class array_test(openram_test):
|
|||
num_spare_rows = 0
|
||||
num_spare_cols = 0
|
||||
|
||||
a = factory.create(module_type="bitcell_array", cols=8 + num_spare_cols, rows=8 + num_spare_rows)
|
||||
a = factory.create(module_type="bitcell_array", cols=4 + num_spare_cols, rows=4 + num_spare_rows)
|
||||
self.local_check(a)
|
||||
|
||||
openram.end_openram()
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@
|
|||
#
|
||||
|
||||
from openram import debug
|
||||
from openram.modules import bitcell_array
|
||||
from openram.modules import bitcell_array, pattern
|
||||
from openram.sram_factory import factory
|
||||
from openram.base import geometry
|
||||
from openram import OPTS
|
||||
from .sky130_bitcell_base_array import sky130_bitcell_base_array
|
||||
|
||||
from math import ceil
|
||||
|
||||
class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array):
|
||||
"""
|
||||
|
|
@ -38,56 +39,29 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array):
|
|||
""" Add the modules used in this design """
|
||||
# Bitcell for port names only
|
||||
self.cell = factory.create(module_type=OPTS.bitcell, version="opt1")
|
||||
self.cell2 = factory.create(module_type=OPTS.bitcell, version="opt1a")
|
||||
self.cella = factory.create(module_type=OPTS.bitcell, version="opt1a")
|
||||
self.strap = factory.create(module_type="internal", version="wlstrap")
|
||||
self.strap2 = factory.create(module_type="internal", version="wlstrap_p")
|
||||
self.strap3 = factory.create(module_type="internal", version="wlstrapa")
|
||||
self.strap4 = factory.create(module_type="internal", version="wlstrapa_p")
|
||||
self.strap_p = factory.create(module_type="internal", version="wlstrap_p")
|
||||
self.strapa = factory.create(module_type="internal", version="wlstrapa")
|
||||
self.strapa_p = factory.create(module_type="internal", version="wlstrapa_p")
|
||||
|
||||
def create_instances(self):
|
||||
""" Create the module instances used in this design """
|
||||
self.cell_inst = {}
|
||||
self.array_layout = []
|
||||
alternate_bitcell = (self.row_size) % 2
|
||||
for row in range(0, self.row_size):
|
||||
self.all_inst={}
|
||||
self.cell_inst={}
|
||||
bit_row_opt1 = [geometry.instance("00_opt1", mod=self.cell, is_bitcell=True)] \
|
||||
+ [geometry.instance("01_strap", mod=self.strap, is_bitcell=False)]\
|
||||
+ [geometry.instance("02_opt1", mod=self.cell, is_bitcell=True)] \
|
||||
+ [geometry.instance("03_strap_p", mod=self.strap_p, is_bitcell=False)]
|
||||
|
||||
bit_row_opt1a = [geometry.instance("10_opt1a", mod=self.cella, is_bitcell=True)] \
|
||||
+ [geometry.instance("11_strapa", mod=self.strapa, is_bitcell=False)] \
|
||||
+ [geometry.instance("12_opt1a", mod=self.cella, is_bitcell=True)] \
|
||||
+ [geometry.instance("13_strapa_p", mod=self.strapa_p, is_bitcell=False)]
|
||||
|
||||
row_layout = []
|
||||
bit_block = []
|
||||
pattern.append_row_to_block(bit_block, bit_row_opt1)
|
||||
pattern.append_row_to_block(bit_block, bit_row_opt1a)
|
||||
self.pattern = pattern(self, "bitcell_array", bit_block, num_rows=self.row_size, num_cols=self.column_size, num_cores_x=ceil(self.row_size/2), name_template="bit_r{0}_c{1}")
|
||||
self.pattern.connect_array()
|
||||
|
||||
alternate_strap = (self.row_size+1) % 2
|
||||
for col in range(0, self.column_size):
|
||||
if alternate_bitcell == 1:
|
||||
row_layout.append(self.cell)
|
||||
self.cell_inst[row, col]=self.add_inst(name="row_{}_col_{}_bitcell".format(row, col),
|
||||
mod=self.cell)
|
||||
else:
|
||||
row_layout.append(self.cell2)
|
||||
self.cell_inst[row, col]=self.add_inst(name="row_{}_col_{}_bitcell".format(row, col),
|
||||
mod=self.cell2)
|
||||
self.connect_inst(self.get_bitcell_pins(row, col))
|
||||
if col != self.column_size - 1:
|
||||
if alternate_strap:
|
||||
if row % 2:
|
||||
name="row_{}_col_{}_wlstrapa_p".format(row, col)
|
||||
row_layout.append(self.strap4)
|
||||
self.add_inst(name=name, mod=self.strap4)
|
||||
else:
|
||||
name="row_{}_col_{}_wlstrap_p".format(row, col)
|
||||
row_layout.append(self.strap2)
|
||||
self.add_inst(name=name, mod=self.strap2)
|
||||
alternate_strap = 0
|
||||
else:
|
||||
if row % 2:
|
||||
name="row_{}_col_{}_wlstrapa".format(row, col)
|
||||
row_layout.append(self.strap3)
|
||||
self.add_inst(name=name.format(row, col), mod=self.strap3)
|
||||
else:
|
||||
name="row_{}_col_{}_wlstrap".format(row, col)
|
||||
row_layout.append(self.strap)
|
||||
self.add_inst(name=name.format(row, col), mod=self.strap)
|
||||
alternate_strap = 1
|
||||
self.connect_inst(self.get_strap_pins(row, col, name))
|
||||
if alternate_bitcell == 0:
|
||||
alternate_bitcell = 1
|
||||
else:
|
||||
alternate_bitcell = 0
|
||||
self.array_layout.append(row_layout)
|
||||
|
|
|
|||
|
|
@ -23,44 +23,6 @@ class sky130_bitcell_base_array(bitcell_base_array):
|
|||
|
||||
self.cell = factory.create(module_type=OPTS.bitcell, version="opt1")
|
||||
|
||||
def place_array(self, name_template, row_offset=0, col_offset=0):
|
||||
yoffset = 0.0
|
||||
|
||||
for row in range(0, len(self.array_layout)):
|
||||
xoffset = 0.0
|
||||
for col in range(0, len(self.array_layout[row])):
|
||||
self.place_inst = self.insts[(col) + (row) * len(self.array_layout[row])]
|
||||
|
||||
if row % 2 == 0:
|
||||
if col == 0:
|
||||
self.place_inst.place(offset=[xoffset, yoffset + self.cell.height], mirror="MX")
|
||||
elif col % 4 == 0:
|
||||
self.place_inst.place(offset=[xoffset, yoffset + self.cell.height], mirror="MX")
|
||||
elif col % 4 == 3 :
|
||||
self.place_inst.place(offset=[xoffset, yoffset + self.cell.height], mirror="MX")
|
||||
elif col % 4 == 2:
|
||||
self.place_inst.place(offset=[xoffset + self.cell.width, yoffset + self.cell.height], mirror="XY")
|
||||
else:
|
||||
self.place_inst.place(offset=[xoffset, yoffset + self.cell.height], mirror="MX")
|
||||
else:
|
||||
if col == 0:
|
||||
self.place_inst.place(offset=[xoffset, yoffset])
|
||||
elif col % 4 == 0:
|
||||
self.place_inst.place(offset=[xoffset, yoffset])
|
||||
elif col % 4 == 3 :
|
||||
self.place_inst.place(offset=[xoffset, yoffset])
|
||||
elif col % 4 == 2:
|
||||
self.place_inst.place(offset=[xoffset + self.cell.width, yoffset], mirror="MY")
|
||||
# self.place_inst.place(offset=[xoffset, yoffset])
|
||||
else:
|
||||
self.place_inst.place(offset=[xoffset, yoffset])
|
||||
|
||||
xoffset += self.place_inst.width
|
||||
yoffset += self.place_inst.height
|
||||
|
||||
self.width = max([x.rx() for x in self.insts])
|
||||
self.height = max([x.uy() for x in self.insts])
|
||||
|
||||
def get_bitcell_pins(self, row, col, swap = False):
|
||||
"""
|
||||
Creates a list of connections in the bitcell,
|
||||
|
|
@ -139,49 +101,28 @@ class sky130_bitcell_base_array(bitcell_base_array):
|
|||
for pin_name in ["vdd", "gnd"]:
|
||||
self.copy_layout_pin(inst, pin_name)
|
||||
|
||||
if row == 2: #add only 1 label per col
|
||||
# if row == 2: #add only 1 label per col
|
||||
#
|
||||
# if 'VPB' or 'vpb' in self.cell_inst[row, col].mod.pins:
|
||||
# pin = inst.get_pin("vpb")
|
||||
# self.objs.append(geometry.rectangle(layer["nwell"],
|
||||
# pin.ll(),
|
||||
# pin.width(),
|
||||
# pin.height()))
|
||||
# self.objs.append(geometry.label("vdd", layer["nwell"], pin.center()))
|
||||
#
|
||||
# if 'VNB' or 'vnb'in self.cell_inst[row, col].mod.pins:
|
||||
# try:
|
||||
# from openram.tech import layer_override
|
||||
# if layer_override['VNB']:
|
||||
# pin = inst.get_pin("vnb")
|
||||
# self.objs.append(geometry.label("gnd", layer["pwellp"], pin.center()))
|
||||
# self.objs.append(geometry.rectangle(layer["pwellp"],
|
||||
# pin.ll(),
|
||||
# pin.width(),
|
||||
# pin.height()))
|
||||
# except:
|
||||
# pin = inst.get_pin("vnb")
|
||||
# self.add_label("vdd", pin.layer, pin.center())
|
||||
|
||||
if 'VPB' or 'vpb' in self.cell_inst[row, col].mod.pins:
|
||||
pin = inst.get_pin("vpb")
|
||||
self.objs.append(geometry.rectangle(layer["nwell"],
|
||||
pin.ll(),
|
||||
pin.width(),
|
||||
pin.height()))
|
||||
self.objs.append(geometry.label("vdd", layer["nwell"], pin.center()))
|
||||
|
||||
if 'VNB' or 'vnb'in self.cell_inst[row, col].mod.pins:
|
||||
try:
|
||||
from openram.tech import layer_override
|
||||
if layer_override['VNB']:
|
||||
pin = inst.get_pin("vnb")
|
||||
self.objs.append(geometry.label("gnd", layer["pwellp"], pin.center()))
|
||||
self.objs.append(geometry.rectangle(layer["pwellp"],
|
||||
pin.ll(),
|
||||
pin.width(),
|
||||
pin.height()))
|
||||
except:
|
||||
pin = inst.get_pin("vnb")
|
||||
self.add_label("vdd", pin.layer, pin.center())
|
||||
|
||||
def add_bitline_pins(self):
|
||||
bitline_names = self.cell.get_all_bitline_names()
|
||||
for col in range(self.column_size):
|
||||
for port in self.all_ports:
|
||||
bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port])
|
||||
text = "bl_{0}_{1}".format(port, col)
|
||||
#if "Y" in self.cell_inst[0, col].mirror:
|
||||
# text = text.replace("bl", "br")
|
||||
self.add_layout_pin(text=text,
|
||||
layer=bl_pin.layer,
|
||||
offset=bl_pin.ll().scale(1, 0),
|
||||
width=bl_pin.width(),
|
||||
height=self.height)
|
||||
br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1])
|
||||
text = "br_{0}_{1}".format(port, col)
|
||||
#if "Y" in self.cell_inst[0, col].mirror:
|
||||
# text = text.replace("br", "bl")
|
||||
self.add_layout_pin(text=text,
|
||||
layer=br_pin.layer,
|
||||
offset=br_pin.ll().scale(1, 0),
|
||||
width=br_pin.width(),
|
||||
height=self.height)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue