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

View File

@ -119,17 +119,6 @@ class layout(lef.lef):
for pin in pin_list:
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):
"""Adds an instance of a mod to this module"""
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):
""" Placing Bitcell Array """
self.place_inst(name="bitcell_array",
offset=vector(0,0))
self.bitcell_array_inst.place(vector(0,0))
def create_precharge_array(self):
@ -304,8 +303,7 @@ class bank(design.design):
# The wells must be far enough apart
# The enclosure is for the well and the spacing is to the bitcell wells
y_offset = self.bitcell_array.height + self.m2_gap
self.place_inst(name=self.precharge_array_inst[k].name,
offset=vector(0,y_offset))
self.precharge_array_inst[k].place(vector(0,y_offset))
def create_column_mux_array(self):
""" Creating Column Mux when words_per_row > 1 . """
@ -339,8 +337,7 @@ class bank(design.design):
for k in range(self.total_ports):
y_offset = self.column_mux_height
self.place_inst(name=self.col_mux_array_inst[k].name,
offset=vector(0,y_offset).scale(-1,-1))
self.col_mux_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
def create_sense_amp_array(self):
""" Creating Sense amp """
@ -369,8 +366,7 @@ class bank(design.design):
# FIXME: place for multiport
for k in range(self.total_read):
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,
offset=vector(0,y_offset).scale(-1,-1))
self.sense_amp_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
def create_write_driver_array(self):
""" Creating Write Driver """
@ -400,8 +396,7 @@ class bank(design.design):
for k in range(self.total_write):
y_offset = self.sense_amp_array.height + self.column_mux_height \
+ self.m2_gap + self.write_driver_array.height
self.place_inst(name=self.write_driver_array_inst[k].name,
offset=vector(0,y_offset).scale(-1,-1))
self.write_driver_array_inst[k].place(vector(0,y_offset).scale(-1,-1))
@ -433,8 +428,7 @@ class bank(design.design):
# FIXME: place for multiport
for k in range(self.total_ports):
x_offset = -(self.row_decoder.width + self.central_bus_width + self.wordline_driver.width)
self.place_inst(name=self.row_decoder_inst[k].name,
offset=vector(x_offset,0))
self.row_decoder_inst[k].place(vector(x_offset,0))
def create_wordline_driver(self):
@ -462,8 +456,7 @@ class bank(design.design):
for k in range(self.total_ports):
# 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
self.place_inst(name=self.wordline_driver_inst[k].name,
offset=vector(x_offset,0))
self.wordline_driver_inst[k].place(vector(x_offset,0))
def create_column_decoder(self):
@ -509,8 +502,7 @@ class bank(design.design):
# Place the col decoder right aligned with row decoder
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"])
self.place_inst(name=self.col_decoder_inst[k].name,
offset=vector(x_off,y_off))
self.col_decoder_inst[k].place(vector(x_off,y_off))
def create_bank_select(self):
@ -546,8 +538,7 @@ class bank(design.design):
y_off = self.row_decoder_inst[0].by()
y_off -= (self.bank_select.height + drc["well_to_well"])
self.bank_select_pos = vector(x_off,y_off)
self.place_inst(name=self.bank_select_inst[k].name,
offset=self.bank_select_pos)
self.bank_select_inst[k].place(self.bank_select_pos)
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)
# bank select inverter (must be made unique if more than one OR)
self.bank_sel_inv=self.add_inst(name="bank_sel_inv",
mod=self.inv,
offset=[self.xoffset_bank_sel_inv, 0])
self.connect_inst(["bank_sel", "bank_sel_bar", "vdd", "gnd"])
self.bank_sel_inv.place(vector(self.xoffset_bank_sel_inv, 0))
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]
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
if i%2:
@ -154,20 +151,17 @@ class bank_select(design.design):
# (writes occur on clk low)
if input_name in ("clk_buf"):
self.place_inst(name=name_nor,
offset=[self.xoffset_nor, y_offset],
mirror=mirror)
logic_inst.place(offset=[self.xoffset_nor, y_offset],
mirror=mirror)
# the rest are AND (nand2+inv) gates
else:
self.place_inst(name=name_nand,
offset=[self.xoffset_nand, y_offset],
mirror=mirror)
logic_inst.place(offset=[self.xoffset_nand, y_offset],
mirror=mirror)
# They all get inverters on the output
self.place_inst(name=name_inv,
offset=[self.xoffset_inv, y_offset],
mirror=mirror)
inv_inst.place(offset=[self.xoffset_inv, y_offset],
mirror=mirror)
def route_modules(self):

View File

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

View File

@ -183,8 +183,7 @@ class control_logic(design.design):
# Add the RBL above the rows
# Add to the right of the control rows and routing channel
self.replica_bitline_offset = vector(0, y_off)
self.place_inst(name="replica_bitline",
offset=self.replica_bitline_offset)
self.rbl_inst.place(self.replica_bitline_offset)
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
(y_off,mirror)=self.get_offset(row)
clkbuf_offset = vector(x_off,y_off)
self.place_inst(name="clkbuf",
offset=clkbuf_offset)
self.clkbuf_inst.place(clkbuf_offset)
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.place_inst(name="nand3_rbl_in_bar",
offset=self.rbl_in_bar_offset,
mirror=mirror)
self.rbl_in_bar_inst.place(offset=self.rbl_in_bar_offset,
mirror=mirror)
x_off += self.nand2.width
self.rbl_in_offset = vector(x_off, y_off)
self.place_inst(name="inv_rbl_in",
offset=self.rbl_in_offset,
mirror=mirror)
self.rbl_in_inst.place(offset=self.rbl_in_offset,
mirror=mirror)
self.row_end_inst.append(self.rbl_in_inst)
def create_sen_row(self):
@ -253,15 +249,13 @@ class control_logic(design.design):
(y_off,mirror)=self.get_offset(row)
self.pre_s_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_s_en_bar",
offset=self.pre_s_en_bar_offset,
mirror=mirror)
self.pre_s_en_bar_inst.place(offset=self.pre_s_en_bar_offset,
mirror=mirror)
x_off += self.inv2.width
self.s_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_s_en",
offset=self.s_en_offset,
mirror=mirror)
self.s_en_inst.place(offset=self.s_en_offset,
mirror=mirror)
self.row_end_inst.append(self.s_en_inst)
@ -292,8 +286,7 @@ class control_logic(design.design):
def place_dffs(self):
""" Place the input DFFs (with inverters) """
self.place_inst(name="ctrl_dffs",
offset=vector(0,0))
self.ctrl_dff_inst.place(vector(0,0))
def get_offset(self,row):
@ -333,27 +326,23 @@ class control_logic(design.design):
(y_off,mirror)=self.get_offset(row)
w_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="nand3_w_en_bar",
offset=w_en_bar_offset,
mirror=mirror)
self.w_en_bar_inst.place(offset=w_en_bar_offset,
mirror=mirror)
x_off += self.nand3.width
pre_w_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_w_en",
offset=pre_w_en_offset,
mirror=mirror)
self.pre_w_en_inst.place(offset=pre_w_en_offset,
mirror=mirror)
x_off += self.inv1.width
pre_w_en_bar_offset = vector(x_off, y_off)
self.place_inst(name="inv_pre_w_en_bar",
offset=pre_w_en_bar_offset,
mirror=mirror)
self.pre_w_en_bar_inst.place(offset=pre_w_en_bar_offset,
mirror=mirror)
x_off += self.inv2.width
w_en_offset = vector(x_off, y_off)
self.place_inst(name="inv_w_en2",
offset=w_en_offset,
mirror=mirror)
self.w_en_inst.place(offset=w_en_offset,
mirror=mirror)
x_off += self.inv8.width
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)
# Add the inverter
self.place_inst(name="dinv{}".format(stage_num),
offset=inv_offset,
mirror=inv_mirror)
cur_driver=self.driver_inst_list[stage_num]
cur_driver.place(offset=inv_offset,
mirror=inv_mirror)
# Now add the dummy loads to the right
load_list = self.load_inst_map[cur_driver]
for i in range(fanout_size):
inv_offset += vector(self.inv.width,0)
self.place_inst(name="dload_{0}_{1}".format(stage_num,i),
offset=inv_offset,
mirror=inv_mirror)
load_list[i].place(offset=inv_offset,
mirror=inv_mirror)
def add_route(self, pin1, pin2):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,16 +67,15 @@ class ms_flop_array(design.design):
def place_ms_flop_array(self):
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):
base = vector(i*self.ms.width,0)
mirror = "R0"
else:
base = vector((i+1)*self.ms.width,0)
mirror = "MY"
self.place_inst(name=name,
offset=base,
mirror=mirror)
self.ms_inst[index].place(offset=base,
mirror=mirror)
def add_layout_pins(self):

View File

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

View File

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

View File

@ -68,11 +68,8 @@ class sense_amp_array(design.design):
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)
self.local_insts[i].place(amp_position)
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):
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)
self.mux_inst[col_num].place(x_off)
def add_layout_pins(self):

View File

@ -63,10 +63,8 @@ class tri_gate_array(design.design):
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)
self.tri_inst[i].place(base)
def add_layout_pins(self):

View File

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

View File

@ -66,11 +66,9 @@ class write_driver_array(design.design):
def place_write_array(self):
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)
self.place_inst(name=name,
offset=base)
self.driver_insts[index].place(base)
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
self.pmos_pos = self.pmos.active_offset.scale(1,0) \
+ vector(0, self.height-self.pmos.active_height-self.top_bottom_space)
self.place_inst(name="pinv_pmos",
offset=self.pmos_pos)
self.pmos_inst.place(self.pmos_pos)
# 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.place_inst(name="pinv_nmos",
offset=self.nmos_pos)
self.nmos_inst.place(self.nmos_pos)
# 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.height = 2*self.inv1.height
self.place_insts()
self.place_modules()
self.route_wires()
self.add_layout_pins()
@ -97,23 +97,19 @@ class pinvbuf(design.design):
mod=self.inv2)
self.connect_inst(["zb_int", "Z", "vdd", "gnd"])
def place_insts(self):
def place_modules(self):
# Add INV1 to the right (capacitance shield)
self.place_inst(name="buf_inv1",
offset=vector(0,0))
self.inv1_inst.place(vector(0,0))
# Add INV2 to the right
self.place_inst(name="buf_inv2",
offset=vector(self.inv1_inst.rx(),0))
self.inv2_inst.place(vector(self.inv1_inst.rx(),0))
# Add INV3 to the right
self.place_inst(name="buf_inv3",
offset=vector(self.inv2_inst.rx(),0))
self.inv3_inst.place(vector(self.inv2_inst.rx(),0))
# Add INV4 to the bottom
self.place_inst(name="buf_inv4",
offset=vector(self.inv2_inst.rx(),2*self.inv2.height),
mirror = "MX")
self.inv4_inst.place(offset=vector(self.inv2_inst.rx(),2*self.inv2.height),
mirror = "MX")
def route_wires(self):

View File

@ -149,21 +149,17 @@ class pnand2(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space)
self.place_inst(name="pnand2_pmos1",
offset=pmos1_pos)
self.pmos1_inst.place(pmos1_pos)
self.pmos2_pos = pmos1_pos + self.overlap_offset
self.place_inst(name="pnand2_pmos2",
offset=self.pmos2_pos)
self.pmos2_inst.place(self.pmos2_pos)
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.place_inst(name="pnand2_nmos1",
offset=nmos1_pos)
self.nmos1_inst.place(nmos1_pos)
self.nmos2_pos = nmos1_pos + self.overlap_offset
self.place_inst(name="pnand2_nmos2",
offset=self.nmos2_pos)
self.nmos2_inst.place(self.nmos2_pos)
# 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))

View File

@ -154,29 +154,23 @@ class pnand3(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space)
self.pmos1_inst=self.place_inst(name="pnand3_pmos1",
offset=pmos1_pos)
self.pmos1_inst.place(pmos1_pos)
pmos2_pos = pmos1_pos + self.overlap_offset
self.pmos2_inst = self.place_inst(name="pnand3_pmos2",
offset=pmos2_pos)
self.pmos2_inst.place(pmos2_pos)
self.pmos3_pos = pmos2_pos + self.overlap_offset
self.pmos3_inst = self.place_inst(name="pnand3_pmos3",
offset=self.pmos3_pos)
self.pmos3_inst.place(self.pmos3_pos)
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.nmos1_inst=self.place_inst(name="pnand3_nmos1",
offset=nmos1_pos)
self.nmos1_inst.place(nmos1_pos)
nmos2_pos = nmos1_pos + self.overlap_offset
self.nmos2_inst=self.place_inst(name="pnand3_nmos2",
offset=nmos2_pos)
self.nmos2_inst.place(nmos2_pos)
self.nmos3_pos = nmos2_pos + self.overlap_offset
self.nmos3_inst=self.place_inst(name="pnand3_nmos3",
offset=self.nmos3_pos)
self.nmos3_inst.place(self.nmos3_pos)
# This should be placed at the top of the NMOS well
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)
self.lower_pmos_position = vector(self.bitcell.get_pin(self.bitcell_bl).lx(),
self.pmos.active_offset.y)
self.place_inst(name="lower_pmos",
offset=self.lower_pmos_position)
self.lower_pmos_inst.place(self.lower_pmos_position)
# adds the upper pmos(s) to layout
ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width
self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff)
self.place_inst(name="upper_pmos1",
offset=self.upper_pmos1_pos)
self.upper_pmos1_inst.place(self.upper_pmos1_pos)
upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset
self.place_inst(name="upper_pmos2",
offset=upper_pmos2_pos)
self.upper_pmos2_inst.place(upper_pmos2_pos)
def connect_poly(self):
"""Connects the upper and lower pmos together"""

View File

@ -58,14 +58,12 @@ class sram_1bank(sram_base):
# up to the row address DFFs.
control_pos = vector(-self.control_logic.width - 2*self.m2_pitch,
self.bank.bank_center.y - self.control_logic.control_logic_center.y)
self.place_inst(name=self.control_logic_inst.name,
offset=control_pos)
self.control_logic_inst.place(control_pos)
# 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,
self.control_logic_inst.uy())
self.place_inst(name=self.row_addr_dff_inst.name,
offset=row_addr_pos)
self.row_addr_dff_inst.place(row_addr_pos)
# 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)
@ -75,8 +73,7 @@ class sram_1bank(sram_base):
if self.col_addr_dff:
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)
self.place_inst(name=self.col_addr_dff_inst.name,
offset=col_addr_pos)
self.col_addr_dff_inst.place(col_addr_pos)
# Add the data flops below the bank to the right of the center of bank:
# This relies on the center point of the bank:
@ -85,8 +82,7 @@ class sram_1bank(sram_base):
# sense amps.
data_pos = vector(self.bank.bank_center.x,
data_gap - self.data_dff.height)
self.place_inst(self.data_dff.name,
offset=data_pos)
self.data_dff_inst.place(data_pos)
# 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

View File

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