From e750ef22f561a49a12b7d71210ed4857a4c04fd5 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Fri, 26 Jul 2019 21:41:27 -0700 Subject: [PATCH] Undo some control logic changes. --- compiler/modules/control_logic.py | 173 ++++++++++++------------------ 1 file changed, 66 insertions(+), 107 deletions(-) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 97acff81..e9b212fa 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -90,9 +90,10 @@ class control_logic(design.design): self.add_mod(self.ctrl_dff_array) - self.nand2 = factory.create(module_type="pnand2", + self.and2 = factory.create(module_type="pand2", + size=4, height=dff_height) - self.add_mod(self.nand2) + self.add_mod(self.and2) if self.port_type=="rw": self.rbl_driver = factory.create(module_type="pand2", @@ -124,24 +125,16 @@ class control_logic(design.design): self.add_mod(self.wl_en_driver) # w_en drives every write driver - self.wen_nand2 = factory.create(module_type="pnand2", - height=dff_height) - self.add_mod(self.wen_nand2) - self.wen_inv = factory.create(module_type="pdriver", - neg_polarity=True, - fanout=self.word_size+8, - height=dff_height) - self.add_mod(self.wen_inv) + self.wen_and2 = factory.create(module_type="pand2", + size=self.word_size+8, + height=dff_height) + self.add_mod(self.wen_and2) # s_en drives every sense amp - self.and2 = factory.create(module_type="pand2", - height=dff_height) - self.add_mod(self.and2) - self.sen_inv = factory.create(module_type="pdriver", - neg_polarity=True, - fanout=self.word_size, - height=dff_height) - self.add_mod(self.sen_inv) + self.sen_and2 = factory.create(module_type="pand2", + size=self.word_size, + height=dff_height) + self.add_mod(self.sen_and2) # used to generate inverted signals with low fanout self.inv = factory.create(module_type="pinv", @@ -469,7 +462,7 @@ class control_logic(design.design): def place_delay(self,row): """ Place the replica bitline """ - y_off = row * self.nand2.height + 2*self.m1_pitch + y_off = row * self.and2.height + 2*self.m1_pitch # Add the RBL above the rows # Add to the right of the control rows and routing channel @@ -510,7 +503,6 @@ class control_logic(design.design): mid2 = vector(self.rail_offsets["clk_buf"].x, mid1.y) bus_pos = self.rail_offsets["clk_buf"] self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, mid2, bus_pos]) - # The pin is on M1, so we need another via as well self.add_via_center(layers=("metal1","via1","metal2"), offset=self.clk_buf_inst.get_pin("Z").center()) @@ -518,30 +510,46 @@ class control_logic(design.design): self.connect_output(self.clk_buf_inst, "Z", "clk_buf") def create_gated_clk_bar_row(self): - self.gated_clk_bar_inst = self.add_inst(name="gated_clk_bar_nand2", - mod=self.nand2) - self.connect_inst(["cs","clk_buf","gated_clk_bar","vdd","gnd"]) + self.clk_bar_inst = self.add_inst(name="inv_clk_bar", + mod=self.inv) + self.connect_inst(["clk_buf","clk_bar","vdd","gnd"]) + + self.gated_clk_bar_inst = self.add_inst(name="and2_gated_clk_bar", + mod=self.and2) + self.connect_inst(["cs","clk_bar","gated_clk_bar","vdd","gnd"]) def place_gated_clk_bar_row(self,row): """ Place the gated clk logic below the control flops """ x_off = self.control_x_offset (y_off,mirror)=self.get_offset(row) + offset = vector(x_off,y_off) + self.clk_bar_inst.place(offset, mirror) + + x_off += self.inv.width + offset = vector(x_off,y_off) self.gated_clk_bar_inst.place(offset, mirror) self.row_end_inst.append(self.gated_clk_bar_inst) def route_gated_clk_bar(self): + clkbuf_map = zip(["A"], ["clk_buf"]) + self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.rail_offsets) + out_pos = self.clk_bar_inst.get_pin("Z").center() + in_pos = self.gated_clk_bar_inst.get_pin("B").center() + mid1 = vector(in_pos.x,out_pos.y) + self.add_path("metal1",[out_pos, mid1, in_pos]) - clkbuf_map = zip(["A", "B"], ["cs", "clk_buf"]) - self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets) - + # This is the second gate over, so it needs to be on M3 + clkbuf_map = zip(["A"], ["cs"]) + self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) # The pin is on M1, so we need another via as well self.add_via_center(layers=("metal1","via1","metal2"), offset=self.gated_clk_bar_inst.get_pin("A").center()) + # This is the second gate over, so it needs to be on M3 clkbuf_map = zip(["Z"], ["gated_clk_bar"]) self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) @@ -550,23 +558,14 @@ class control_logic(design.design): offset=self.gated_clk_bar_inst.get_pin("Z").center()) def create_gated_clk_buf_row(self): - self.clk_bar_inst = self.add_inst(name="clk_bar_inv", - mod=self.inv) - self.connect_inst(["clk_buf","clk_bar","vdd","gnd"]) - - self.gated_clk_buf_inst = self.add_inst(name="gated_clk_nand2", - mod=self.nand2) - self.connect_inst(["clk_bar", "cs","gated_clk_buf","vdd","gnd"]) + self.gated_clk_buf_inst = self.add_inst(name="and2_gated_clk_buf", + mod=self.and2) + self.connect_inst(["clk_buf", "cs","gated_clk_buf","vdd","gnd"]) def place_gated_clk_buf_row(self,row): """ Place the gated clk logic below the control flops """ x_off = self.control_x_offset (y_off,mirror)=self.get_offset(row) - - offset = vector(x_off,y_off) - self.clk_bar_inst.place(offset, mirror) - - x_off += self.inv.width offset = vector(x_off,y_off) self.gated_clk_buf_inst.place(offset, mirror) @@ -574,20 +573,8 @@ class control_logic(design.design): self.row_end_inst.append(self.gated_clk_buf_inst) def route_gated_clk_buf(self): - clkbuf_map = zip(["A"], ["clk_buf"]) - self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.rail_offsets) - - out_pos = self.clk_bar_inst.get_pin("Z").center() - in_pos = self.gated_clk_buf_inst.get_pin("A").center() - mid1 = vector(in_pos.x,out_pos.y) - self.add_path("metal1",[out_pos, mid1, in_pos]) - - # This is the second gate over, so it needs to be on M3 - clkbuf_map = zip(["B"], ["cs"]) - self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("metal3", "via2", "metal2")) - # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), - offset=self.gated_clk_buf_inst.get_pin("B").center()) + clkbuf_map = zip(["A", "B"], ["clk_buf", "cs"]) + self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets) clkbuf_map = zip(["Z"], ["gated_clk_buf"]) @@ -598,7 +585,7 @@ class control_logic(design.design): def create_wlen_row(self): # input pre_p_en, output: wl_en - self.wl_en_inst=self.add_inst(name="wl_en_buf", + self.wl_en_inst=self.add_inst(name="buf_wl_en", mod=self.wl_en_driver) self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"]) @@ -651,24 +638,24 @@ class control_logic(design.design): self.copy_layout_pin(self.delay_inst, "in", "rbl_bl") def create_pen_row(self): - # input: gated_clk_bar, output: p_en_bar - self.p_en_bar_inst=self.add_inst(name="p_en_bar_inv", + input_name = "gated_clk_buf" + + # input: pre_p_en, output: p_en_bar + self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar", mod=self.p_en_bar_driver) - self.connect_inst(["gated_clk_bar", "p_en_bar", "vdd", "gnd"]) + self.connect_inst([input_name, "p_en_bar", "vdd", "gnd"]) def place_pen_row(self,row): x_off = self.control_x_offset (y_off,mirror)=self.get_offset(row) - offset = vector(x_off,y_off) self.p_en_bar_inst.place(offset, mirror) self.row_end_inst.append(self.p_en_bar_inst) def route_pen(self): - - in_map = zip(["A"], ["gated_clk_bar"]) + in_map = zip(["A"], ["gated_clk_buf"]) self.connect_vertical_bus(in_map, self.p_en_bar_inst, self.rail_offsets) self.connect_output(self.p_en_bar_inst, "Z", "p_en_bar") @@ -676,13 +663,9 @@ class control_logic(design.design): def create_sen_row(self): """ Create the sense enable buffer. """ # GATE FOR S_EN - self.s_en_gate_inst = self.add_inst(name="s_en_and", - mod=self.and2) - self.connect_inst(["pre_s_en", "gated_clk_bar", "s_en_bar", "vdd", "gnd"]) - - self.s_en_inv_inst = self.add_inst(name="s_en_inv", - mod=self.sen_inv) - self.connect_inst(["s_en_bar", "s_en", "vdd", "gnd"]) + self.s_en_gate_inst = self.add_inst(name="buf_s_en_and", + mod=self.sen_and2) + self.connect_inst(["pre_s_en", "gated_clk_bar", "s_en", "vdd", "gnd"]) def place_sen_row(self,row): @@ -695,14 +678,8 @@ class control_logic(design.design): offset = vector(x_off, y_off) self.s_en_gate_inst.place(offset, mirror) - - x_off += self.and2.width - offset = vector(x_off,y_off) - self.s_en_inv_inst.place(offset, mirror) - - - self.row_end_inst.append(self.s_en_inv_inst) + self.row_end_inst.append(self.s_en_gate_inst) def route_sen(self): @@ -715,12 +692,7 @@ class control_logic(design.design): mid1 = vector(out_pos.x,in_pos.y) self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) - out_pos = self.s_en_gate_inst.get_pin("Z").bc() - in_pos = self.s_en_inv_inst.get_pin("A").lc() - mid1 = vector(out_pos.x,in_pos.y) - self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) - - self.connect_output(self.s_en_inv_inst, "Z", "s_en") + self.connect_output(self.s_en_gate_inst, "Z", "s_en") def create_wen_row(self): @@ -732,14 +704,9 @@ class control_logic(design.design): input_name = "cs" # GATE THE W_EN - self.w_en_gate_inst = self.add_inst(name="w_en_nand", - mod=self.wen_nand2) - self.connect_inst([input_name, "gated_clk_bar", "w_en_bar", "vdd", "gnd"]) - - - self.w_en_inv_inst = self.add_inst(name="w_en_inv", - mod=self.wen_inv) - self.connect_inst(["w_en_bar", "w_en", "vdd", "gnd"]) + self.w_en_gate_inst = self.add_inst(name="buf_w_en_and", + mod=self.wen_and2) + self.connect_inst([input_name, "gated_clk_bar", "w_en", "vdd", "gnd"]) def place_wen_row(self,row): @@ -748,13 +715,8 @@ class control_logic(design.design): offset = vector(x_off, y_off) self.w_en_gate_inst.place(offset, mirror) - - x_off += self.nand2.width - offset = vector(x_off,y_off) - self.w_en_inv_inst.place(offset, mirror) - - self.row_end_inst.append(self.w_en_inv_inst) + self.row_end_inst.append(self.w_en_gate_inst) def route_wen(self): if self.port_type == "rw": @@ -766,12 +728,7 @@ class control_logic(design.design): wen_map = zip(["A", "B"], [input_name, "gated_clk_bar"]) self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets) - out_pos = self.w_en_gate_inst.get_pin("Z").bc() - in_pos = self.w_en_inv_inst.get_pin("A").lc() - mid1 = vector(out_pos.x,in_pos.y) - self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) - - self.connect_output(self.w_en_inv_inst, "Z", "w_en") + self.connect_output(self.w_en_gate_inst, "Z", "w_en") def create_dffs(self): self.ctrl_dff_inst=self.add_inst(name="ctrl_dffs", @@ -784,6 +741,8 @@ class control_logic(design.design): def route_dffs(self): if self.port_type == "rw": dff_out_map = zip(["dout_bar_0", "dout_bar_1", "dout_1"], ["cs", "we", "we_bar"]) + elif self.port_type == "r": + dff_out_map = zip(["dout_bar_0", "dout_0"], ["cs", "cs_bar"]) else: dff_out_map = zip(["dout_bar_0"], ["cs"]) self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, ("metal3", "via2", "metal2")) @@ -802,9 +761,9 @@ class control_logic(design.design): def get_offset(self,row): """ Compute the y-offset and mirroring """ - y_off = row*self.nand2.height + y_off = row*self.and2.height if row % 2: - y_off += self.nand2.height + y_off += self.and2.height mirror="MX" else: mirror="R0" @@ -930,11 +889,11 @@ class control_logic(design.design): #First stage, gated_clk_bar -(and2)-> rbl_in. Only for RW ports. if self.port_type == "rw": stage1_cout = self.replica_bitline.get_en_cin() - stage_effort_list += self.nand2.get_stage_efforts(stage1_cout, last_stage_rise) + stage_effort_list += self.and2.get_stage_efforts(stage1_cout, last_stage_rise) last_stage_rise = stage_effort_list[-1].is_rise #Replica bitline stage, rbl_in -(rbl)-> pre_s_en - stage2_cout = self.and2.get_cin() + stage2_cout = self.sen_and2.get_cin() stage_effort_list += self.replica_bitline.determine_sen_stage_efforts(stage2_cout, last_stage_rise) last_stage_rise = stage_effort_list[-1].is_rise @@ -970,8 +929,8 @@ class control_logic(design.design): last_stage_rise = stage_effort_list[-1].is_rise #Second stage, clk_buf -(inv)-> clk_bar - clk_bar_cout = self.nand2.get_cin() - stage_effort_list += self.nand2.get_stage_efforts(clk_bar_cout, last_stage_rise) + clk_bar_cout = self.and2.get_cin() + stage_effort_list += self.and2.get_stage_efforts(clk_bar_cout, last_stage_rise) last_stage_rise = stage_effort_list[-1].is_rise #Third stage clk_bar -(and)-> gated_clk_bar @@ -990,7 +949,7 @@ class control_logic(design.design): """ #Control logic internal load - int_clk_buf_cap = self.inv.get_cin() + self.ctrl_dff_array.get_clk_cin() + self.nand2.get_cin() + int_clk_buf_cap = self.inv.get_cin() + self.ctrl_dff_array.get_clk_cin() + self.and2.get_cin() #Control logic external load (in the other parts of the SRAM) ext_clk_buf_cap = self.sram.get_clk_bar_cin() @@ -1003,7 +962,7 @@ class control_logic(design.design): total_cin = 0 total_cin += self.wl_en_driver.get_cin() if self.port_type == 'rw': - total_cin +=self.nand2.get_cin() + total_cin +=self.and2.get_cin() return total_cin def graph_exclude_dffs(self):