diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index bc079f25..2f7931ad 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -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): diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 1e84f26f..780baaf9 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -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)) diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 8950707f..5547b99d 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -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): diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index fa727e81..337deb48 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -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): diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 62ad6e88..de5034c2 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -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 diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 1c037370..02504313 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -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) diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index 5cccf112..eb61df52 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -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): diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index fd21aa98..7c6ae90e 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -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: diff --git a/compiler/modules/dff_buf_array.py b/compiler/modules/dff_buf_array.py index 9f978b74..e221e724 100644 --- a/compiler/modules/dff_buf_array.py +++ b/compiler/modules/dff_buf_array.py @@ -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: diff --git a/compiler/modules/dff_inv.py b/compiler/modules/dff_inv.py index f0a88c80..8d51aa29 100644 --- a/compiler/modules/dff_inv.py +++ b/compiler/modules/dff_inv.py @@ -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): diff --git a/compiler/modules/dff_inv_array.py b/compiler/modules/dff_inv_array.py index 512d6c7d..01ca3a47 100644 --- a/compiler/modules/dff_inv_array.py +++ b/compiler/modules/dff_inv_array.py @@ -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: diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index ae393eda..38136b62 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -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) diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index 61db09af..d0699cc3 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -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): diff --git a/compiler/modules/ms_flop_array.py b/compiler/modules/ms_flop_array.py index 653c0c38..4f266683 100644 --- a/compiler/modules/ms_flop_array.py +++ b/compiler/modules/ms_flop_array.py @@ -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): diff --git a/compiler/modules/precharge_array.py b/compiler/modules/precharge_array.py index 3b127f6b..9e2bce40 100644 --- a/compiler/modules/precharge_array.py +++ b/compiler/modules/precharge_array.py @@ -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) diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index 67f648a2..06f26417 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -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) diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index 5a513583..c2fc5c82 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -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): diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 4913bfb7..a732ce74 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -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): diff --git a/compiler/modules/tri_gate_array.py b/compiler/modules/tri_gate_array.py index 22004a9f..5eff379a 100644 --- a/compiler/modules/tri_gate_array.py +++ b/compiler/modules/tri_gate_array.py @@ -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): diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 5ba641e2..2d4ef224 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -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): diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 2d5bea87..4f6bd146 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -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): diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index f4e43086..e2e87053 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -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 diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index 0958643e..e55fb649 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -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): diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index bb885454..99ae9f02 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -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)) diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index 1f578d0b..984ee417 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -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()) diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index a90c44c8..3ddca616 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -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""" diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index 501899bd..e2a62e42 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -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 diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 80786e13..da6403db 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -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)