diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index f442b34b..6b7d7988 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -31,7 +31,7 @@ class single_level_column_mux(design.design): self.add_ptx() self.pin_height = 2*self.m2_width self.width = self.bitcell.width - self.height = self.nmos2.uy() + self.pin_height + self.height = self.nmos_upper.uy() + self.pin_height self.connect_poly() self.add_bitline_pins() self.connect_bitlines() @@ -67,32 +67,32 @@ class single_level_column_mux(design.design): def add_ptx(self): """ Create the two pass gate NMOS transistors to switch the bitlines""" - # Adds nmos1,nmos2 to the module + # Adds nmos_lower,nmos_upper to the module self.nmos = ptx(width=self.ptx_width) self.add_mod(self.nmos) # Space it in the center - nmos1_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0) - self.nmos1=self.add_inst(name="mux_tx1", + nmos_lower_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0) + self.nmos_lower=self.add_inst(name="mux_tx1", mod=self.nmos, - offset=nmos1_position) + offset=nmos_lower_position) self.connect_inst(["bl", "sel", "bl_out", "gnd"]) # This aligns it directly above the other tx with gates abutting - nmos2_position = nmos1_position + vector(0,self.nmos.active_height + self.poly_space) - self.nmos2=self.add_inst(name="mux_tx2", + nmos_upper_position = nmos_lower_position + vector(0,self.nmos.active_height + self.poly_space) + self.nmos_upper=self.add_inst(name="mux_tx2", mod=self.nmos, - offset=nmos2_position) + offset=nmos_upper_position) self.connect_inst(["br", "sel", "br_out", "gnd"]) def connect_poly(self): """ Connect the poly gate of the two pass transistors """ - height=self.nmos2.get_pin("G").uy() - self.nmos1.get_pin("G").by() + height=self.nmos_upper.get_pin("G").uy() - self.nmos_lower.get_pin("G").by() self.add_layout_pin(text="sel", layer="poly", - offset=self.nmos1.get_pin("G").ll(), + offset=self.nmos_lower.get_pin("G").ll(), height=height) @@ -105,36 +105,36 @@ class single_level_column_mux(design.design): br_out_pin = self.get_pin("br_out") # These are on metal1 - nmos1_s_pin = self.nmos1.get_pin("S") - nmos1_d_pin = self.nmos1.get_pin("D") - nmos2_s_pin = self.nmos2.get_pin("S") - nmos2_d_pin = self.nmos2.get_pin("D") + nmos_lower_s_pin = self.nmos_lower.get_pin("S") + nmos_lower_d_pin = self.nmos_lower.get_pin("D") + nmos_upper_s_pin = self.nmos_upper.get_pin("S") + nmos_upper_d_pin = self.nmos_upper.get_pin("D") - # Add vias to bl, br_out, nmos2/S, nmos1/D + # Add vias to bl, br_out, nmos_upper/S, nmos_lower/D self.add_via_center(layers=("metal1","via1","metal2"), offset=bl_pin.bc()) self.add_via_center(layers=("metal1","via1","metal2"), offset=br_out_pin.uc()) self.add_via_center(layers=("metal1","via1","metal2"), - offset=nmos2_s_pin.center()) + offset=nmos_upper_s_pin.center()) self.add_via_center(layers=("metal1","via1","metal2"), - offset=nmos1_d_pin.center()) + offset=nmos_lower_d_pin.center()) - # bl -> nmos2/D on metal1 - # bl_out -> nmos2/S on metal2 - self.add_path("metal1",[bl_pin.ll(), vector(nmos2_d_pin.cx(),bl_pin.by()), nmos2_d_pin.center()]) + # bl -> nmos_upper/D on metal1 + # bl_out -> nmos_upper/S on metal2 + self.add_path("metal1",[bl_pin.ll(), vector(nmos_upper_d_pin.cx(),bl_pin.by()), nmos_upper_d_pin.center()]) # halfway up, move over - mid1 = bl_out_pin.uc().scale(1,0.5)+nmos2_s_pin.bc().scale(0,0.5) - mid2 = bl_out_pin.uc().scale(0,0.5)+nmos2_s_pin.bc().scale(1,0.5) - self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos2_s_pin.bc()]) + mid1 = bl_out_pin.uc().scale(1,0.5)+nmos_upper_s_pin.bc().scale(0,0.5) + mid2 = bl_out_pin.uc().scale(0,0.5)+nmos_upper_s_pin.bc().scale(1,0.5) + self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()]) - # br -> nmos1/D on metal2 - # br_out -> nmos1/S on metal1 - self.add_path("metal1",[br_out_pin.uc(), vector(nmos1_s_pin.cx(),br_out_pin.uy()), nmos1_s_pin.center()]) + # br -> nmos_lower/D on metal2 + # br_out -> nmos_lower/S on metal1 + self.add_path("metal1",[br_out_pin.uc(), vector(nmos_lower_s_pin.cx(),br_out_pin.uy()), nmos_lower_s_pin.center()]) # halfway up, move over - mid1 = br_pin.bc().scale(1,0.5)+nmos1_d_pin.uc().scale(0,0.5) - mid2 = br_pin.bc().scale(0,0.5)+nmos1_d_pin.uc().scale(1,0.5) - self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos1_d_pin.uc()]) + mid1 = br_pin.bc().scale(1,0.5)+nmos_lower_d_pin.uc().scale(0,0.5) + mid2 = br_pin.bc().scale(0,0.5)+nmos_lower_d_pin.uc().scale(1,0.5) + self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()]) def add_wells(self): @@ -144,11 +144,11 @@ class single_level_column_mux(design.design): """ # Add it to the right, aligned in between the two tx - active_pos = self.nmos2.lr().scale(0,0.5) + self.nmos1.ur().scale(1,0.5) - self.add_via_center(layers=("active", "contact", "metal1"), - offset=active_pos, - implant_type="p", - well_type="p") + active_pos = vector(self.bitcell.width,self.nmos_upper.by()) + active_via = self.add_via_center(layers=("active", "contact", "metal1"), + offset=active_pos, + implant_type="p", + well_type="p") # Add the M1->M2->M3 stack @@ -159,6 +159,12 @@ class single_level_column_mux(design.design): self.add_layout_pin_rect_center(text="gnd", layer="metal3", offset=active_pos) + + # Add well enclosure over all the tx and contact + self.add_rect(layer="pwell", + offset=vector(0,0), + width=self.bitcell.width, + height=self.height)