mirror of https://github.com/VLSIDA/OpenRAM.git
Move place function to instance class rather than hierarchy.
This commit is contained in:
parent
8664f7a0b8
commit
6401cbf2a6
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue