All modules have split netlist/layout.

This commit is contained in:
Matt Guthaus 2018-08-27 11:13:34 -07:00
parent 87f539f3a8
commit 0daad338e4
6 changed files with 134 additions and 78 deletions

View File

@ -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"""

View File

@ -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",

View File

@ -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. """

View File

@ -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):

View File

@ -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):

View File

@ -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")