diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index 90645326..9d21211e 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -7,7 +7,7 @@ # import pgate import debug -from tech import drc +from tech import drc, layer from vector import vector from sram_factory import factory import logical_effort @@ -22,13 +22,13 @@ class single_level_column_mux(pgate.pgate): for optimal speed """ def __init__(self, name, tx_size=8, bitcell_bl="bl", bitcell_br="br"): - + debug.info(2, "creating single column mux cell: {0}".format(name)) self.tx_size = int(tx_size) self.bitcell_bl = bitcell_bl self.bitcell_br = bitcell_br - + pgate.pgate.__init__(self, name) def get_bl_names(self): @@ -41,9 +41,9 @@ class single_level_column_mux(pgate.pgate): self.add_modules() self.add_pins() self.add_ptx() - + def create_layout(self): - + self.pin_height = 2 * self.m2_width self.width = self.bitcell.width self.height = self.nmos_upper.uy() + self.pin_height @@ -59,39 +59,42 @@ class single_level_column_mux(pgate.pgate): self.ptx_width = self.tx_size * drc("minwidth_tx") self.nmos = factory.create(module_type="ptx", width=self.ptx_width) self.add_mod(self.nmos) - + def add_pins(self): self.add_pin_list(["bl", "br", "bl_out", "br_out", "sel", "gnd"]) def add_bitline_pins(self): """ Add the top and bottom pins to this cell """ - bl_pos = vector(self.bitcell.get_pin(self.bitcell_bl).lx(), 0) - br_pos = vector(self.bitcell.get_pin(self.bitcell_br).lx(), 0) + bl_pin=self.bitcell.get_pin(self.bitcell_bl) + br_pin=self.bitcell.get_pin(self.bitcell_br) + + bl_pos = vector(bl_pin.lx(), 0) + br_pos = vector(br_pin.lx(), 0) # bl and br self.add_layout_pin(text="bl", - layer="m2", + layer=bl_pin.layer, offset=bl_pos + vector(0, self.height - self.pin_height), height=self.pin_height) self.add_layout_pin(text="br", - layer="m2", + layer=br_pin.layer, offset=br_pos + vector(0, self.height - self.pin_height), height=self.pin_height) - + # bl_out and br_out self.add_layout_pin(text="bl_out", - layer="m2", + layer=bl_pin.layer, offset=bl_pos, height=self.pin_height) self.add_layout_pin(text="br_out", - layer="m2", + layer=br_pin.layer, offset=br_pos, height=self.pin_height) def add_ptx(self): """ Create the two pass gate NMOS transistors to switch the bitlines""" - + # Space it in the center nmos_lower_position = self.nmos.active_offset.scale(0,1) \ + vector(0.5 * self.bitcell.width- 0.5 * self.nmos.active_width, 0) @@ -102,7 +105,7 @@ class single_level_column_mux(pgate.pgate): # This aligns it directly above the other tx with gates abutting nmos_upper_position = nmos_lower_position \ - + vector(0, self.nmos.active_height + self.poly_space) + + vector(0, self.nmos.active_height + self.active_space) self.nmos_upper = self.add_inst(name="mux_tx2", mod=self.nmos, offset=nmos_upper_position) @@ -110,12 +113,11 @@ class single_level_column_mux(pgate.pgate): def connect_poly(self): """ Connect the poly gate of the two pass transistors """ - - 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.nmos_lower.get_pin("G").ll(), - height=height) + offset=self.nmos_lower.get_pin("G").ul() - vector(0,self.poly_extend_active), + height=self.active_space) def connect_bitlines(self): """ Connect the bitlines to the mux transistors """ @@ -131,36 +133,42 @@ class single_level_column_mux(pgate.pgate): nmos_upper_s_pin = self.nmos_upper.get_pin("S") nmos_upper_d_pin = self.nmos_upper.get_pin("D") + # If li exists, use li and m1 for the mux, otherwise use m1 and m2 + if "li" in layer: + col_mux_stack = self.li_stack + else: + col_mux_stack = self.m1_stack + # Add vias to bl, br_out, nmos_upper/S, nmos_lower/D - self.add_via_center(layers=self.m1_stack, + self.add_via_center(layers=col_mux_stack, offset=bl_pin.bc(), directions=("V", "V")) - self.add_via_center(layers=self.m1_stack, + self.add_via_center(layers=col_mux_stack, offset=br_out_pin.uc(), directions=("V", "V")) - self.add_via_center(layers=self.m1_stack, + self.add_via_center(layers=col_mux_stack, offset=nmos_upper_s_pin.center(), directions=("V", "V")) - self.add_via_center(layers=self.m1_stack, + self.add_via_center(layers=col_mux_stack, offset=nmos_lower_d_pin.center(), directions=("V", "V")) - + # bl -> nmos_upper/D on metal1 # bl_out -> nmos_upper/S on metal2 - self.add_path("m1", + self.add_path(col_mux_stack[0], [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.4) \ + nmos_upper_s_pin.bc().scale(0, 0.4) mid2 = bl_out_pin.uc().scale(0, 0.4) \ - + nmos_upper_s_pin.bc().scale(1, 0.4) - self.add_path("m2", - [bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()]) - + + nmos_upper_s_pin.bc().scale(1, 0.4) + self.add_path(col_mux_stack[2], + [bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.center()]) + # br -> nmos_lower/D on metal2 # br_out -> nmos_lower/S on metal1 - self.add_path("m1", + self.add_path(col_mux_stack[0], [br_out_pin.uc(), vector(nmos_lower_s_pin.cx(), br_out_pin.uy()), nmos_lower_s_pin.center()]) @@ -169,9 +177,9 @@ class single_level_column_mux(pgate.pgate): + 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("m2", - [br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()]) - + self.add_path(col_mux_stack[2], + [br_pin.bc(), mid1, mid2, nmos_lower_d_pin.center()]) + def add_wells(self): """ Add a well and implant over the whole cell. Also, add the @@ -192,11 +200,12 @@ class single_level_column_mux(pgate.pgate): start_layer="m1") # 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) - + if "pwell" in layer: + self.add_rect(layer="pwell", + offset=vector(0, 0), + width=self.bitcell.width, + height=self.height) + def get_stage_effort(self, corner, slew, load): """ Returns relative delay that the column mux. @@ -211,4 +220,3 @@ class single_level_column_mux(pgate.pgate): load, parasitic_delay, False) -