From bac684a82a1c855752b98ced590177998fff69ef Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Sat, 10 Aug 2019 08:53:02 -0700 Subject: [PATCH] Fix control logic routing. --- compiler/modules/control_logic.py | 155 +++++++++++++++++------------- 1 file changed, 88 insertions(+), 67 deletions(-) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index c2d86da8..3ce7921a 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -343,11 +343,11 @@ class control_logic(design.design): # list of output control signals (for making a vertical bus) if self.port_type == "rw": - self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"] + self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"] elif self.port_type == "r": - self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"] + self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"] else: - self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "clk_buf", "cs"] + self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs"] # leave space for the bus plus one extra space self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch @@ -381,6 +381,7 @@ class control_logic(design.design): self.create_gated_clk_buf_row() self.create_wlen_row() if (self.port_type == "rw") or (self.port_type == "w"): + self.create_rbl_delay_row() self.create_wen_row() if (self.port_type == "rw") or (self.port_type == "r"): self.create_sen_row() @@ -418,6 +419,9 @@ class control_logic(design.design): row += 1 self.place_pen_row(row) row += 1 + if (self.port_type == "rw") or (self.port_type == "w"): + self.place_rbl_delay_row(row) + row += 1 if (self.port_type == "rw") or (self.port_type == "r"): self.place_sen_row(row) row += 1 @@ -442,6 +446,7 @@ class control_logic(design.design): self.route_dffs() self.route_wlen() if (self.port_type == "rw") or (self.port_type == "w"): + self.route_rbl_delay() self.route_wen() if (self.port_type == "rw") or (self.port_type == "r"): self.route_sen() @@ -469,7 +474,18 @@ class control_logic(design.design): self.delay_inst.place(offset, mirror="MY") def route_delay(self): + + out_pos = self.delay_inst.get_pin("out").bc() + # Connect to the rail level with the vdd rail + # Use pen since it is in every type of control logic + vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by() + in_pos = vector(self.rail_offsets["rbl_bl_delay"].x,vdd_ypos) + mid1 = vector(out_pos.x,in_pos.y) + self.add_wire(("metal1","via1","metal2"),[out_pos, mid1, in_pos]) + self.add_via_center(layers=("metal1","via1","metal2"), + offset=in_pos) + # Input from RBL goes to the delay line for futher delay self.copy_layout_pin(self.delay_inst, "in", "rbl_bl") @@ -481,12 +497,9 @@ class control_logic(design.design): self.connect_inst(["clk","clk_buf","vdd","gnd"]) def place_clk_buf_row(self,row): - """ Place the multistage clock buffer below the control flops """ - x_off = self.control_x_offset - (y_off,mirror)=self.get_offset(row) + x_offset = self.control_x_offset - offset = vector(x_off,y_off) - self.clk_buf_inst.place(offset, mirror) + x_offset = self.place_util(self.clk_buf_inst, x_offset, row) self.row_end_inst.append(self.clk_buf_inst) @@ -523,17 +536,10 @@ class control_logic(design.design): 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) + x_offset = self.control_x_offset - 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) + x_offset = self.place_util(self.clk_bar_inst, x_offset, row) + x_offset = self.place_util(self.gated_clk_bar_inst, x_offset, row) self.row_end_inst.append(self.gated_clk_bar_inst) @@ -567,12 +573,9 @@ class control_logic(design.design): 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.gated_clk_buf_inst.place(offset, mirror) + x_offset = self.control_x_offset + + x_offset = self.place_util(self.gated_clk_buf_inst, x_offset, row) self.row_end_inst.append(self.gated_clk_buf_inst) @@ -594,11 +597,9 @@ class control_logic(design.design): self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"]) def place_wlen_row(self, row): - x_off = self.control_x_offset - (y_off,mirror)=self.get_offset(row) - - offset = vector(x_off, y_off) - self.wl_en_inst.place(offset, mirror) + x_offset = self.control_x_offset + + x_offset = self.place_util(self.wl_en_inst, x_offset, row) self.row_end_inst.append(self.wl_en_inst) @@ -609,29 +610,32 @@ class control_logic(design.design): self.connect_output(self.wl_en_inst, "Z", "wl_en") def create_pen_row(self): - self.p_en_bar_inst=self.add_inst(name="nand_p_en_bar", - mod=self.nand2) + self.p_en_bar_nand_inst=self.add_inst(name="nand_p_en_bar", + mod=self.nand2) self.connect_inst(["gated_clk_buf", "rbl_bl_delay", "p_en_bar_unbuf", "vdd", "gnd"]) - self.p_en_bar_inst=self.add_inst(name="buf_p_en_bar", - mod=self.p_en_bar_driver) + self.p_en_bar_driver_inst=self.add_inst(name="buf_p_en_bar", + mod=self.p_en_bar_driver) self.connect_inst(["p_en_bar_unbuf", "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) + x_offset = self.control_x_offset - self.row_end_inst.append(self.p_en_bar_inst) + x_offset = self.place_util(self.p_en_bar_nand_inst, x_offset, row) + x_offset = self.place_util(self.p_en_bar_driver_inst, x_offset, row) + + self.row_end_inst.append(self.p_en_bar_driver_inst) def route_pen(self): - in_map = zip(["A"], ["gated_clk_buf"]) - self.connect_vertical_bus(in_map, self.p_en_bar_inst, self.rail_offsets) + in_map = zip(["A", "B"], ["gated_clk_buf", "rbl_bl_delay"]) + self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.rail_offsets) + + out_pos = self.p_en_bar_nand_inst.get_pin("Z").rc() + in_pos = self.p_en_bar_driver_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.p_en_bar_inst, "Z", "p_en_bar") + self.connect_output(self.p_en_bar_driver_inst, "Z", "p_en_bar") def create_sen_row(self): """ Create the sense enable buffer. """ @@ -646,15 +650,9 @@ class control_logic(design.design): def place_sen_row(self,row): - """ - The sense enable buffer gets placed to the far right of the - row. - """ - x_off = self.control_x_offset - (y_off,mirror)=self.get_offset(row) + x_offset = self.control_x_offset - offset = vector(x_off, y_off) - self.s_en_gate_inst.place(offset, mirror) + x_offset = self.place_util(self.s_en_gate_inst, x_offset, row) self.row_end_inst.append(self.s_en_gate_inst) @@ -666,23 +664,41 @@ class control_logic(design.design): else: input_name = "cs_bar" - sen_map = zip(["B"], [input_name]) + sen_map = zip(["A", "B"], ["rbl_bl_delay", input_name]) self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.rail_offsets) - out_pos = self.delay_inst.get_pin("out").bc() - in_pos = self.s_en_gate_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_gate_inst, "Z", "s_en") - def create_wen_row(self): + def create_rbl_delay_row(self): self.rbl_bl_delay_inv_inst = self.add_inst(name="rbl_bl_delay_inv", mod=self.inv) self.connect_inst(["rbl_bl_delay", "rbl_bl_delay_bar", "vdd", "gnd"]) + + def place_rbl_delay_row(self,row): + x_offset = self.control_x_offset + + x_offset = self.place_util(self.rbl_bl_delay_inv_inst, x_offset, row) + self.row_end_inst.append(self.rbl_bl_delay_inv_inst) + + def route_rbl_delay(self): + # Connect from delay line + # Connect to rail + + rbl_map = zip(["Z"], ["rbl_bl_delay_bar"]) + self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_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.rbl_bl_delay_inv_inst.get_pin("Z").center()) + + + rbl_map = zip(["A"], ["rbl_bl_delay"]) + self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets) + + def create_wen_row(self): + # input: we (or cs) output: w_en if self.port_type == "rw": input_name = "we" @@ -697,11 +713,9 @@ class control_logic(design.design): def place_wen_row(self,row): - x_off = self.ctrl_dff_inst.width + self.internal_bus_width - (y_off,mirror)=self.get_offset(row) - - offset = vector(x_off, y_off) - self.w_en_gate_inst.place(offset, mirror) + x_offset = self.control_x_offset + + x_offset = self.place_util(self.w_en_gate_inst, x_offset, row) self.row_end_inst.append(self.w_en_gate_inst) @@ -712,7 +726,7 @@ class control_logic(design.design): # No we for write-only reports, so use cs input_name = "cs" - wen_map = zip(["A", "B"], [input_name, "gated_clk_bar"]) + wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"]) self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets) self.connect_output(self.w_en_gate_inst, "Z", "w_en") @@ -791,9 +805,8 @@ class control_logic(design.design): self.add_power_pin("gnd", pin_loc) self.add_path("metal1", [row_loc, pin_loc]) - if (self.port_type == "rw") or (self.port_type == "r"): - self.copy_layout_pin(self.delay_inst,"gnd") - self.copy_layout_pin(self.delay_inst,"vdd") + self.copy_layout_pin(self.delay_inst,"gnd") + self.copy_layout_pin(self.delay_inst,"vdd") self.copy_layout_pin(self.ctrl_dff_inst,"gnd") self.copy_layout_pin(self.ctrl_dff_inst,"vdd") @@ -958,3 +971,11 @@ class control_logic(design.design): self.graph_inst_exclude.add(self.ctrl_dff_inst) if self.port_type=="rw" or self.port_type=="w": self.graph_inst_exclude.add(self.w_en_gate_inst) + + def place_util(self, inst, x_offset, row): + """ Utility to place a row and compute the next offset """ + + (y_offset,mirror)=self.get_offset(row) + offset = vector(x_offset, y_offset) + inst.place(offset, mirror) + return x_offset+inst.width