mirror of https://github.com/VLSIDA/OpenRAM.git
137 lines
5.2 KiB
Python
137 lines
5.2 KiB
Python
import debug
|
|
from tech import drc
|
|
import design
|
|
from vector import vector
|
|
from globals import OPTS
|
|
|
|
class tri_gate_array(design.design):
|
|
"""
|
|
Dynamically generated tri gate array of all bitlines. words_per_row
|
|
"""
|
|
|
|
def __init__(self, columns, word_size):
|
|
"""Intial function of tri gate array """
|
|
design.design.__init__(self, "tri_gate_array")
|
|
debug.info(1, "Creating {0}".format(self.name))
|
|
|
|
c = reload(__import__(OPTS.config.tri_gate))
|
|
self.mod_tri_gate = getattr(c, OPTS.config.tri_gate)
|
|
self.tri_gate_chars = self.mod_tri_gate.chars
|
|
|
|
self.columns = columns
|
|
self.word_size = word_size
|
|
self.create_layout()
|
|
self.DRC_LVS()
|
|
|
|
def create_layout(self):
|
|
"""generate layout """
|
|
self.add_modules()
|
|
self.setup_layout_constants()
|
|
self.add_pins()
|
|
self.create_write_array()
|
|
self.add_metal_rails()
|
|
self.add_labels()
|
|
|
|
def add_pins(self):
|
|
"""create the name of pins depend on the word size"""
|
|
for i in range(self.word_size):
|
|
self.add_pin("tri_in[{0}]".format(i))
|
|
for i in range(self.word_size):
|
|
self.add_pin("DATA[{0}]".format(i))
|
|
for pin in ["en", "en_bar", "vdd", "gnd"]:
|
|
self.add_pin(pin)
|
|
|
|
def setup_layout_constants(self):
|
|
"""caculate the size of tri gate array"""
|
|
self.words_per_row = self.columns / self.word_size
|
|
self.width = (self.columns / self.words_per_row) * self.tri.width
|
|
self.height = self.tri.height
|
|
self.tri_gate_positions = []
|
|
self.vdd_positions = []
|
|
self.gnd_positions = []
|
|
self.tri_in_positions = []
|
|
self.DATA_positions = []
|
|
|
|
def add_modules(self):
|
|
"""instantiation of a tri gate"""
|
|
self.tri = self.mod_tri_gate("tri_gate")
|
|
self.add_mod(self.tri)
|
|
|
|
def create_write_array(self):
|
|
"""add tri gate to the array """
|
|
for i in range(self.word_size):
|
|
mirror = "R0"
|
|
if (i % 2 == 0):
|
|
name = "Xtri_gate{0}".format(i)
|
|
x_off = i * self.tri.width * self.words_per_row
|
|
else:
|
|
name = "Xtri_gate{0}".format(i)
|
|
if (self.words_per_row == 1):
|
|
x_off = (i + 1) * self.tri.width * self.words_per_row
|
|
mirror = "MY"
|
|
else:
|
|
x_off = i * self.tri.width * self.words_per_row
|
|
self.add_inst(name=name,
|
|
mod=self.tri,
|
|
offset=[x_off, 0],
|
|
mirror = mirror)
|
|
self.connect_inst(["tri_in[{0}]".format(i),
|
|
"DATA[{0}]".format(i),
|
|
"en", "en_bar", "vdd", "gnd"])
|
|
|
|
def add_metal_rails(self):
|
|
"""Connect en en_bar and vdd together """
|
|
correct = vector(0, 0.5 * drc["minwidth_metal1"])
|
|
width = (self.tri.width * self.columns
|
|
- (self.words_per_row - 1) * self.tri.width)
|
|
self.add_rect(layer="metal1",
|
|
offset=(self.tri_gate_chars["en"] - correct).scale(0, 1),
|
|
width=width,
|
|
height=drc['minwidth_metal1'])
|
|
self.add_rect(layer="metal1",
|
|
offset=(self.tri_gate_chars["en_bar"] - correct).scale(0, 1),
|
|
width=width,
|
|
height=drc['minwidth_metal1'])
|
|
self.add_rect(layer="metal1",
|
|
offset=(self.tri_gate_chars["vdd"] - correct).scale(0, 1),
|
|
width=width,
|
|
height=drc['minwidth_metal1'])
|
|
|
|
def add_labels(self):
|
|
"""add label for pins"""
|
|
for i in range(self.word_size):
|
|
if (i % 2 == 0 or self.words_per_row > 1):
|
|
x_off = i * self.tri.width * self.words_per_row
|
|
dir_vector = vector(1,1)
|
|
else:
|
|
x_off = (i + 1) * self.tri.width * self.words_per_row
|
|
dir_vector = vector(-1,1)
|
|
|
|
pin_offset={}
|
|
for pin in ["en", "en_bar", "vdd", "gnd", "in", "out"]:
|
|
pin_offset[pin] = vector(x_off, 0) + dir_vector.scale(self.tri_gate_chars[pin])
|
|
|
|
for pin in ["en", "en_bar", "vdd"]:
|
|
self.add_label(text=pin,
|
|
layer="metal1",
|
|
offset=pin_offset[pin])
|
|
self.add_label(text="gnd",
|
|
layer="metal2",
|
|
offset=pin_offset["gnd"])
|
|
self.add_label(text="tri_in[{0}]".format(i),
|
|
layer="metal2",
|
|
offset=pin_offset["in"])
|
|
self.add_label(text="DATA[{0}]".format(i),
|
|
layer="metal2",
|
|
offset=pin_offset["out"])
|
|
|
|
self.vdd_positions.append(pin_offset["vdd"])
|
|
self.gnd_positions.append(pin_offset["gnd"])
|
|
self.tri_in_positions.append(pin_offset["in"])
|
|
self.DATA_positions.append(pin_offset["out"])
|
|
|
|
self.add_label(text="tri gate",
|
|
layer="text",
|
|
offset=[self.width / 2.0,
|
|
self.height / 2.0])
|