diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index df40a38d..d65603a8 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -62,13 +62,29 @@ class sense_amp_array(design.design): br_offset = amp_position + br_pin.ll().scale(1,0) dout_offset = amp_position + dout_pin.ll() - self.add_inst(name=name, + inst = self.add_inst(name=name, mod=self.amp, offset=amp_position) self.connect_inst(["bl[{0}]".format(i),"br[{0}]".format(i), "data[{0}]".format(i/self.words_per_row), "en", "vdd", "gnd"]) + + gnd_pos = inst.get_pin("gnd").center() + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=gnd_pos) + self.add_layout_pin_rect_center(text="gnd", + layer="metal3", + offset=gnd_pos) + + vdd_pos = inst.get_pin("vdd").center() + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=vdd_pos) + self.add_layout_pin_rect_center(text="vdd", + layer="metal3", + offset=vdd_pos) + + self.add_layout_pin(text="bl[{0}]".format(i), layer="metal2", offset=bl_offset, @@ -87,26 +103,7 @@ class sense_amp_array(design.design): height=dout_pin.height()) - - def connect_rails(self): - # add vdd rail across entire array - vdd_offset = self.amp.get_pin("vdd").ll().scale(0,1) - self.add_layout_pin(text="vdd", - layer="metal1", - offset=vdd_offset, - width=self.width, - height=drc["minwidth_metal1"]) - - # NOTE:the gnd rails are vertical so it is not connected horizontally - # add gnd rail across entire array - gnd_offset = self.amp.get_pin("gnd").ll().scale(0,1) - self.add_layout_pin(text="gnd", - layer="metal1", - offset=gnd_offset, - width=self.width, - height=drc["minwidth_metal1"]) - # add sclk rail across entire array sclk_offset = self.amp.get_pin("en").ll().scale(0,1) self.add_layout_pin(text="en", diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 8677cd3a..3ac43d59 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -100,16 +100,9 @@ class single_level_column_mux_array(design.design): offset=offset, height=self.height-offset.y) - gnd_pins = mux_inst.get_pins("gnd") - for gnd_pin in gnd_pins: - # only do even colums to avoid duplicates - offset = gnd_pin.ll() - if col_num % 2 == 0: - self.add_layout_pin(text="gnd", - layer="metal2", - offset=offset.scale(1,0), - height=self.height) - + for inst in self.mux_inst: + self.copy_layout_pin(inst, "gnd") + def add_routing(self): self.add_horizontal_input_rail() diff --git a/compiler/modules/precharge.py b/compiler/pgates/precharge.py similarity index 100% rename from compiler/modules/precharge.py rename to compiler/pgates/precharge.py diff --git a/compiler/modules/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py similarity index 81% rename from compiler/modules/single_level_column_mux.py rename to compiler/pgates/single_level_column_mux.py index 8b8fd994..24f3b1fa 100644 --- a/compiler/modules/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -32,7 +32,6 @@ class single_level_column_mux(design.design): self.width = self.bitcell.width self.height = self.nmos2.uy() + self.pin_height self.connect_poly() - self.add_gnd_rail() self.add_bitline_pins() self.connect_bitlines() self.add_wells() @@ -137,37 +136,28 @@ class single_level_column_mux(design.design): self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos1_d_pin.uc()]) - def add_gnd_rail(self): - """ Add the gnd rails through the cell to connect to the bitcell array """ - - gnd_pins = self.bitcell.get_pins("gnd") - for gnd_pin in gnd_pins: - # only use vertical gnd pins that span the whole cell - if gnd_pin.layer == "metal2" and gnd_pin.height >= self.bitcell.height: - gnd_position = vector(gnd_pin.lx(), 0) - self.add_layout_pin(text="gnd", - layer="metal2", - offset=gnd_position, - height=self.height) - def add_wells(self): - """ Add a well and implant over the whole cell. Also, add the pwell contact (if it exists) """ - - # find right most gnd rail - gnd_pins = self.bitcell.get_pins("gnd") - right_gnd = None - for gnd_pin in gnd_pins: - if right_gnd == None or gnd_pin.lx()>right_gnd.lx(): - right_gnd = gnd_pin - - # Add to the right (first) gnd rail - m1m2_offset = right_gnd.bc() + vector(0,0.5*self.nmos.poly_height) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=m1m2_offset) - active_offset = right_gnd.bc() + vector(0,0.5*self.nmos.poly_height) + """ + Add a well and implant over the whole cell. Also, add the + pwell contact (if it exists) + """ + + # 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_offset, + offset=active_pos, implant_type="p", well_type="p") + # Add the M1->M2->M3 stack + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=active_pos) + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=active_pos) + self.add_layout_pin_rect_center(text="gnd", + layer="metal3", + offset=active_pos) + + + diff --git a/compiler/tests/04_single_level_column_mux_test.py b/compiler/tests/04_single_level_column_mux_test.py new file mode 100644 index 00000000..25bd953a --- /dev/null +++ b/compiler/tests/04_single_level_column_mux_test.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2.7 +""" +Run a regresion test on a wordline_driver array +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +#@unittest.skip("SKIPPING 04_driver_test") + +class single_level_column_mux_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + global verify + import verify + OPTS.check_lvsdrc = False + + import single_level_column_mux + import tech + + debug.info(2, "Checking column mux") + tx = single_level_column_mux.single_level_column_mux(tx_size=8) + self.local_check(tx) + + OPTS.check_lvsdrc = True + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/technology/scn3me_subm/gds_lib/sense_amp.gds b/technology/scn3me_subm/gds_lib/sense_amp.gds index c0582672..90a777d1 100644 Binary files a/technology/scn3me_subm/gds_lib/sense_amp.gds and b/technology/scn3me_subm/gds_lib/sense_amp.gds differ diff --git a/technology/scn3me_subm/mag_lib/sense_amp.mag b/technology/scn3me_subm/mag_lib/sense_amp.mag index 32dfb9d8..0300a61b 100644 --- a/technology/scn3me_subm/mag_lib/sense_amp.mag +++ b/technology/scn3me_subm/mag_lib/sense_amp.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1516827653 +timestamp 1523056564 << nwell >> rect 0 0 40 102 << pwell >> @@ -50,13 +50,10 @@ rect 6 20 10 44 rect 14 20 18 44 rect 22 20 26 44 rect 30 20 34 44 -<< nsubstratendiff >> -rect 18 64 22 66 -rect 18 58 22 60 << psubstratepcontact >> -rect 32 138 36 142 +rect 32 137 36 141 << nsubstratencontact >> -rect 18 60 22 64 +rect 27 70 31 74 << polysilicon >> rect 21 139 23 149 rect 21 129 23 130 @@ -90,8 +87,7 @@ rect 29 51 33 55 << metal1 >> rect -2 149 20 153 rect 24 149 36 153 -rect -2 142 32 146 -rect 24 139 28 142 +rect 28 133 32 137 rect 16 117 19 130 rect 7 94 11 108 rect 23 105 27 108 @@ -102,28 +98,25 @@ rect 15 78 19 80 rect 23 94 27 101 rect 23 78 27 80 rect 15 75 18 78 -rect 15 72 21 75 +rect 15 74 31 75 +rect 15 72 27 74 rect 7 65 9 69 -rect 18 66 21 72 -rect 18 64 22 66 -rect -2 60 18 62 -rect 22 60 36 62 -rect -2 58 36 60 rect 6 44 9 54 rect 33 51 34 55 rect 31 44 34 51 rect 3 20 6 23 rect 3 15 7 20 << m2contact >> -rect 32 142 36 146 +rect 32 133 36 137 +rect 27 66 31 70 rect 13 44 17 48 rect 22 44 26 48 rect 3 11 7 15 << metal2 >> rect 10 48 14 163 rect 20 48 24 163 -rect 32 146 36 163 -rect 32 138 36 142 +rect 32 129 36 133 +rect 27 62 31 66 rect 10 44 13 48 rect 20 44 22 48 rect 3 8 7 11 @@ -140,12 +133,12 @@ rect 2 3 8 4 << m3p >> rect 0 0 34 163 << labels >> -flabel metal1 0 58 0 58 4 FreeSans 26 0 0 0 vdd flabel metal1 0 149 0 149 4 FreeSans 26 0 0 0 en -flabel metal1 0 142 0 142 4 FreeSans 26 0 0 0 gnd flabel metal2 10 0 10 0 4 FreeSans 26 0 0 0 bl flabel metal2 20 0 20 0 4 FreeSans 26 0 0 0 br flabel metal3 3 3 3 3 4 FreeSans 26 0 0 0 dout +rlabel metal2 34 131 34 131 1 gnd +rlabel metal2 29 64 29 64 1 vdd << properties >> string path 270.000 468.000 270.000 486.000 288.000 486.000 288.000 468.000 270.000 468.000 << end >>