diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index b1ed2a0c..b025e4b1 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -92,9 +92,11 @@ class bank(design.design): """ Create routing amoung the modules """ self.route_central_bus() self.route_precharge_to_bitcell_array() + self.route_sense_amp_to_bitcell_array() self.route_sense_amp_to_trigate() self.route_tri_gate_out() self.route_wordline_driver() + self.route_write_driver() self.route_row_decoder() self.route_column_address_lines() self.route_control_lines() @@ -235,14 +237,16 @@ class bank(design.design): temp.extend(["vdd", "gnd"]) self.connect_inst(temp) - + # A space for wells or jogging m2 + self.m2_gap = max(2*drc["pwell_to_nwell"] + drc["well_enclosure_active"], + 2*self.m2_pitch) def add_precharge_array(self): """ Adding Precharge """ # The wells must be far enough apart # The enclosure is for the well and the spacing is to the bitcell wells - y_offset = self.bitcell_array.height + 2*drc["pwell_to_nwell"] + drc["well_enclosure_active"] + y_offset = self.bitcell_array.height + self.m2_gap self.precharge_array_inst=self.add_inst(name="precharge_array", mod=self.precharge_array, offset=vector(0,y_offset)) @@ -275,13 +279,13 @@ class bank(design.design): def add_sense_amp_array(self): """ Adding Sense amp """ - y_offset = self.column_mux_height + self.sense_amp_array.height + y_offset = self.column_mux_height + self.sense_amp_array.height + self.m2_gap self.sense_amp_array_inst=self.add_inst(name="sense_amp_array", mod=self.sense_amp_array, offset=vector(0,y_offset).scale(-1,-1)) temp = [] for i in range(self.word_size): - temp.append("data_out[{0}]".format(i)) + temp.append("sa_out[{0}]".format(i)) if self.words_per_row == 1: temp.append("bl[{0}]".format(i)) temp.append("br[{0}]".format(i)) @@ -295,7 +299,7 @@ class bank(design.design): def add_write_driver_array(self): """ Adding Write Driver """ - y_offset = self.sense_amp_array.height + self.column_mux_height + self.write_driver_array.height + y_offset = self.sense_amp_array.height + self.column_mux_height + + self.m2_gap + self.write_driver_array.height self.write_driver_array_inst=self.add_inst(name="write_driver_array", mod=self.write_driver_array, offset=vector(0,y_offset).scale(-1,-1)) @@ -316,14 +320,14 @@ class bank(design.design): def add_tri_gate_array(self): """ data tri gate to drive the data bus """ y_offset = self.sense_amp_array.height+self.column_mux_height \ - + self.write_driver_array.height + self.tri_gate_array.height + + self.write_driver_array.height + self.m2_gap + self.tri_gate_array.height self.tri_gate_array_inst=self.add_inst(name="tri_gate_array", mod=self.tri_gate_array, offset=vector(0,y_offset).scale(-1,-1)) temp = [] for i in range(self.word_size): - temp.append("data_out[{0}]".format(i)) + temp.append("sa_out[{0}]".format(i)) for i in range(self.word_size): temp.append("DOUT[{0}]".format(i)) temp.extend([self.prefix+"tri_en", self.prefix+"tri_en_bar", "vdd", "gnd"]) @@ -454,8 +458,10 @@ class bank(design.design): for inst in top_instances: - # These copy all pins if more thanone - self.copy_layout_pin(inst, "vdd") + print inst.name + # Column mux has no vdd + if self.col_addr_size>0 and inst != self.col_mux_array_inst: + self.copy_layout_pin(inst, "vdd") # Precharge has no gnd if inst != self.precharge_array_inst: self.copy_layout_pin(inst, "gnd") @@ -569,15 +575,34 @@ class bank(design.design): bitcell_bl = self.bitcell_array_inst.get_pin("bl[{}]".format(i)).uc() bitcell_br = self.bitcell_array_inst.get_pin("br[{}]".format(i)).uc() - self.add_path("metal2",[precharge_bl,bitcell_bl]) - self.add_path("metal2",[precharge_br,bitcell_br]) + yoffset = 0.5*(precharge_bl.y+bitcell_bl.y) + self.add_path("metal2",[precharge_bl, vector(precharge_bl.x,yoffset), + vector(bitcell_bl.x,yoffset), bitcell_bl]) + self.add_path("metal2",[precharge_br, vector(precharge_br.x,yoffset), + vector(bitcell_br.x,yoffset), bitcell_br]) + + def route_sense_amp_to_bitcell_array(self): + """ Routing of BL and BR between pre-charge and bitcell array """ + + for i in range(self.word_size): + sense_amp_bl = self.sense_amp_array_inst.get_pin("bl[{}]".format(i)).uc() + sense_amp_br = self.sense_amp_array_inst.get_pin("br[{}]".format(i)).uc() + bitcell_bl = self.bitcell_array_inst.get_pin("bl[{}]".format(i)).bc() + bitcell_br = self.bitcell_array_inst.get_pin("br[{}]".format(i)).bc() + + yoffset = 0.5*(sense_amp_bl.y+bitcell_bl.y) + self.add_path("metal2",[sense_amp_bl, vector(sense_amp_bl.x,yoffset), + vector(bitcell_bl.x,yoffset), bitcell_bl]) + self.add_path("metal2",[sense_amp_br, vector(sense_amp_br.x,yoffset), + vector(bitcell_br.x,yoffset), bitcell_br]) + def route_sense_amp_to_trigate(self): """ Routing of sense amp output to tri_gate input """ for i in range(self.word_size): # Connection of data_out of sense amp to data_in - tri_gate_in = self.tri_gate_array_inst.get_pin("in[{}]".format(i)).uc() + tri_gate_in = self.tri_gate_array_inst.get_pin("in[{}]".format(i)).lc() sa_data_out = self.sense_amp_array_inst.get_pin("data[{}]".format(i)).bc() self.add_path("metal2",[sa_data_out,tri_gate_in]) @@ -612,7 +637,7 @@ class bank(design.design): """ Metal 3 routing of tri_gate output data """ for i in range(self.word_size): data_pin = self.tri_gate_array_inst.get_pin("out[{}]".format(i)) - self.add_layout_pin_rect_center(text="DATA[{}]".format(i), + self.add_layout_pin_rect_center(text="DOUT[{}]".format(i), layer="metal2", offset=data_pin.center(), height=data_pin.height(), @@ -630,6 +655,13 @@ class bank(design.design): self.copy_layout_pin(self.row_decoder_inst, decoder_name, addr_name) + def route_write_driver(self): + """ Connecting write driver """ + + for i in range(self.word_size): + data_name = "data[{}]".format(i) + din_name = "DIN[{}]".format(i) + self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name) @@ -733,7 +765,7 @@ class bank(design.design): for i in range(self.word_size): data_name = "data[{}]".format(i) data_pin = self.sense_amp_array_inst.get_pin(data_name) - self.add_label(text="data_out[{}]".format(i), + self.add_label(text="sa_out[{}]".format(i), layer="metal3", offset=data_pin.ll()) diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index d65603a8..6658a093 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -85,19 +85,19 @@ class sense_amp_array(design.design): offset=vdd_pos) - self.add_layout_pin(text="bl[{0}]".format(i), + self.add_layout_pin(text="bl[{0}]".format(i/self.words_per_row), layer="metal2", offset=bl_offset, width=bl_pin.width(), height=bl_pin.height()) - self.add_layout_pin(text="br[{0}]".format(i), + self.add_layout_pin(text="br[{0}]".format(i/self.words_per_row), layer="metal2", offset=br_offset, width=br_pin.width(), height=br_pin.height()) self.add_layout_pin(text="data[{0}]".format(i/self.words_per_row), - layer="metal3", + layer="metal2", offset=dout_offset, width=dout_pin.width(), height=dout_pin.height()) diff --git a/technology/freepdk45/gds_lib/tri_gate.gds b/technology/freepdk45/gds_lib/tri_gate.gds index 129200d5..4879c9ef 100644 Binary files a/technology/freepdk45/gds_lib/tri_gate.gds and b/technology/freepdk45/gds_lib/tri_gate.gds differ diff --git a/technology/scn3me_subm/gds_lib/sense_amp.gds b/technology/scn3me_subm/gds_lib/sense_amp.gds index 90a777d1..6a826c56 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/gds_lib/tri_gate.gds b/technology/scn3me_subm/gds_lib/tri_gate.gds index 030a8150..2c0e3ace 100644 Binary files a/technology/scn3me_subm/gds_lib/tri_gate.gds and b/technology/scn3me_subm/gds_lib/tri_gate.gds differ diff --git a/technology/scn3me_subm/gds_lib/write_driver.gds b/technology/scn3me_subm/gds_lib/write_driver.gds index 59a5ac02..52b8e510 100644 Binary files a/technology/scn3me_subm/gds_lib/write_driver.gds and b/technology/scn3me_subm/gds_lib/write_driver.gds differ diff --git a/technology/scn3me_subm/mag_lib/sense_amp.mag b/technology/scn3me_subm/mag_lib/sense_amp.mag index 0300a61b..b29f7da0 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 1523056564 +timestamp 1524065550 << nwell >> rect 0 0 40 102 << pwell >> @@ -119,26 +119,18 @@ 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 -rect 3 0 7 4 +rect 3 0 7 11 rect 10 0 14 44 rect 20 0 24 44 -<< m3contact >> -rect 3 4 7 8 -<< metal3 >> -rect 2 8 8 9 -rect 2 4 3 8 -rect 7 4 8 8 -rect 2 3 8 4 << m3p >> rect 0 0 34 163 << labels >> flabel metal1 0 149 0 149 4 FreeSans 26 0 0 0 en -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 +rlabel metal2 12 161 12 161 5 bl +rlabel metal2 22 161 22 161 5 br +rlabel metal2 5 3 5 3 1 dout << properties >> string path 270.000 468.000 270.000 486.000 288.000 486.000 288.000 468.000 270.000 468.000 << end >> diff --git a/technology/scn3me_subm/mag_lib/tri_gate.mag b/technology/scn3me_subm/mag_lib/tri_gate.mag index 27c963f4..da973d0b 100644 --- a/technology/scn3me_subm/mag_lib/tri_gate.mag +++ b/technology/scn3me_subm/mag_lib/tri_gate.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1523484606 +timestamp 1524065602 << nwell >> rect -2 45 38 73 << pwell >> @@ -63,6 +63,7 @@ rect 16 38 20 42 rect 25 12 29 16 rect 28 4 32 8 << metal1 >> +rect 16 65 23 69 rect 12 61 16 65 rect 3 53 4 61 rect 3 42 6 53 @@ -78,12 +79,11 @@ rect 29 12 36 16 rect 0 4 28 8 rect 32 4 36 8 << m2contact >> -rect 8 65 12 69 +rect 23 65 27 69 rect 15 46 19 50 rect 25 34 29 38 rect 24 19 28 23 << metal2 >> -rect 15 50 19 73 rect 13 46 15 50 rect 15 34 25 38 rect 15 9 19 34 @@ -102,7 +102,7 @@ rect 0 0 34 73 rlabel metal1 0 12 0 12 3 en rlabel metal1 0 4 0 4 2 en_bar rlabel metal2 16 1 16 1 1 out -rlabel metal2 17 70 17 70 5 in -rlabel m2contact 10 67 10 67 1 vdd rlabel m2contact 26 21 26 21 1 gnd +rlabel m2contact 25 67 25 67 1 vdd +rlabel m2contact 17 48 17 48 1 in << end >> diff --git a/technology/scn3me_subm/mag_lib/write_driver.mag b/technology/scn3me_subm/mag_lib/write_driver.mag index 4395e8b0..5e80eff9 100644 --- a/technology/scn3me_subm/mag_lib/write_driver.mag +++ b/technology/scn3me_subm/mag_lib/write_driver.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1523920429 +timestamp 1523920689 << nwell >> rect -3 101 37 138 rect -3 0 37 51 @@ -159,7 +159,7 @@ rect 23 96 27 100 rect 3 71 7 75 rect 23 75 27 79 rect 7 24 11 28 -rect 16 10 20 14 +rect 15 10 19 14 << metal1 >> rect 5 192 10 196 rect 5 189 8 192 @@ -202,14 +202,12 @@ rect 16 118 20 122 rect 26 86 30 90 rect 19 64 23 68 rect 19 31 23 35 -rect 12 10 16 14 +rect 15 6 19 10 << metal2 >> rect 10 196 14 202 -rect 9 192 10 195 rect 20 193 24 202 rect 20 177 24 189 -rect 16 10 20 14 -rect 15 0 19 10 +rect 15 0 19 6 << m3p >> rect 0 0 34 202 << labels >>