diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index 0b2ff335..de0386b1 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -131,25 +131,20 @@ class delay_chain(design.design): # Drop a via on each A pin a_pin = load.get_pin("A") self.add_via_center(layers=("metal1","via1","metal2"), - offset=a_pin.center(), - rotate=90) + offset=a_pin.center()) self.add_via_center(layers=("metal2","via2","metal3"), - offset=a_pin.center(), - rotate=90) + offset=a_pin.center()) # Route an M3 horizontal wire to the furthest z_pin = inv.get_pin("Z") a_pin = inv.get_pin("A") a_max = self.rightest_load_inst[inv].get_pin("A") self.add_via_center(layers=("metal1","via1","metal2"), - offset=a_pin.center(), - rotate=90) + offset=a_pin.center()) self.add_via_center(layers=("metal1","via1","metal2"), - offset=z_pin.center(), - rotate=90) + offset=z_pin.center()) self.add_via_center(layers=("metal2","via2","metal3"), - offset=z_pin.center(), - rotate=90) + offset=z_pin.center()) self.add_path("metal3",[z_pin.center(), a_max.center()]) @@ -185,12 +180,10 @@ class delay_chain(design.design): # input is A pin of first inverter a_pin = self.driver_inst_list[0].get_pin("A") self.add_via_center(layers=("metal1","via1","metal2"), - offset=a_pin.center(), - rotate=90) + offset=a_pin.center()) self.add_layout_pin(text="in", layer="metal2", offset=a_pin.ll().scale(1,0), - width=a_pin.width(), height=a_pin.cy()) @@ -198,12 +191,12 @@ class delay_chain(design.design): last_driver_inst = self.driver_inst_list[-1] a_pin = self.rightest_load_inst[last_driver_inst].get_pin("A") self.add_via_center(layers=("metal1","via1","metal2"), - offset=a_pin.center(), - rotate=90) + offset=a_pin.center()) mid_point = vector(a_pin.cx()+3*self.m2_width,a_pin.cy()) self.add_path("metal2",[a_pin.center(), mid_point, mid_point.scale(1,0)]) - self.add_layout_pin(text="out", - layer="metal2", - offset=mid_point.scale(1,0)) + self.add_layout_pin_center_segment(text="out", + layer="metal2", + start=mid_point, + end=mid_point.scale(1,0)) diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index b5c2118c..fbd1f361 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -37,8 +37,11 @@ class replica_bitline(design.design): self.calculate_module_offsets() self.add_modules() self.route() + + self.offset_all_coordinates() + self.add_layout_pins() - self.add_lvs_correspondence_points() + #self.add_lvs_correspondence_points() self.DRC_LVS() @@ -51,28 +54,22 @@ class replica_bitline(design.design): # M1/M2 routing pitch is based on contacted pitch self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(self.m1_space,self.m2_space) self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(self.m2_space,self.m3_space) + - # This corrects the offset pitch difference between M2 and M1 - self.offset_fix = vector(0.5*(self.m2_width-self.m1_width),0) - - # delay chain will be rotated 90, so move it over a width - # we move it up a inv height just for some routing room - self.rbl_inv_offset = vector(self.delay_chain.height, self.inv.width) - # access TX goes right on top of inverter, leave space for an inverter which is - # about the same as a TX. We'll need to add rails though. - self.access_tx_offset = vector(1.25*self.inv.height,self.rbl_inv_offset.y) + vector(0,2.5*self.inv.width) - self.delay_chain_offset = self.rbl_inv_offset + vector(0,4*self.inv.width) - - # Replica bitline and such are not rotated, but they must be placed far enough + # Quadrant 1: Replica bitline and such are not rotated, but they must be placed far enough # away from the delay chain/inverter with space for three M2 tracks - self.bitcell_offset = self.rbl_inv_offset + vector(2*self.m2_pitch, 0) + vector(0, self.bitcell.height + self.inv.width) - - self.rbl_offset = self.bitcell_offset - + self.bitcell_offset = vector(0,self.replica_bitcell.height) + self.rbl_offset = self.bitcell_offset - self.height = max(self.rbl_offset.y + self.rbl.height + self.m2_pitch, - self.delay_chain_offset.y + self.delay_chain.width + self.m2_pitch) - self.width = self.rbl_offset.x + self.bitcell.width + # Quadrant 4: with some space below it and tracks on the right for vdd/gnd + self.delay_chain_offset = vector(-self.delay_chain.width-4*self.m2_pitch,self.replica_bitcell.height) + + # Will be flipped vertically below the delay chain + self.rbl_inv_offset = self.delay_chain_offset + vector(0.5*self.delay_chain.width, 0) + + # Placed next to the replica bitcell + self.access_tx_offset = vector(-4*self.m2_pitch-self.access_tx.width-self.inv.width, 0.5*self.inv.height) + def create_modules(self): @@ -99,23 +96,20 @@ class replica_bitline(design.design): # This is the threshold detect inverter on the output of the RBL self.rbl_inv_inst=self.add_inst(name="rbl_inv", mod=self.inv, - offset=self.rbl_inv_offset+vector(0,self.inv.width), - rotate=270, - mirror="MX") + offset=self.rbl_inv_offset, + rotate=180) self.connect_inst(["bl[0]", "out", "vdd", "gnd"]) self.tx_inst=self.add_inst(name="rbl_access_tx", mod=self.access_tx, - offset=self.access_tx_offset, - rotate=90) + offset=self.access_tx_offset) # D, G, S, B self.connect_inst(["vdd", "delayed_en", "bl[0]", "vdd"]) # add the well and poly contact self.dc_inst=self.add_inst(name="delay_chain", mod=self.delay_chain, - offset=self.delay_chain_offset, - rotate=90) + offset=self.delay_chain_offset) self.connect_inst(["en", "delayed_en", "vdd", "gnd"]) self.rbc_inst=self.add_inst(name="bitcell", @@ -129,6 +123,10 @@ class replica_bitline(design.design): offset=self.rbl_offset) self.connect_inst(["bl[0]", "br[0]"] + ["gnd"]*self.bitcell_loads + ["vdd", "gnd"]) + + self.height = max(self.rbl_inst.uy(),self.dc_inst.uy()) + self.m2_pitch + self.width = self.rbl_inst.rx() + self.m2_width + @@ -146,185 +144,386 @@ class replica_bitline(design.design): # (middle in between the pmos and nmos) poly_pin = self.tx_inst.get_pin("G") - poly_offset = poly_pin.rc() - # This centers the contact on the poly - contact_offset = poly_offset.scale(0,1) + self.dc_inst.get_pin("out").bc().scale(1,0) + poly_offset = poly_pin.uc() + # This centers the contact above the poly by one pitch + contact_offset = poly_offset + vector(0,self.m2_pitch) self.add_contact_center(layers=("poly", "contact", "metal1"), offset=contact_offset) - self.add_rect(layer="poly", - offset=poly_pin.lr(), - width=contact_offset.x-poly_offset.x, - height=self.poly_width) + self.add_contact_center(layers=("metal1", "via1", "metal2"), + offset=contact_offset) + self.add_segment_center(layer="poly", + start=poly_offset, + end=contact_offset) nwell_offset = self.rbl_inv_offset + vector(-self.inv.height,self.inv.width) - self.add_rect(layer="nwell", - offset=nwell_offset, - width=0.5*self.inv.height, - height=self.delay_chain_offset.y-nwell_offset.y) + # self.add_rect(layer="nwell", + # offset=nwell_offset, + # width=0.5*self.inv.height, + # height=self.delay_chain_offset.y-nwell_offset.y) # 2. Route delay chain output to access tx gate delay_en_offset = self.dc_inst.get_pin("out").bc() - self.add_path("metal1", [delay_en_offset,contact_offset]) + self.add_path("metal2", [delay_en_offset,contact_offset]) - # 3. Route the mid-point of previous route to the bitcell WL + # 3. Route the contact of previous route to the bitcell WL # route bend of previous net to bitcell WL wl_offset = self.rbc_inst.get_pin("WL").lc() - wl_mid = vector(contact_offset.x,wl_offset.y) - self.add_path("metal1", [contact_offset, wl_mid, wl_offset]) + xmid_point= 0.5*(wl_offset.x+contact_offset.x) + wl_mid1 = vector(xmid_point,contact_offset.y) + wl_mid2 = vector(xmid_point,wl_offset.y) + self.add_path("metal1", [contact_offset, wl_mid1, wl_mid2, wl_offset]) # DRAIN ROUTE # Route the drain to the vdd rail - drain_offset = self.tx_inst.get_pin("D").lc() - inv_vdd_offset = self.rbl_inv_inst.get_pin("vdd").uc() - vdd_offset = inv_vdd_offset.scale(1,0) + drain_offset.scale(0,1) - self.add_path("metal1", [drain_offset, vdd_offset]) + drain_offset = self.tx_inst.get_pin("D").center() + self.add_path("metal1", [drain_offset, drain_offset.scale(1,0)]) # SOURCE ROUTE - # Route the source to the RBL inverter input - source_offset = self.tx_inst.get_pin("S").bc() - mid1 = source_offset.scale(1,0) + vector(0,self.rbl_inv_offset.y+self.inv.width+self.m2_pitch) - inv_A_offset = self.rbl_inv_inst.get_pin("A").uc() - mid2 = vector(inv_A_offset.x, mid1.y) - self.add_path("metal1",[source_offset, mid1, mid2, inv_A_offset]) - - # Route the connection of the source route (mid2) to the RBL bitline (left) - source_offset = mid2 - # Route the M2 to the right of the vdd rail between rbl_inv and bitcell - gnd_pin = self.rbl_inv_inst.get_pin("gnd").ll() - mid1 = vector(gnd_pin.x+self.m2_pitch,source_offset.y) + # Route the drain to the RBL inverter input + source_offset = self.tx_inst.get_pin("S").center() + inv_A_offset = self.rbl_inv_inst.get_pin("A").center() + self.add_path("metal1",[source_offset, inv_A_offset]) + + # Route the connection of the source route to the RBL bitline (left) # Via will go halfway down from the bitcell bl_offset = self.rbc_inst.get_pin("BL").bc() - via_offset = bl_offset - vector(0,0.5*self.inv.width) - mid2 = vector(mid1.x,via_offset.y) - # self.add_contact(layers=("metal1", "via1", "metal2"), - # offset=via_offset - vector(0.5*self.m2_width,0.5*self.m1_width)) - self.add_wire(("metal1","via1","metal2"),[source_offset,mid1,mid2,via_offset,bl_offset]) - #self.add_path("metal2",[via_offset,bl_offset]) + self.add_path("metal3",[source_offset, bl_offset]) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=source_offset) + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=source_offset) + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=bl_offset) + + # BODY ROUTE + # Connect it to the inverter well + nwell_offset = self.rbl_inv_inst.lr() + ur_offset = self.tx_inst.ur() + self.add_rect(layer="nwell", + offset=nwell_offset, + width=ur_offset.x-nwell_offset.x, + height=ur_offset.y-nwell_offset.y) def route_vdd(self): - # Add a rail in M2 that is to the right of the inverter gnd pin - # The replica column may not fit in a single standard cell pitch, so add the vdd rail to the - # right of it. - vdd_start = vector(self.bitcell_offset.x + self.bitcell.width + self.m1_pitch,0) - # It is the height of the entire RBL and bitcell - self.add_layout_pin(text="vdd", - layer="metal1", - offset=vdd_start, - width=self.m1_width, - height=self.rbl.height+self.bitcell.height+2*self.inv.width+0.5*self.m1_width) - - # Connect the vdd pins of the bitcell load directly to vdd - vdd_pins = self.rbl_inst.get_pins("vdd") - for pin in vdd_pins: - offset = vector(vdd_start.x,pin.by()) - self.add_rect(layer="metal1", - offset=offset, - width=self.rbl_offset.x-vdd_start.x, - height=self.m1_width) - - # Also connect the replica bitcell vdd pin to vdd - pin = self.rbc_inst.get_pin("vdd") - offset = vector(vdd_start.x,pin.by()) - self.add_rect(layer="metal1", - offset=offset, - width=self.bitcell_offset.x-vdd_start.x, - height=self.m1_width) + """ Route all signals connected to vdd """ - # Add a second vdd pin. No need for full length. It is must connect at the next level. - inv_vdd_offset = self.rbl_inv_inst.get_pin("vdd").ll() - self.add_layout_pin(text="vdd", - layer="metal1", - offset=inv_vdd_offset.scale(1,0), - width=self.m1_width, - height=self.delay_chain_offset.y) + # Route the vdd lines from left to right + + # Add via for the delay chain + left_vdd_start = self.dc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,2*self.m2_pitch) + left_vdd_end = vector(left_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch) + left_vdd_pin=self.add_layout_pin_center_segment(text="vdd", + layer="metal2", + start=left_vdd_start, + end=left_vdd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=left_vdd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=left_vdd_end, + rotate=90) + + # Vdd line to the left of the replica bitline + center_vdd_start = self.rbc_inst.ll() - vector(3*self.m2_pitch,2*self.m2_pitch) + center_vdd_end = vector(center_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch) + center_vdd_pin=self.add_layout_pin_center_segment(text="vdd", + layer="metal2", + start=center_vdd_start, + end=center_vdd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=center_vdd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=center_vdd_end, + rotate=90) + + # Vdd line to the right of the replica bitline + right_vdd_start = self.rbc_inst.lr() + vector(2*self.m2_pitch,-2*self.m2_pitch) + right_vdd_end = vector(right_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch) + right_vdd_pin=self.add_layout_pin_center_segment(text="vdd", + layer="metal2", + start=right_vdd_start, + end=right_vdd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=right_vdd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=right_vdd_end, + rotate=90) + + + + # Connect the WL and vdd pins directly to the center and right vdd rails + # Connect RBL vdd pins to center and right rails + rbl_vdd_pins = self.rbl_inst.get_pins("vdd") + for pin in rbl_vdd_pins: + if pin.layer != "metal1": + continue + start = vector(center_vdd_pin.cx(),pin.cy()) + end = vector(right_vdd_pin.cx(),pin.cy()) + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + + + # Connect the vdd pins of the delay chain to the left rails + dc_vdd_pins = self.dc_inst.get_pins("vdd") + for pin in dc_vdd_pins: + if pin.layer != "metal1": + continue + start = vector(left_vdd_pin.cx(),pin.cy()) + # Note, we don't connect to center because of via conflicts + # with the RBL pins + #end = vector(center_vdd_pin.cx(),pin.cy()) + end = pin.rc() + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=end, + #rotate=90) + + + # Add via for the inverter + pin = self.rbl_inv_inst.get_pin("vdd") + start = vector(left_vdd_pin.cx(),pin.cy()) + end = vector(center_vdd_pin.cx(),pin.cy()) + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + + # Add via for the RBC + pin = self.rbc_inst.get_pin("vdd") + start = pin.lc() + end = vector(right_vdd_pin.cx(),pin.cy()) + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + # Connect the RBL rails at the top and bottom + rbl_pins = self.rbl_inst.get_pins("vdd") + for pin in rbl_pins: + if pin.layer != "metal2": + continue + end = vector(pin.cx(),right_vdd_pin.uy()) + self.add_segment_center(layer="metal2", + start=pin.uc(), + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + start = vector(pin.cx(),right_vdd_pin.by()) + self.add_segment_center(layer="metal2", + start=pin.bc(), + end=start) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + + # Connect the rails at the top and bottom + self.add_segment_center(layer="metal1", + start=left_vdd_end, + end=right_vdd_end) + self.add_segment_center(layer="metal1", + start=left_vdd_start, + end=right_vdd_start) def route_gnd(self): """ Route all signals connected to gnd """ - - gnd_start = self.rbl_inv_inst.get_pin("gnd").bc() - gnd_end = vector(gnd_start.x, self.rbl_inst.uy()+2*self.m2_pitch) - - # Add a rail in M1 from bottom of delay chain to two above the RBL - # This prevents DRC errors with vias for the WL - dc_top = self.dc_inst.ur() - self.add_segment_center(layer="metal1", - start=vector(gnd_start.x, dc_top.y), - end=gnd_end) - # Add a rail in M2 from RBL inverter to two above the RBL - self.add_segment_center(layer="metal2", - start=gnd_start, - end=gnd_end) - - # Add pin from bottom to RBL inverter - self.add_layout_pin_center_segment(text="gnd", - layer="metal1", - start=gnd_start.scale(1,0), - end=gnd_start) + # Route the gnd lines from left to right + + # Add via for the delay chain + left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(self.m2_pitch,self.m2_pitch) + left_gnd_end = vector(left_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + left_gnd_pin=self.add_layout_pin_center_segment(text="gnd", + layer="metal2", + start=left_gnd_start, + end=left_gnd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=left_gnd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=left_gnd_end, + rotate=90) + + # Gnd line to the left of the replica bitline + center_gnd_start = self.rbc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,self.m2_pitch) + center_gnd_end = vector(center_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + center_gnd_pin=self.add_layout_pin_center_segment(text="gnd", + layer="metal2", + start=center_gnd_start, + end=center_gnd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=center_gnd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=center_gnd_end, + rotate=90) + + # Gnd line to the right of the replica bitline + right_gnd_start = self.rbc_inst.lr().scale(1,0) + vector(self.m2_pitch,-self.m2_pitch) + right_gnd_end = vector(right_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + right_gnd_pin=self.add_layout_pin_center_segment(text="gnd", + layer="metal2", + start=right_gnd_start, + end=right_gnd_end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=right_gnd_start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=right_gnd_end, + rotate=90) - # Connect the WL pins directly to gnd - gnd_pin = self.get_pin("gnd").rc() + + + # Connect the WL and gnd pins directly to the center and right gnd rails for row in range(self.bitcell_loads): wl = "wl[{}]".format(row) pin = self.rbl_inst.get_pin(wl) - start = vector(gnd_pin.x,pin.cy()) + if pin.layer != "metal1": + continue + start = vector(center_gnd_pin.cx(),pin.cy()) + end = vector(right_gnd_pin.cx(),pin.cy()) self.add_segment_center(layer="metal1", start=start, - end=pin.lc()) + end=end) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=start) + offset=start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) - # Add via for the delay chain - offset = self.dc_inst.get_pins("gnd")[0].bc() + vector(0.5*contact.m1m2.width,0.5*contact.m1m2.height) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=offset) - # Add via for the inverter - offset = self.rbl_inv_inst.get_pin("gnd").bc() - vector(0,0.5*contact.m1m2.height) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=offset) - - # Connect the bitcell gnd pins to the rail - gnd_pins = self.get_pins("gnd") - gnd_start = gnd_pins[0].ul() rbl_gnd_pins = self.rbl_inst.get_pins("gnd") # Add L shapes to each vertical gnd rail for pin in rbl_gnd_pins: + if pin.layer != "metal1": + continue + start = vector(center_gnd_pin.cx(),pin.cy()) + end = vector(right_gnd_pin.cx(),pin.cy()) + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + + + # Connect the gnd pins of the delay chain to the left rails + dc_gnd_pins = self.dc_inst.get_pins("gnd") + for pin in dc_gnd_pins: + if pin.layer != "metal1": + continue + start = vector(left_gnd_pin.cx(),pin.cy()) + # Note, we don't connect to the center rails because of + # via conflicts with the RBL + #end = vector(center_gnd_pin.cx(),pin.cy()) + end = pin.rc() + self.add_segment_center(layer="metal1", + start=start, + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=end, + #rotate=90) + + + # Add via for the inverter + # pin = self.rbl_inv_inst.get_pin("gnd") + # start = vector(left_gnd_pin.cx(),pin.cy()) + # end = vector(center_gnd_pin.cx(),pin.cy()) + # self.add_segment_center(layer="metal1", + # start=start, + # end=end) + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=start, + #rotate=90) + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=end, + #rotate=90) + + + + # Connect the RBL rails at the top and bottom + rbl_pins = self.rbl_inst.get_pins("gnd") + for pin in rbl_pins: if pin.layer != "metal2": continue - gnd_end = pin.uc() - gnd_mid = vector(gnd_end.x, gnd_start.y) - self.add_wire(("metal1","via1","metal2"), [gnd_start, gnd_mid, gnd_end]) - gnd_start = gnd_mid + end = vector(pin.cx(),right_gnd_pin.uy()) + self.add_segment_center(layer="metal2", + start=pin.uc(), + end=end) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end, + rotate=90) + + start = vector(pin.cx(),right_gnd_pin.by()) + self.add_segment_center(layer="metal2", + start=pin.bc(), + end=start) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=start, + rotate=90) + + # Connect the rails at the top and bottom + self.add_segment_center(layer="metal1", + start=left_gnd_end, + end=right_gnd_end) + self.add_segment_center(layer="metal1", + start=left_gnd_start, + end=right_gnd_start) - - # Add a second gnd pin to the second delay chain rail. No need for full length. - dc_gnd_offset = self.dc_inst.get_pins("gnd")[1].ll() - self.add_layout_pin(text="gnd", - layer="metal1", - offset=dc_gnd_offset.scale(1,0), - width=self.m1_width, - height=self.delay_chain_offset.y) - def add_layout_pins(self): """ Route the input and output signal """ - en_offset = self.dc_inst.get_pin("in").ll() - self.add_layout_pin(text="en", - layer="metal1", - offset=en_offset.scale(1,0), - width=self.m1_width, - height=en_offset.y) + en_offset = self.dc_inst.get_pin("in").bc() + self.add_layout_pin_center_segment(text="en", + layer="metal2", + start=en_offset, + end=en_offset.scale(1,0)) - out_offset = self.rbl_inv_inst.get_pin("Z").ll() - self.add_layout_pin(text="out", - layer="metal1", - offset=out_offset.scale(1,0), - width=self.m1_width, - height=out_offset.y) + out_offset = self.rbl_inv_inst.get_pin("Z").center() + self.add_layout_pin_center_segment(text="out", + layer="metal2", + start=out_offset, + end=out_offset.scale(1,0)) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=out_offset) def add_lvs_correspondence_points(self): """ This adds some points for easier debugging if LVS goes wrong. diff --git a/compiler/options.py b/compiler/options.py index 6f564f73..946d76cc 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -13,8 +13,8 @@ class options(optparse.Values): # This is the name of the technology. tech_name = "" # This is the temp directory where all intermediate results are stored. - #openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),os.getpid()) - openram_temp = "/Users/{}/openram_temp/".format(getpass.getuser()) + openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),os.getpid()) + #openram_temp = "/Users/{}/openram_temp/".format(getpass.getuser()) # This is the verbosity level to control debug information. 0 is none, 1 # is minimal, etc. debug_level = 0