mirror of https://github.com/VLSIDA/OpenRAM.git
All modules have split netlist/layout.
This commit is contained in:
parent
87f539f3a8
commit
0daad338e4
|
|
@ -127,6 +127,7 @@ class layout(lef.lef):
|
|||
inst.mirror = mirror
|
||||
inst.rotate = rotate
|
||||
inst.update_boundary()
|
||||
return inst
|
||||
|
||||
def add_inst(self, name, mod, offset=[0,0], mirror="R0",rotate=0):
|
||||
"""Adds an instance of a mod to this module"""
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class sense_amp_array(design.design):
|
|||
self.height = self.amp.height
|
||||
self.width = self.amp.width * self.word_size * self.words_per_row
|
||||
|
||||
self.add_pins()
|
||||
self.create_netlist()
|
||||
self.create_layout()
|
||||
self.DRC_LVS()
|
||||
|
||||
|
|
@ -42,36 +42,42 @@ class sense_amp_array(design.design):
|
|||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.create_sense_amp_array()
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
self.add_sense_amp()
|
||||
self.connect_rails()
|
||||
self.place_sense_amp_array()
|
||||
self.add_layout_pins()
|
||||
self.route_rails()
|
||||
|
||||
|
||||
def add_sense_amp(self):
|
||||
|
||||
bl_pin = self.amp.get_pin("bl")
|
||||
br_pin = self.amp.get_pin("br")
|
||||
dout_pin = self.amp.get_pin("dout")
|
||||
|
||||
amp_spacing = self.amp.width * self.words_per_row
|
||||
def create_sense_amp_array(self):
|
||||
self.local_insts = []
|
||||
for i in range(0,self.word_size):
|
||||
|
||||
name = "sa_d{0}".format(i)
|
||||
amp_position = vector(amp_spacing * i, 0)
|
||||
|
||||
bl_offset = amp_position + bl_pin.ll().scale(1,0)
|
||||
br_offset = amp_position + br_pin.ll().scale(1,0)
|
||||
dout_offset = amp_position + dout_pin.ll()
|
||||
|
||||
inst = self.add_inst(name=name,
|
||||
mod=self.amp,
|
||||
offset=amp_position)
|
||||
self.local_insts.append(self.add_inst(name=name,
|
||||
mod=self.amp))
|
||||
self.connect_inst(["bl[{0}]".format(i),
|
||||
"br[{0}]".format(i),
|
||||
"data[{0}]".format(i),
|
||||
"en", "vdd", "gnd"])
|
||||
|
||||
def place_sense_amp_array(self):
|
||||
|
||||
amp_spacing = self.amp.width * self.words_per_row
|
||||
for i in range(0,self.word_size):
|
||||
|
||||
name = "sa_d{0}".format(i)
|
||||
amp_position = vector(amp_spacing * i, 0)
|
||||
self.place_inst(name=name,
|
||||
offset=amp_position)
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
for i in range(len(self.local_insts)):
|
||||
inst = self.local_insts[i]
|
||||
|
||||
gnd_pos = inst.get_pin("gnd").center()
|
||||
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||
|
|
@ -79,33 +85,36 @@ class sense_amp_array(design.design):
|
|||
self.add_layout_pin_rect_center(text="gnd",
|
||||
layer="metal3",
|
||||
offset=gnd_pos)
|
||||
|
||||
vdd_pos = inst.get_pin("vdd").center()
|
||||
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||
offset=vdd_pos)
|
||||
self.add_layout_pin_rect_center(text="vdd",
|
||||
layer="metal3",
|
||||
offset=vdd_pos)
|
||||
|
||||
bl_pin = inst.get_pin("bl")
|
||||
br_pin = inst.get_pin("br")
|
||||
dout_pin = inst.get_pin("dout")
|
||||
|
||||
self.add_layout_pin(text="bl[{0}]".format(i),
|
||||
layer="metal2",
|
||||
offset=bl_offset,
|
||||
offset=bl_pin.ll(),
|
||||
width=bl_pin.width(),
|
||||
height=bl_pin.height())
|
||||
self.add_layout_pin(text="br[{0}]".format(i),
|
||||
layer="metal2",
|
||||
offset=br_offset,
|
||||
offset=br_pin.ll(),
|
||||
width=br_pin.width(),
|
||||
height=br_pin.height())
|
||||
|
||||
self.add_layout_pin(text="data[{0}]".format(i),
|
||||
layer="metal2",
|
||||
offset=dout_offset,
|
||||
offset=dout_pin.ll(),
|
||||
width=dout_pin.width(),
|
||||
height=dout_pin.height())
|
||||
|
||||
|
||||
def connect_rails(self):
|
||||
|
||||
def route_rails(self):
|
||||
# add sclk rail across entire array
|
||||
sclk_offset = self.amp.get_pin("en").ll().scale(0,1)
|
||||
self.add_layout_pin(text="en",
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@ class single_level_column_mux_array(design.design):
|
|||
self.columns = columns
|
||||
self.word_size = word_size
|
||||
self.words_per_row = int(self.columns / self.word_size)
|
||||
self.add_pins()
|
||||
self.create_netlist()
|
||||
self.create_layout()
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
for i in range(self.columns):
|
||||
|
|
@ -35,10 +34,14 @@ class single_level_column_mux_array(design.design):
|
|||
self.add_pin("br_out[{}]".format(i))
|
||||
self.add_pin("gnd")
|
||||
|
||||
def create_layout(self):
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_modules()
|
||||
self.setup_layout_constants()
|
||||
self.create_array()
|
||||
|
||||
def create_layout(self):
|
||||
self.setup_layout_constants()
|
||||
self.place_array()
|
||||
self.add_routing()
|
||||
# Find the highest shapes to determine height before adding well
|
||||
highest = self.find_highest_coords()
|
||||
|
|
@ -46,6 +49,7 @@ class single_level_column_mux_array(design.design):
|
|||
self.add_layout_pins()
|
||||
self.add_enclosure(self.mux_inst, "pwell")
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
|
|
@ -65,14 +69,11 @@ class single_level_column_mux_array(design.design):
|
|||
|
||||
def create_array(self):
|
||||
self.mux_inst = []
|
||||
|
||||
# For every column, add a pass gate
|
||||
for col_num in range(self.columns):
|
||||
name = "XMUX{0}".format(col_num)
|
||||
x_off = vector(col_num * self.mux.width, self.route_height)
|
||||
self.mux_inst.append(self.add_inst(name=name,
|
||||
mod=self.mux,
|
||||
offset=x_off))
|
||||
mod=self.mux))
|
||||
|
||||
self.connect_inst(["bl[{}]".format(col_num),
|
||||
"br[{}]".format(col_num),
|
||||
|
|
@ -81,6 +82,14 @@ class single_level_column_mux_array(design.design):
|
|||
"sel[{}]".format(col_num % self.words_per_row),
|
||||
"gnd"])
|
||||
|
||||
def place_array(self):
|
||||
# For every column, add a pass gate
|
||||
for col_num in range(self.columns):
|
||||
name = "XMUX{0}".format(col_num)
|
||||
x_off = vector(col_num * self.mux.width, self.route_height)
|
||||
self.place_inst(name=name,
|
||||
offset=x_off)
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
""" Add the pins after we determine the height. """
|
||||
|
|
|
|||
|
|
@ -27,14 +27,17 @@ class tri_gate_array(design.design):
|
|||
self.width = (self.columns / self.words_per_row) * self.tri.width
|
||||
self.height = self.tri.height
|
||||
|
||||
self.create_netlist()
|
||||
self.create_layout()
|
||||
self.DRC_LVS()
|
||||
|
||||
def create_layout(self):
|
||||
"""generate layout """
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.create_array()
|
||||
|
||||
def create_layout(self):
|
||||
self.place_array()
|
||||
self.add_layout_pins()
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
"""create the name of pins depend on the word size"""
|
||||
|
|
@ -50,15 +53,21 @@ class tri_gate_array(design.design):
|
|||
self.tri_inst = {}
|
||||
for i in range(0,self.columns,self.words_per_row):
|
||||
name = "Xtri_gate{0}".format(i)
|
||||
base = vector(i*self.tri.width, 0)
|
||||
self.tri_inst[i]=self.add_inst(name=name,
|
||||
mod=self.tri,
|
||||
offset=base)
|
||||
mod=self.tri)
|
||||
index = int(i/self.words_per_row)
|
||||
self.connect_inst(["in[{0}]".format(index),
|
||||
"out[{0}]".format(index),
|
||||
"en", "en_bar", "vdd", "gnd"])
|
||||
|
||||
def place_array(self):
|
||||
""" Place the tri gate to the array """
|
||||
for i in range(0,self.columns,self.words_per_row):
|
||||
name = "Xtri_gate{0}".format(i)
|
||||
base = vector(i*self.tri.width, 0)
|
||||
self.place_inst(name=name,
|
||||
offset=base)
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ class wordline_driver(design.design):
|
|||
design.design.__init__(self, "wordline_driver")
|
||||
|
||||
self.rows = rows
|
||||
self.add_pins()
|
||||
self.design_layout()
|
||||
self.create_netlist()
|
||||
self.create_layout()
|
||||
self.offset_all_coordinates()
|
||||
self.DRC_LVS()
|
||||
|
||||
|
|
@ -36,14 +36,18 @@ class wordline_driver(design.design):
|
|||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def design_layout(self):
|
||||
self.create_modules()
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_modules()
|
||||
self.create_drivers()
|
||||
|
||||
def create_layout(self):
|
||||
self.place_drivers()
|
||||
self.route_layout()
|
||||
self.route_vdd_gnd()
|
||||
|
||||
|
||||
def create_modules(self):
|
||||
def add_modules(self):
|
||||
self.inv = pinv()
|
||||
self.add_mod(self.inv)
|
||||
|
||||
|
|
@ -84,7 +88,37 @@ class wordline_driver(design.design):
|
|||
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
def create_drivers(self):
|
||||
self.inv1_inst = []
|
||||
self.nand_inst = []
|
||||
self.inv2_inst = []
|
||||
for row in range(self.rows):
|
||||
name_inv1 = "wl_driver_inv_en{}".format(row)
|
||||
name_nand = "wl_driver_nand{}".format(row)
|
||||
name_inv2 = "wl_driver_inv{}".format(row)
|
||||
|
||||
# add inv1 based on the info above
|
||||
self.inv1_inst.append(self.add_inst(name=name_inv1,
|
||||
mod=self.inv_no_output))
|
||||
self.connect_inst(["en",
|
||||
"en_bar[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
# add nand 2
|
||||
self.nand_inst.append(self.add_inst(name=name_nand,
|
||||
mod=self.nand2))
|
||||
self.connect_inst(["en_bar[{0}]".format(row),
|
||||
"in[{0}]".format(row),
|
||||
"wl_bar[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
# add inv2
|
||||
self.inv2_inst.append(self.add_inst(name=name_inv2,
|
||||
mod=self.inv))
|
||||
self.connect_inst(["wl_bar[{0}]".format(row),
|
||||
"wl[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
|
||||
|
||||
def place_drivers(self):
|
||||
inv1_xoffset = 2*self.m1_width + 5*self.m1_space
|
||||
nand2_xoffset = inv1_xoffset + self.inv.width
|
||||
inv2_xoffset = nand2_xoffset + self.nand2.width
|
||||
|
|
@ -93,9 +127,6 @@ class wordline_driver(design.design):
|
|||
self.height = self.inv.height * self.rows
|
||||
|
||||
|
||||
self.inv1_inst = []
|
||||
self.nand_inst = []
|
||||
self.inv2_inst = []
|
||||
for row in range(self.rows):
|
||||
name_inv1 = "wl_driver_inv_en{}".format(row)
|
||||
name_nand = "wl_driver_nand{}".format(row)
|
||||
|
|
@ -113,30 +144,17 @@ class wordline_driver(design.design):
|
|||
inv2_offset=[inv2_xoffset, y_offset]
|
||||
|
||||
# add inv1 based on the info above
|
||||
self.inv1_inst.append(self.add_inst(name=name_inv1,
|
||||
mod=self.inv_no_output,
|
||||
offset=inv1_offset,
|
||||
mirror=inst_mirror))
|
||||
self.connect_inst(["en",
|
||||
"en_bar[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
self.place_inst(name=name_inv1,
|
||||
offset=inv1_offset,
|
||||
mirror=inst_mirror)
|
||||
# add nand 2
|
||||
self.nand_inst.append(self.add_inst(name=name_nand,
|
||||
mod=self.nand2,
|
||||
offset=nand2_offset,
|
||||
mirror=inst_mirror))
|
||||
self.connect_inst(["en_bar[{0}]".format(row),
|
||||
"in[{0}]".format(row),
|
||||
"wl_bar[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
self.place_inst(name=name_nand,
|
||||
offset=nand2_offset,
|
||||
mirror=inst_mirror)
|
||||
# add inv2
|
||||
self.inv2_inst.append(self.add_inst(name=name_inv2,
|
||||
mod=self.inv,
|
||||
offset=inv2_offset,
|
||||
mirror=inst_mirror))
|
||||
self.connect_inst(["wl_bar[{0}]".format(row),
|
||||
"wl[{0}]".format(row),
|
||||
"vdd", "gnd"])
|
||||
self.place_inst(name=name_inv2,
|
||||
offset=inv2_offset,
|
||||
mirror=inst_mirror)
|
||||
|
||||
|
||||
def route_layout(self):
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ class write_driver_array(design.design):
|
|||
self.width = self.columns * self.driver.width
|
||||
self.height = self.height = self.driver.height
|
||||
|
||||
self.add_pins()
|
||||
self.create_netlist()
|
||||
self.create_layout()
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
for i in range(self.word_size):
|
||||
|
|
@ -42,20 +41,22 @@ class write_driver_array(design.design):
|
|||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def create_layout(self):
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.create_write_array()
|
||||
|
||||
def create_layout(self):
|
||||
self.place_write_array()
|
||||
self.add_layout_pins()
|
||||
self.DRC_LVS()
|
||||
|
||||
def create_write_array(self):
|
||||
self.driver_insts = {}
|
||||
for i in range(0,self.columns,self.words_per_row):
|
||||
name = "Xwrite_driver{}".format(i)
|
||||
base = vector(i * self.driver.width,0)
|
||||
|
||||
index = int(i/self.words_per_row)
|
||||
self.driver_insts[index]=self.add_inst(name=name,
|
||||
mod=self.driver,
|
||||
offset=base)
|
||||
mod=self.driver)
|
||||
|
||||
self.connect_inst(["data[{0}]".format(index),
|
||||
"bl[{0}]".format(index),
|
||||
|
|
@ -63,6 +64,15 @@ class write_driver_array(design.design):
|
|||
"en", "vdd", "gnd"])
|
||||
|
||||
|
||||
def place_write_array(self):
|
||||
for i in range(0,self.columns,self.words_per_row):
|
||||
name = "Xwrite_driver{}".format(i)
|
||||
base = vector(i * self.driver.width,0)
|
||||
|
||||
self.place_inst(name=name,
|
||||
offset=base)
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
for i in range(self.word_size):
|
||||
din_pin = self.driver_insts[i].get_pin("din")
|
||||
|
|
|
|||
Loading…
Reference in New Issue