From 4345136d1a3b4ada6ab1afa14bf9db97c5299bf8 Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 13 May 2022 10:46:00 -0700 Subject: [PATCH] Fix offsets for local bitcell arrays. --- compiler/modules/local_bitcell_array.py | 16 ++++++----- compiler/modules/replica_bitcell_array.py | 16 ++++++++--- compiler/modules/wordline_buffer_array.py | 33 ++++++----------------- 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/compiler/modules/local_bitcell_array.py b/compiler/modules/local_bitcell_array.py index 0d3cfd12..18b33c0f 100644 --- a/compiler/modules/local_bitcell_array.py +++ b/compiler/modules/local_bitcell_array.py @@ -159,18 +159,20 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array): def place(self): """ Place the bitcelll array to the right of the wl driver. """ - # FIXME: Replace this with a tech specific paramter + + # FIXME: Replace this with a tech specific parameter driver_to_array_spacing = 3 * self.m3_pitch - self.wl_insts[0].place(vector(0, - self.bitcell_array.get_replica_bottom() + self.cell.height)) + wl_offset = vector(0, self.bitcell_array.get_replica_bottom()) + self.wl_insts[0].place(wl_offset) - self.bitcell_array_inst.place(vector(self.wl_insts[0].rx() + driver_to_array_spacing, - 0)) + bitcell_array_offset = vector(self.wl_insts[0].rx() + driver_to_array_spacing, 0) + self.bitcell_array_inst.place(bitcell_array_offset) if len(self.all_ports) > 1: - self.wl_insts[1].place(vector(self.bitcell_array_inst.rx() + self.wl_array.width + driver_to_array_spacing, - self.bitcell_array.get_replica_top() + self.cell.height), + wl_offset = vector(self.bitcell_array_inst.rx() + self.wl_array.width + driver_to_array_spacing, + self.bitcell_array.get_replica_bottom() + self.wl_array.height + self.cell.height) + self.wl_insts[1].place(wl_offset, mirror="XY") self.height = self.bitcell_array.height diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 0c86f3a6..f81926d4 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -353,28 +353,36 @@ class replica_bitcell_array(bitcell_base_array): self.DRC_LVS() def get_main_array_top(self): + """ Return the top of the main bitcell array. """ return self.bitcell_array_inst.uy() def get_main_array_bottom(self): + """ Return the bottom of the main bitcell array. """ return self.bitcell_array_inst.by() def get_main_array_left(self): + """ Return the left of the main bitcell array. """ return self.bitcell_array_inst.lx() def get_main_array_right(self): + """ Return the right of the main bitcell array. """ return self.bitcell_array_inst.rx() def get_replica_top(self): - return max([x.uy() for x in self.replica_col_insts if x] + [self.get_main_array_top()]) + """ Return the top of all replica columns. """ + return self.dummy_row_insts[0].by() def get_replica_bottom(self): - return min([x.by() for x in self.replica_col_insts if x] + [self.get_main_array_bottom()]) + """ Return the bottom of all replica columns. """ + return self.dummy_row_insts[0].uy() def get_replica_left(self): - return min([x.lx() for x in self.replica_col_insts if x] + [self.get_main_array_left()]) + """ Return the left of all replica columns. """ + return self.dummy_col_insts[0].rx() def get_replica_right(self): - return min([x.rx() for x in self.replica_col_insts if x] + [self.get_main_array_right()]) + """ Return the right of all replica columns. """ + return self.dummy_col_insts[1].rx() def get_column_offsets(self): """ diff --git a/compiler/modules/wordline_buffer_array.py b/compiler/modules/wordline_buffer_array.py index 51fe4030..9c74b79d 100644 --- a/compiler/modules/wordline_buffer_array.py +++ b/compiler/modules/wordline_buffer_array.py @@ -44,7 +44,10 @@ class wordline_buffer_array(design.design): self.place_drivers() self.route_layout() self.route_supplies() - self.offset_all_coordinates() + + # Don't offset these because some cells use standard cell style drivers + #self.offset_all_coordinates() + self.add_boundary() self.DRC_LVS() @@ -71,31 +74,11 @@ class wordline_buffer_array(design.design): are must-connects next level up. """ if layer_props.wordline_driver.vertical_supply: - for name in ["vdd", "gnd"]: - supply_pins = self.wld_inst[0].get_pins(name) - for pin in supply_pins: - self.add_layout_pin_segment_center(text=name, - layer=pin.layer, - start=pin.bc(), - end=vector(pin.cx(), self.height)) + self.route_vertical_pins("vdd", self.wld_inst) + self.route_vertical_pins("gnd", self.wld_inst) else: - # Find the x offsets for where the vias/pins should be placed - xoffset_list = [self.wld_inst[0].rx()] - for num in range(self.rows): - # this will result in duplicate polygons for rails, but who cares - - # use the inverter offset even though it will be the and's too - (gate_offset, y_dir) = self.get_gate_offset(0, - self.wl_driver.height, - num) - # Route both supplies - for name in ["vdd", "gnd"]: - supply_pin = self.wld_inst[num].get_pin(name) - - # Add pins in two locations - for xoffset in xoffset_list: - pin_pos = vector(xoffset, supply_pin.cy()) - self.copy_power_pin(supply_pin, loc=pin_pos) + self.route_vertical_pins("vdd", self.wld_inst, xside="rx",) + self.route_vertical_pins("gnd", self.wld_inst, xside="lx",) def create_drivers(self): self.wld_inst = []