Move place function to instance class rather than hierarchy.

This commit is contained in:
Matt Guthaus 2018-08-27 17:25:39 -07:00
parent 8664f7a0b8
commit 6401cbf2a6
28 changed files with 125 additions and 222 deletions

View File

@ -195,6 +195,14 @@ class instance(geometry):
mirror=self.mirror, mirror=self.mirror,
rotate=self.rotate) rotate=self.rotate)
def place(self, offset, mirror="R0", rotate=0):
""" This updates the placement of an instance. """
debug.info(3, "placing instance {}".format(self.name))
# Update the placement of an already added instance
self.offset = offset
self.mirror = mirror
self.rotate = rotate
self.update_boundary()
def get_pin(self,name,index=-1): def get_pin(self,name,index=-1):

View File

@ -119,17 +119,6 @@ class layout(lef.lef):
for pin in pin_list: for pin in pin_list:
pin.rect = [pin.ll() - offset, pin.ur() - offset] pin.rect = [pin.ll() - offset, pin.ur() - offset]
def place_inst(self, name, offset, mirror="R0", rotate=0):
""" This updates the placement of an instance. """
inst = self.get_inst(name)
debug.info(3, "placing instance {}".format(inst))
# Update the placement of an already added instance
inst.offset = offset
inst.mirror = mirror
inst.rotate = rotate
inst.update_boundary()
return inst
def add_inst(self, name, mod, offset=[0,0], mirror="R0",rotate=0): def add_inst(self, name, mod, offset=[0,0], mirror="R0",rotate=0):
"""Adds an instance of a mod to this module""" """Adds an instance of a mod to this module"""
self.insts.append(geometry.instance(name, mod, offset, mirror, rotate)) self.insts.append(geometry.instance(name, mod, offset, mirror, rotate))

View File

@ -278,8 +278,7 @@ class bank(design.design):
def place_bitcell_array(self): def place_bitcell_array(self):
""" Placing Bitcell Array """ """ Placing Bitcell Array """
self.place_inst(name="bitcell_array", self.bitcell_array_inst.place(vector(0,0))
offset=vector(0,0))
def create_precharge_array(self): def create_precharge_array(self):
@ -304,8 +303,7 @@ class bank(design.design):
# The wells must be far enough apart # The wells must be far enough apart
# The enclosure is for the well and the spacing is to the bitcell wells # The enclosure is for the well and the spacing is to the bitcell wells
y_offset = self.bitcell_array.height + self.m2_gap y_offset = self.bitcell_array.height + self.m2_gap
self.place_inst(name=self.precharge_array_inst[k].name, self.precharge_array_inst[k].place(vector(0,y_offset))
offset=vector(0,y_offset))
def create_column_mux_array(self): def create_column_mux_array(self):
""" Creating Column Mux when words_per_row > 1 . """ """ Creating Column Mux when words_per_row > 1 . """
@ -339,8 +337,7 @@ class bank(design.design):
for k in range(self.total_ports): for k in range(self.total_ports):
y_offset = self.column_mux_height y_offset = self.column_mux_height
self.place_inst(name=self.col_mux_array_inst[k].name, self.col_mux_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
offset=vector(0,y_offset).scale(-1,-1))
def create_sense_amp_array(self): def create_sense_amp_array(self):
""" Creating Sense amp """ """ Creating Sense amp """
@ -369,8 +366,7 @@ class bank(design.design):
# FIXME: place for multiport # FIXME: place for multiport
for k in range(self.total_read): for k in range(self.total_read):
y_offset = self.column_mux_height + self.sense_amp_array.height + self.m2_gap y_offset = self.column_mux_height + self.sense_amp_array.height + self.m2_gap
self.place_inst(name=self.sense_amp_array_inst[k].name, self.sense_amp_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
offset=vector(0,y_offset).scale(-1,-1))
def create_write_driver_array(self): def create_write_driver_array(self):
""" Creating Write Driver """ """ Creating Write Driver """
@ -400,8 +396,7 @@ class bank(design.design):
for k in range(self.total_write): for k in range(self.total_write):
y_offset = self.sense_amp_array.height + self.column_mux_height \ y_offset = self.sense_amp_array.height + self.column_mux_height \
+ self.m2_gap + self.write_driver_array.height + self.m2_gap + self.write_driver_array.height
self.place_inst(name=self.write_driver_array_inst[k].name, self.write_driver_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
offset=vector(0,y_offset).scale(-1,-1))
@ -433,8 +428,7 @@ class bank(design.design):
# FIXME: place for multiport # FIXME: place for multiport
for k in range(self.total_ports): for k in range(self.total_ports):
x_offset = -(self.row_decoder.width + self.central_bus_width + self.wordline_driver.width) x_offset = -(self.row_decoder.width + self.central_bus_width + self.wordline_driver.width)
self.place_inst(name=self.row_decoder_inst[k].name, self.row_decoder_inst[k].place(vector(x_offset,0))
offset=vector(x_offset,0))
def create_wordline_driver(self): def create_wordline_driver(self):
@ -462,8 +456,7 @@ class bank(design.design):
for k in range(self.total_ports): for k in range(self.total_ports):
# The wordline driver is placed to the right of the main decoder width. # The wordline driver is placed to the right of the main decoder width.
x_offset = -(self.central_bus_width + self.wordline_driver.width) + self.m2_pitch x_offset = -(self.central_bus_width + self.wordline_driver.width) + self.m2_pitch
self.place_inst(name=self.wordline_driver_inst[k].name, self.wordline_driver_inst[k].place(vector(x_offset,0))
offset=vector(x_offset,0))
def create_column_decoder(self): def create_column_decoder(self):
@ -509,8 +502,7 @@ class bank(design.design):
# Place the col decoder right aligned with row decoder # Place the col decoder right aligned with row decoder
x_off = -(self.central_bus_width + self.wordline_driver.width + self.col_decoder.width) x_off = -(self.central_bus_width + self.wordline_driver.width + self.col_decoder.width)
y_off = -(self.col_decoder.height + 2*drc["well_to_well"]) y_off = -(self.col_decoder.height + 2*drc["well_to_well"])
self.place_inst(name=self.col_decoder_inst[k].name, self.col_decoder_inst[k].place(vector(x_off,y_off))
offset=vector(x_off,y_off))
def create_bank_select(self): def create_bank_select(self):
@ -546,8 +538,7 @@ class bank(design.design):
y_off = self.row_decoder_inst[0].by() y_off = self.row_decoder_inst[0].by()
y_off -= (self.bank_select.height + drc["well_to_well"]) y_off -= (self.bank_select.height + drc["well_to_well"])
self.bank_select_pos = vector(x_off,y_off) self.bank_select_pos = vector(x_off,y_off)
self.place_inst(name=self.bank_select_inst[k].name, self.bank_select_inst[k].place(self.bank_select_pos)
offset=self.bank_select_pos)
def route_vdd_gnd(self): def route_vdd_gnd(self):

View File

@ -131,17 +131,14 @@ class bank_select(design.design):
self.bank_select_inv_position = vector(self.xoffset_bank_sel_inv, 0) self.bank_select_inv_position = vector(self.xoffset_bank_sel_inv, 0)
# bank select inverter (must be made unique if more than one OR) # bank select inverter (must be made unique if more than one OR)
self.bank_sel_inv=self.add_inst(name="bank_sel_inv", self.bank_sel_inv.place(vector(self.xoffset_bank_sel_inv, 0))
mod=self.inv,
offset=[self.xoffset_bank_sel_inv, 0])
self.connect_inst(["bank_sel", "bank_sel_bar", "vdd", "gnd"])
for i in range(self.num_control_lines): for i in range(self.num_control_lines):
logic_inst = self.logic_inst[i]
inv_inst = self.inv_inst[i]
input_name = self.input_control_signals[i] input_name = self.input_control_signals[i]
gated_name = self.control_signals[i]
name_nand = "nand_{}".format(input_name)
name_nor = "nor_{}".format(input_name)
name_inv = "inv_{}".format(input_name)
y_offset = self.inv.height * i y_offset = self.inv.height * i
if i%2: if i%2:
@ -154,20 +151,17 @@ class bank_select(design.design):
# (writes occur on clk low) # (writes occur on clk low)
if input_name in ("clk_buf"): if input_name in ("clk_buf"):
self.place_inst(name=name_nor, logic_inst.place(offset=[self.xoffset_nor, y_offset],
offset=[self.xoffset_nor, y_offset], mirror=mirror)
mirror=mirror)
# the rest are AND (nand2+inv) gates # the rest are AND (nand2+inv) gates
else: else:
self.place_inst(name=name_nand, logic_inst.place(offset=[self.xoffset_nand, y_offset],
offset=[self.xoffset_nand, y_offset], mirror=mirror)
mirror=mirror)
# They all get inverters on the output # They all get inverters on the output
self.place_inst(name=name_inv, inv_inst.place(offset=[self.xoffset_inv, y_offset],
offset=[self.xoffset_inv, y_offset], mirror=mirror)
mirror=mirror)
def route_modules(self): def route_modules(self):

View File

@ -66,9 +66,8 @@ class bitcell_array(design.design):
tempy = yoffset tempy = yoffset
dir_key = "" dir_key = ""
self.place_inst(name=name, self.cell_inst[row,col].place(offset=[xoffset, tempy],
offset=[xoffset, tempy], mirror=dir_key)
mirror=dir_key)
yoffset += self.cell.height yoffset += self.cell.height
xoffset += self.cell.width xoffset += self.cell.width

View File

@ -183,8 +183,7 @@ class control_logic(design.design):
# Add the RBL above the rows # Add the RBL above the rows
# Add to the right of the control rows and routing channel # Add to the right of the control rows and routing channel
self.replica_bitline_offset = vector(0, y_off) self.replica_bitline_offset = vector(0, y_off)
self.place_inst(name="replica_bitline", self.rbl_inst.place(self.replica_bitline_offset)
offset=self.replica_bitline_offset)
def create_clk_row(self): def create_clk_row(self):
@ -198,8 +197,7 @@ class control_logic(design.design):
x_off = self.ctrl_dff_array.width + self.internal_bus_width x_off = self.ctrl_dff_array.width + self.internal_bus_width
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
clkbuf_offset = vector(x_off,y_off) clkbuf_offset = vector(x_off,y_off)
self.place_inst(name="clkbuf", self.clkbuf_inst.place(clkbuf_offset)
offset=clkbuf_offset)
self.row_end_inst.append(self.clkbuf_inst) self.row_end_inst.append(self.clkbuf_inst)
@ -220,15 +218,13 @@ class control_logic(design.design):
self.rbl_in_bar_offset = vector(x_off, y_off) self.rbl_in_bar_offset = vector(x_off, y_off)
self.place_inst(name="nand3_rbl_in_bar", self.rbl_in_bar_inst.place(offset=self.rbl_in_bar_offset,
offset=self.rbl_in_bar_offset, mirror=mirror)
mirror=mirror)
x_off += self.nand2.width x_off += self.nand2.width
self.rbl_in_offset = vector(x_off, y_off) self.rbl_in_offset = vector(x_off, y_off)
self.place_inst(name="inv_rbl_in", self.rbl_in_inst.place(offset=self.rbl_in_offset,
offset=self.rbl_in_offset, mirror=mirror)
mirror=mirror)
self.row_end_inst.append(self.rbl_in_inst) self.row_end_inst.append(self.rbl_in_inst)
def create_sen_row(self): def create_sen_row(self):
@ -253,15 +249,13 @@ class control_logic(design.design):
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
self.pre_s_en_bar_offset = vector(x_off, y_off) self.pre_s_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_s_en_bar", self.pre_s_en_bar_inst.place(offset=self.pre_s_en_bar_offset,
offset=self.pre_s_en_bar_offset, mirror=mirror)
mirror=mirror)
x_off += self.inv2.width x_off += self.inv2.width
self.s_en_offset = vector(x_off, y_off) self.s_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_s_en", self.s_en_inst.place(offset=self.s_en_offset,
offset=self.s_en_offset, mirror=mirror)
mirror=mirror)
self.row_end_inst.append(self.s_en_inst) self.row_end_inst.append(self.s_en_inst)
@ -292,8 +286,7 @@ class control_logic(design.design):
def place_dffs(self): def place_dffs(self):
""" Place the input DFFs (with inverters) """ """ Place the input DFFs (with inverters) """
self.place_inst(name="ctrl_dffs", self.ctrl_dff_inst.place(vector(0,0))
offset=vector(0,0))
def get_offset(self,row): def get_offset(self,row):
@ -333,27 +326,23 @@ class control_logic(design.design):
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
w_en_bar_offset = vector(x_off, y_off) w_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="nand3_w_en_bar", self.w_en_bar_inst.place(offset=w_en_bar_offset,
offset=w_en_bar_offset, mirror=mirror)
mirror=mirror)
x_off += self.nand3.width x_off += self.nand3.width
pre_w_en_offset = vector(x_off, y_off) pre_w_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_w_en", self.pre_w_en_inst.place(offset=pre_w_en_offset,
offset=pre_w_en_offset, mirror=mirror)
mirror=mirror)
x_off += self.inv1.width x_off += self.inv1.width
pre_w_en_bar_offset = vector(x_off, y_off) pre_w_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_w_en_bar", self.pre_w_en_bar_inst.place(offset=pre_w_en_bar_offset,
offset=pre_w_en_bar_offset, mirror=mirror)
mirror=mirror)
x_off += self.inv2.width x_off += self.inv2.width
w_en_offset = vector(x_off, y_off) w_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_w_en2", self.w_en_inst.place(offset=w_en_offset,
offset=w_en_offset, mirror=mirror)
mirror=mirror)
x_off += self.inv8.width x_off += self.inv8.width
self.row_end_inst.append(self.w_en_inst) self.row_end_inst.append(self.w_en_inst)

View File

@ -110,16 +110,16 @@ class delay_chain(design.design):
inv_offset = vector(0, stage_num * self.inv.height) inv_offset = vector(0, stage_num * self.inv.height)
# Add the inverter # Add the inverter
self.place_inst(name="dinv{}".format(stage_num), cur_driver=self.driver_inst_list[stage_num]
offset=inv_offset, cur_driver.place(offset=inv_offset,
mirror=inv_mirror) mirror=inv_mirror)
# Now add the dummy loads to the right # Now add the dummy loads to the right
load_list = self.load_inst_map[cur_driver]
for i in range(fanout_size): for i in range(fanout_size):
inv_offset += vector(self.inv.width,0) inv_offset += vector(self.inv.width,0)
self.place_inst(name="dload_{0}_{1}".format(stage_num,i), load_list[i].place(offset=inv_offset,
offset=inv_offset, mirror=inv_mirror)
mirror=inv_mirror)
def add_route(self, pin1, pin2): def add_route(self, pin1, pin2):

View File

@ -75,9 +75,8 @@ class dff_array(design.design):
else: else:
base = vector(col*self.dff.width,(row+1)*self.dff.height) base = vector(col*self.dff.width,(row+1)*self.dff.height)
mirror = "MX" mirror = "MX"
self.place_inst(name=name, self.dff_insts[row,col].place(offset=base,
offset=base, mirror=mirror)
mirror=mirror)
def get_din_name(self, row, col): def get_din_name(self, row, col):
if self.columns == 1: if self.columns == 1:

View File

@ -79,9 +79,8 @@ class dff_buf_array(design.design):
else: else:
base = vector(col*self.dff.width,(row+1)*self.dff.height) base = vector(col*self.dff.width,(row+1)*self.dff.height)
mirror = "MX" mirror = "MX"
self.place_inst(name=name, self.dff_insts[row,col].place(offset=base,
offset=base, mirror=mirror)
mirror=mirror)
def get_din_name(self, row, col): def get_din_name(self, row, col):
if self.columns == 1: if self.columns == 1:

View File

@ -75,12 +75,10 @@ class dff_inv(design.design):
def place_modules(self): def place_modules(self):
# Place the DFF # Place the DFF
self.place_inst(name="dff_inv_dff", self.dff_inst.place(vector(0,0))
offset=vector(0,0))
# Place the INV1 to the right # Place the INV1 to the right
self.place_inst(name="dff_inv_inv1", self.inv1_inst.place(vector(self.dff_inst.rx(),0))
offset=vector(self.dff_inst.rx(),0))
def add_wires(self): def add_wires(self):

View File

@ -79,9 +79,8 @@ class dff_inv_array(design.design):
else: else:
base = vector(col*self.dff.width,(row+1)*self.dff.height) base = vector(col*self.dff.width,(row+1)*self.dff.height)
mirror = "MX" mirror = "MX"
self.place_inst(name=name, self.dff_insts[row,col].place(offset=base,
offset=base, mirror=mirror)
mirror=mirror)
def get_din_name(self, row, col): def get_din_name(self, row, col):
if self.columns == 1: if self.columns == 1:

View File

@ -303,8 +303,7 @@ class hierarchical_decoder(design.design):
else: else:
base= vector(-self.pre2_4.width, num * self.pre2_4.height) base= vector(-self.pre2_4.width, num * self.pre2_4.height)
self.place_inst(name="pre[{0}]".format(num), self.pre2x4_inst[num].place(base)
offset=base)
def place_pre3x8(self,num): def place_pre3x8(self,num):
@ -316,8 +315,7 @@ class hierarchical_decoder(design.design):
height = self.no_of_pre2x4*self.pre2_4.height + num*self.pre3_8.height height = self.no_of_pre2x4*self.pre2_4.height + num*self.pre3_8.height
offset = vector(-self.pre3_8.width, height) offset = vector(-self.pre3_8.width, height)
self.place_inst(name="pre3x8[{0}]".format(num), self.pre3x8_inst[num].place(offset)
offset=offset)
def create_row_decoder(self): def create_row_decoder(self):
@ -397,7 +395,6 @@ class hierarchical_decoder(design.design):
x_off = self.internal_routing_width + self.nand3.width x_off = self.internal_routing_width + self.nand3.width
for row in range(self.rows): for row in range(self.rows):
name = self.INV_FORMAT.format(row)
if (row % 2 == 0): if (row % 2 == 0):
inv_row_height = self.inv.height * row inv_row_height = self.inv.height * row
mirror = "R0" mirror = "R0"
@ -408,9 +405,8 @@ class hierarchical_decoder(design.design):
y_dir = -1 y_dir = -1
y_off = inv_row_height y_off = inv_row_height
offset = vector(x_off,y_off) offset = vector(x_off,y_off)
self.place_inst(name=name, self.inv_inst[row].place(offset=offset,
offset=offset, mirror=mirror)
mirror=mirror)
def place_row_decoder(self): def place_row_decoder(self):
""" """
@ -449,9 +445,8 @@ class hierarchical_decoder(design.design):
y_dir = -1 y_dir = -1
mirror = "MX" mirror = "MX"
self.place_inst(name=name, self.nand_inst[row].place(offset=[self.internal_routing_width, y_off],
offset=[self.internal_routing_width, y_off], mirror=mirror)
mirror=mirror)

View File

@ -88,7 +88,6 @@ class hierarchical_predecode(design.design):
def create_input_inverters(self): def create_input_inverters(self):
""" Create the input inverters to invert input signals for the decode stage. """ """ Create the input inverters to invert input signals for the decode stage. """
self.in_inst = [] self.in_inst = []
for inv_num in range(self.number_of_inputs): for inv_num in range(self.number_of_inputs):
name = "Xpre_inv[{0}]".format(inv_num) name = "Xpre_inv[{0}]".format(inv_num)
@ -100,9 +99,7 @@ class hierarchical_predecode(design.design):
def place_input_inverters(self): def place_input_inverters(self):
""" Place the input inverters to invert input signals for the decode stage. """ """ Place the input inverters to invert input signals for the decode stage. """
for inv_num in range(self.number_of_inputs): for inv_num in range(self.number_of_inputs):
name = "Xpre_inv[{0}]".format(inv_num)
if (inv_num % 2 == 0): if (inv_num % 2 == 0):
y_off = inv_num * (self.inv.height) y_off = inv_num * (self.inv.height)
mirror = "R0" mirror = "R0"
@ -110,13 +107,11 @@ class hierarchical_predecode(design.design):
y_off = (inv_num + 1) * (self.inv.height) y_off = (inv_num + 1) * (self.inv.height)
mirror="MX" mirror="MX"
offset = vector(self.x_off_inv_1, y_off) offset = vector(self.x_off_inv_1, y_off)
self.place_inst(name=name, self.in_inst[inv_num].place(offset=offset,
offset=offset, mirror=mirror)
mirror=mirror)
def create_output_inverters(self): def create_output_inverters(self):
""" Create inverters for the inverted output decode signals. """ """ Create inverters for the inverted output decode signals. """
self.inv_inst = [] self.inv_inst = []
for inv_num in range(self.number_of_outputs): for inv_num in range(self.number_of_outputs):
name = "Xpre_nand_inv[{}]".format(inv_num) name = "Xpre_nand_inv[{}]".format(inv_num)
@ -129,9 +124,7 @@ class hierarchical_predecode(design.design):
def place_output_inverters(self): def place_output_inverters(self):
""" Place inverters for the inverted output decode signals. """ """ Place inverters for the inverted output decode signals. """
for inv_num in range(self.number_of_outputs): for inv_num in range(self.number_of_outputs):
name = "Xpre_nand_inv[{}]".format(inv_num)
if (inv_num % 2 == 0): if (inv_num % 2 == 0):
y_off = inv_num * self.inv.height y_off = inv_num * self.inv.height
mirror = "R0" mirror = "R0"
@ -139,9 +132,8 @@ class hierarchical_predecode(design.design):
y_off =(inv_num + 1)*self.inv.height y_off =(inv_num + 1)*self.inv.height
mirror = "MX" mirror = "MX"
offset = vector(self.x_off_inv_2, y_off) offset = vector(self.x_off_inv_2, y_off)
self.place_inst(name=name, self.inv_inst[inv_num].place(offset=offset,
offset=offset, mirror=mirror)
mirror=mirror)
def create_nand_array(self,connections): def create_nand_array(self,connections):
""" Create the NAND stage for the decodes """ """ Create the NAND stage for the decodes """
@ -158,7 +150,6 @@ class hierarchical_predecode(design.design):
""" Place the NAND stage for the decodes """ """ Place the NAND stage for the decodes """
for nand_input in range(self.number_of_outputs): for nand_input in range(self.number_of_outputs):
inout = str(self.number_of_inputs)+"x"+str(self.number_of_outputs) inout = str(self.number_of_inputs)+"x"+str(self.number_of_outputs)
name = "Xpre{0}_nand[{1}]".format(inout,nand_input)
if (nand_input % 2 == 0): if (nand_input % 2 == 0):
y_off = nand_input * self.inv.height y_off = nand_input * self.inv.height
mirror = "R0" mirror = "R0"
@ -166,9 +157,8 @@ class hierarchical_predecode(design.design):
y_off = (nand_input + 1) * self.inv.height y_off = (nand_input + 1) * self.inv.height
mirror = "MX" mirror = "MX"
offset = vector(self.x_off_nand, y_off) offset = vector(self.x_off_nand, y_off)
self.place_inst(name=name, self.nand_inst[nand_input].place(offset=offset,
offset=offset, mirror=mirror)
mirror=mirror)
def route(self): def route(self):

View File

@ -67,16 +67,15 @@ class ms_flop_array(design.design):
def place_ms_flop_array(self): def place_ms_flop_array(self):
for i in range(0,self.columns,self.words_per_row): for i in range(0,self.columns,self.words_per_row):
name = "Xdff{0}".format(i) index = int(i/self.words_per_row)
if (i % 2 == 0 or self.words_per_row>1): if (i % 2 == 0 or self.words_per_row>1):
base = vector(i*self.ms.width,0) base = vector(i*self.ms.width,0)
mirror = "R0" mirror = "R0"
else: else:
base = vector((i+1)*self.ms.width,0) base = vector((i+1)*self.ms.width,0)
mirror = "MY" mirror = "MY"
self.place_inst(name=name, self.ms_inst[index].place(offset=base,
offset=base, mirror=mirror)
mirror=mirror)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -92,7 +92,5 @@ class precharge_array(design.design):
def place_insts(self): def place_insts(self):
""" Places precharge array by horizontally tiling the precharge cell""" """ Places precharge array by horizontally tiling the precharge cell"""
for i in range(self.columns): for i in range(self.columns):
name = "pre_column_{0}".format(i)
offset = vector(self.pc_cell.width * i, 0) offset = vector(self.pc_cell.width * i, 0)
inst = self.place_inst(name=name, self.local_insts[i].place(offset)
offset=offset)

View File

@ -132,22 +132,17 @@ class replica_bitline(design.design):
""" Add all of the module instances in the logical netlist """ """ Add all of the module instances in the logical netlist """
# This is the threshold detect inverter on the output of the RBL # This is the threshold detect inverter on the output of the RBL
self.place_inst(name="rbl_inv", self.rbl_inv_inst.place(offset=self.rbl_inv_offset,
offset=self.rbl_inv_offset, rotate=180)
rotate=180)
self.place_inst(name="rbl_access_tx", self.tx_inst.place(self.access_tx_offset)
offset=self.access_tx_offset)
self.place_inst(name="delay_chain", self.dc_inst.place(self.delay_chain_offset)
offset=self.delay_chain_offset)
self.place_inst(name="bitcell", self.rbc_inst.place(offset=self.bitcell_offset,
offset=self.bitcell_offset, mirror="MX")
mirror="MX")
self.place_inst(name="load", self.rbl_inst.place(self.rbl_offset)
offset=self.rbl_offset)

View File

@ -68,11 +68,8 @@ class sense_amp_array(design.design):
amp_spacing = self.amp.width * self.words_per_row amp_spacing = self.amp.width * self.words_per_row
for i in range(0,self.word_size): for i in range(0,self.word_size):
name = "sa_d{0}".format(i)
amp_position = vector(amp_spacing * i, 0) amp_position = vector(amp_spacing * i, 0)
self.place_inst(name=name, self.local_insts[i].place(amp_position)
offset=amp_position)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -87,8 +87,7 @@ class single_level_column_mux_array(design.design):
for col_num in range(self.columns): for col_num in range(self.columns):
name = "XMUX{0}".format(col_num) name = "XMUX{0}".format(col_num)
x_off = vector(col_num * self.mux.width, self.route_height) x_off = vector(col_num * self.mux.width, self.route_height)
self.place_inst(name=name, self.mux_inst[col_num].place(x_off)
offset=x_off)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -63,10 +63,8 @@ class tri_gate_array(design.design):
def place_array(self): def place_array(self):
""" Place the tri gate to the array """ """ Place the tri gate to the array """
for i in range(0,self.columns,self.words_per_row): for i in range(0,self.columns,self.words_per_row):
name = "Xtri_gate{0}".format(i)
base = vector(i*self.tri.width, 0) base = vector(i*self.tri.width, 0)
self.place_inst(name=name, self.tri_inst[i].place(base)
offset=base)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -129,10 +129,6 @@ class wordline_driver(design.design):
for row in range(self.rows): 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)
if (row % 2): if (row % 2):
y_offset = self.inv.height*(row + 1) y_offset = self.inv.height*(row + 1)
inst_mirror = "MX" inst_mirror = "MX"
@ -145,17 +141,14 @@ class wordline_driver(design.design):
inv2_offset=[inv2_xoffset, y_offset] inv2_offset=[inv2_xoffset, y_offset]
# add inv1 based on the info above # add inv1 based on the info above
self.place_inst(name=name_inv1, self.inv1_inst[row].place(offset=inv1_offset,
offset=inv1_offset, mirror=inst_mirror)
mirror=inst_mirror)
# add nand 2 # add nand 2
self.place_inst(name=name_nand, self.nand_inst[row].place(offset=nand2_offset,
offset=nand2_offset, mirror=inst_mirror)
mirror=inst_mirror)
# add inv2 # add inv2
self.place_inst(name=name_inv2, self.inv2_inst[row].place(offset=inv2_offset,
offset=inv2_offset, mirror=inst_mirror)
mirror=inst_mirror)
def route_layout(self): def route_layout(self):

View File

@ -66,11 +66,9 @@ class write_driver_array(design.design):
def place_write_array(self): def place_write_array(self):
for i in range(0,self.columns,self.words_per_row): for i in range(0,self.columns,self.words_per_row):
name = "Xwrite_driver{}".format(i) index = int(i/self.words_per_row)
base = vector(i * self.driver.width,0) base = vector(i * self.driver.width,0)
self.driver_insts[index].place(base)
self.place_inst(name=name,
offset=base)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -198,13 +198,11 @@ class pinv(pgate.pgate):
# place PMOS so it is half a poly spacing down from the top # place PMOS so it is half a poly spacing down from the top
self.pmos_pos = self.pmos.active_offset.scale(1,0) \ self.pmos_pos = self.pmos.active_offset.scale(1,0) \
+ vector(0, self.height-self.pmos.active_height-self.top_bottom_space) + vector(0, self.height-self.pmos.active_height-self.top_bottom_space)
self.place_inst(name="pinv_pmos", self.pmos_inst.place(self.pmos_pos)
offset=self.pmos_pos)
# place NMOS so that it is half a poly spacing up from the bottom # place NMOS so that it is half a poly spacing up from the bottom
self.nmos_pos = self.nmos.active_offset.scale(1,0) + vector(0,self.top_bottom_space) self.nmos_pos = self.nmos.active_offset.scale(1,0) + vector(0,self.top_bottom_space)
self.place_inst(name="pinv_nmos", self.nmos_inst.place(self.nmos_pos)
offset=self.nmos_pos)
# Output position will be in between the PMOS and NMOS drains # Output position will be in between the PMOS and NMOS drains

View File

@ -50,7 +50,7 @@ class pinvbuf(design.design):
self.width = 2*self.inv1.width + self.inv2.width self.width = 2*self.inv1.width + self.inv2.width
self.height = 2*self.inv1.height self.height = 2*self.inv1.height
self.place_insts() self.place_modules()
self.route_wires() self.route_wires()
self.add_layout_pins() self.add_layout_pins()
@ -97,23 +97,19 @@ class pinvbuf(design.design):
mod=self.inv2) mod=self.inv2)
self.connect_inst(["zb_int", "Z", "vdd", "gnd"]) self.connect_inst(["zb_int", "Z", "vdd", "gnd"])
def place_insts(self): def place_modules(self):
# Add INV1 to the right (capacitance shield) # Add INV1 to the right (capacitance shield)
self.place_inst(name="buf_inv1", self.inv1_inst.place(vector(0,0))
offset=vector(0,0))
# Add INV2 to the right # Add INV2 to the right
self.place_inst(name="buf_inv2", self.inv2_inst.place(vector(self.inv1_inst.rx(),0))
offset=vector(self.inv1_inst.rx(),0))
# Add INV3 to the right # Add INV3 to the right
self.place_inst(name="buf_inv3", self.inv3_inst.place(vector(self.inv2_inst.rx(),0))
offset=vector(self.inv2_inst.rx(),0))
# Add INV4 to the bottom # Add INV4 to the bottom
self.place_inst(name="buf_inv4", self.inv4_inst.place(offset=vector(self.inv2_inst.rx(),2*self.inv2.height),
offset=vector(self.inv2_inst.rx(),2*self.inv2.height), mirror = "MX")
mirror = "MX")
def route_wires(self): def route_wires(self):

View File

@ -149,21 +149,17 @@ class pnand2(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x, pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space) self.height - self.pmos.active_height - self.top_bottom_space)
self.place_inst(name="pnand2_pmos1", self.pmos1_inst.place(pmos1_pos)
offset=pmos1_pos)
self.pmos2_pos = pmos1_pos + self.overlap_offset self.pmos2_pos = pmos1_pos + self.overlap_offset
self.place_inst(name="pnand2_pmos2", self.pmos2_inst.place(self.pmos2_pos)
offset=self.pmos2_pos)
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space) nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.place_inst(name="pnand2_nmos1", self.nmos1_inst.place(nmos1_pos)
offset=nmos1_pos)
self.nmos2_pos = nmos1_pos + self.overlap_offset self.nmos2_pos = nmos1_pos + self.overlap_offset
self.place_inst(name="pnand2_nmos2", self.nmos2_inst.place(self.nmos2_pos)
offset=self.nmos2_pos)
# Output position will be in between the PMOS and NMOS # Output position will be in between the PMOS and NMOS
self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height)) self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height))

View File

@ -154,29 +154,23 @@ class pnand3(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x, pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space) self.height - self.pmos.active_height - self.top_bottom_space)
self.pmos1_inst=self.place_inst(name="pnand3_pmos1", self.pmos1_inst.place(pmos1_pos)
offset=pmos1_pos)
pmos2_pos = pmos1_pos + self.overlap_offset pmos2_pos = pmos1_pos + self.overlap_offset
self.pmos2_inst = self.place_inst(name="pnand3_pmos2", self.pmos2_inst.place(pmos2_pos)
offset=pmos2_pos)
self.pmos3_pos = pmos2_pos + self.overlap_offset self.pmos3_pos = pmos2_pos + self.overlap_offset
self.pmos3_inst = self.place_inst(name="pnand3_pmos3", self.pmos3_inst.place(self.pmos3_pos)
offset=self.pmos3_pos)
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space) nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.nmos1_inst=self.place_inst(name="pnand3_nmos1", self.nmos1_inst.place(nmos1_pos)
offset=nmos1_pos)
nmos2_pos = nmos1_pos + self.overlap_offset nmos2_pos = nmos1_pos + self.overlap_offset
self.nmos2_inst=self.place_inst(name="pnand3_nmos2", self.nmos2_inst.place(nmos2_pos)
offset=nmos2_pos)
self.nmos3_pos = nmos2_pos + self.overlap_offset self.nmos3_pos = nmos2_pos + self.overlap_offset
self.nmos3_inst=self.place_inst(name="pnand3_nmos3", self.nmos3_inst.place(self.nmos3_pos)
offset=self.nmos3_pos)
# This should be placed at the top of the NMOS well # This should be placed at the top of the NMOS well
self.well_pos = vector(0,self.nmos1_inst.uy()) self.well_pos = vector(0,self.nmos1_inst.uy())

View File

@ -114,18 +114,15 @@ class precharge(pgate.pgate):
#base = vector(self.width - 2*self.pmos.width + self.overlap_offset.x, 0) #base = vector(self.width - 2*self.pmos.width + self.overlap_offset.x, 0)
self.lower_pmos_position = vector(self.bitcell.get_pin(self.bitcell_bl).lx(), self.lower_pmos_position = vector(self.bitcell.get_pin(self.bitcell_bl).lx(),
self.pmos.active_offset.y) self.pmos.active_offset.y)
self.place_inst(name="lower_pmos", self.lower_pmos_inst.place(self.lower_pmos_position)
offset=self.lower_pmos_position)
# adds the upper pmos(s) to layout # adds the upper pmos(s) to layout
ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width
self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff) self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff)
self.place_inst(name="upper_pmos1", self.upper_pmos1_inst.place(self.upper_pmos1_pos)
offset=self.upper_pmos1_pos)
upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset
self.place_inst(name="upper_pmos2", self.upper_pmos2_inst.place(upper_pmos2_pos)
offset=upper_pmos2_pos)
def connect_poly(self): def connect_poly(self):
"""Connects the upper and lower pmos together""" """Connects the upper and lower pmos together"""

View File

@ -58,14 +58,12 @@ class sram_1bank(sram_base):
# up to the row address DFFs. # up to the row address DFFs.
control_pos = vector(-self.control_logic.width - 2*self.m2_pitch, control_pos = vector(-self.control_logic.width - 2*self.m2_pitch,
self.bank.bank_center.y - self.control_logic.control_logic_center.y) self.bank.bank_center.y - self.control_logic.control_logic_center.y)
self.place_inst(name=self.control_logic_inst.name, self.control_logic_inst.place(control_pos)
offset=control_pos)
# The row address bits are placed above the control logic aligned on the right. # The row address bits are placed above the control logic aligned on the right.
row_addr_pos = vector(self.control_logic_inst.rx() - self.row_addr_dff.width, row_addr_pos = vector(self.control_logic_inst.rx() - self.row_addr_dff.width,
self.control_logic_inst.uy()) self.control_logic_inst.uy())
self.place_inst(name=self.row_addr_dff_inst.name, self.row_addr_dff_inst.place(row_addr_pos)
offset=row_addr_pos)
# This is M2 pitch even though it is on M1 to help stem via spacings on the trunk # This is M2 pitch even though it is on M1 to help stem via spacings on the trunk
data_gap = -self.m2_pitch*(self.word_size+1) data_gap = -self.m2_pitch*(self.word_size+1)
@ -75,8 +73,7 @@ class sram_1bank(sram_base):
if self.col_addr_dff: if self.col_addr_dff:
col_addr_pos = vector(self.bank.bank_center.x - self.col_addr_dff.width - self.bank.central_bus_width, col_addr_pos = vector(self.bank.bank_center.x - self.col_addr_dff.width - self.bank.central_bus_width,
data_gap - self.col_addr_dff.height) data_gap - self.col_addr_dff.height)
self.place_inst(name=self.col_addr_dff_inst.name, self.col_addr_dff_inst.place(col_addr_pos)
offset=col_addr_pos)
# Add the data flops below the bank to the right of the center of bank: # Add the data flops below the bank to the right of the center of bank:
# This relies on the center point of the bank: # This relies on the center point of the bank:
@ -85,8 +82,7 @@ class sram_1bank(sram_base):
# sense amps. # sense amps.
data_pos = vector(self.bank.bank_center.x, data_pos = vector(self.bank.bank_center.x,
data_gap - self.data_dff.height) data_gap - self.data_dff.height)
self.place_inst(self.data_dff.name, self.data_dff_inst.place(data_pos)
offset=data_pos)
# two supply rails are already included in the bank, so just 2 here. # two supply rails are already included in the bank, so just 2 here.
# self.width = self.bank.width + self.control_logic.width + 2*self.supply_rail_pitch # self.width = self.bank.width + self.control_logic.width + 2*self.supply_rail_pitch

View File

@ -355,8 +355,7 @@ class sram_base(design):
else: else:
bank_mirror = "R0" bank_mirror = "R0"
self.place_inst(name=bank_inst.name, bank_inst.place(offset=position,
offset=position,
mirror=bank_mirror, mirror=bank_mirror,
rotate=bank_rotation) rotate=bank_rotation)