From 99507ba5c590b9fdf3b8ec956bf66eb3cb3c78fa Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Sat, 7 Sep 2019 23:22:01 -0700 Subject: [PATCH] Remove rbl_bl_delay_bar from w_en logic inputs. --- compiler/modules/control_logic.py | 51 ++++++++----------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index e62770d8..79db4d61 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -125,7 +125,7 @@ class control_logic(design.design): self.add_mod(self.wl_en_driver) # w_en drives every write driver - self.wen_and = factory.create(module_type="pand3", + self.wen_and = factory.create(module_type="pand2", size=self.word_size+8, height=dff_height) self.add_mod(self.wen_and) @@ -344,11 +344,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 = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"] + self.internal_bus_list = ["rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"] elif self.port_type == "r": - self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"] + self.internal_bus_list = ["rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"] else: - self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs"] + self.internal_bus_list = ["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 @@ -382,7 +382,6 @@ 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() @@ -420,9 +419,6 @@ 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 @@ -447,7 +443,6 @@ 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() @@ -463,6 +458,7 @@ class control_logic(design.design): """ Create the replica bitline """ self.delay_inst=self.add_inst(name="delay_chain", mod=self.delay_chain) + # rbl_bl_delay is asserted (1) when the bitline has been discharged self.connect_inst(["rbl_bl", "rbl_bl_delay", "vdd", "gnd"]) def place_delay(self,row): @@ -613,6 +609,8 @@ class control_logic(design.design): def create_pen_row(self): self.p_en_bar_nand_inst=self.add_inst(name="nand_p_en_bar", mod=self.nand2) + # We use the rbl_bl_delay here to ensure that the p_en is only asserted when the + # bitlines have already been discharged. Otherwise, it is a combination loop. self.connect_inst(["gated_clk_buf", "rbl_bl_delay", "p_en_bar_unbuf", "vdd", "gnd"]) self.p_en_bar_driver_inst=self.add_inst(name="buf_p_en_bar", @@ -647,6 +645,9 @@ class control_logic(design.design): # GATE FOR S_EN self.s_en_gate_inst = self.add_inst(name="buf_s_en_and", mod=self.sen_and3) + # s_en is asserted in the second half of the cycle during a read. + # we also must wait until the bitline has been discharged enough for proper sensing + # hence we use rbl_bl_delay as well. self.connect_inst(["rbl_bl_delay", "gated_clk_bar", input_name, "s_en", "vdd", "gnd"]) @@ -671,33 +672,6 @@ class control_logic(design.design): self.connect_output(self.s_en_gate_inst, "Z", "s_en") - 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 @@ -710,7 +684,8 @@ class control_logic(design.design): # GATE THE W_EN self.w_en_gate_inst = self.add_inst(name="w_en_and", mod=self.wen_and) - self.connect_inst([input_name, "rbl_bl_delay_bar", "gated_clk_bar", "w_en", "vdd", "gnd"]) + # Only drive the writes in the second half of the clock cycle during a write operation. + self.connect_inst([input_name, "gated_clk_bar", "w_en", "vdd", "gnd"]) def place_wen_row(self,row): @@ -727,7 +702,7 @@ class control_logic(design.design): # No we for write-only reports, so use cs input_name = "cs" - wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"]) + wen_map = zip(["A", "B"], [input_name, "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")