From 00a87d57ab12408b8ba93a184cc851a1e26ddace Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Thu, 26 Jul 2018 11:28:48 -0700 Subject: [PATCH] Modified pinvbuf to have a stage effort of 4 for driving the clock bar to wordline enable. Fixed comments in stimulus file to have right cycle numbers. Removed clock gating on we signal since clock gating is already done on the WL signals. It is redundant. --- compiler/characterizer/delay.py | 4 ++-- compiler/modules/control_logic.py | 16 +++++++++------- compiler/modules/wordline_driver.py | 4 ++-- compiler/pgates/pinvbuf.py | 21 ++++++++++++++++----- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 460f75ce..e586bf8a 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -661,11 +661,11 @@ class delay(): # One period msg = "Idle cycle (Read addr 00..00)" + self.cycle_times.append(t_current) + self.idle_cycle=len(self.cycle_times)-1 self.cycle_comments.append("Cycle{0}\t{1}ns:\t{2}".format(len(self.cycle_times)-1, t_current, msg)) - self.cycle_times.append(t_current) - self.idle_cycle=len(self.cycle_times)-1 t_current += self.period # One period diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index d6a7998d..570434ee 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -61,7 +61,9 @@ class control_logic(design.design): self.add_mod(self.nand3) # Special gates: inverters for buffering - self.clkbuf = pinvbuf(4,16,height=dff_height) + # Size the clock for the number of rows (fanout) + clock_driver_size = max(1,int(self.num_rows/4)) + self.clkbuf = pinvbuf(clock_driver_size,height=dff_height) self.add_mod(self.clkbuf) self.inv = self.inv1 = pinv(size=1, height=dff_height) self.add_mod(self.inv1) @@ -345,14 +347,14 @@ class control_logic(design.design): x_off = self.ctrl_dff_inst.width + self.internal_bus_width (y_off,mirror)=self.get_offset(row) - # input: WE, clk_buf_bar, CS output: w_en_bar + # input: WE, CS output: w_en_bar w_en_bar_offset = vector(x_off, y_off) - self.w_en_bar_inst=self.add_inst(name="nand3_w_en_bar", - mod=self.nand3, + self.w_en_bar_inst=self.add_inst(name="nand2_w_en_bar", + mod=self.nand2, offset=w_en_bar_offset, mirror=mirror) - self.connect_inst(["clk_buf_bar", "cs", "we", "w_en_bar", "vdd", "gnd"]) - x_off += self.nand3.width + self.connect_inst(["cs", "we", "w_en_bar", "vdd", "gnd"]) + x_off += self.nand2.width # input: w_en_bar, output: pre_w_en pre_w_en_offset = vector(x_off, y_off) @@ -458,7 +460,7 @@ class control_logic(design.design): def route_wen(self): - wen_map = zip(["A", "B", "C"], ["clk_buf_bar", "cs", "we"]) + wen_map = zip(["A", "B"], ["cs", "we"]) self.connect_vertical_bus(wen_map, self.w_en_bar_inst, self.rail_offsets) # Connect the NAND3 output to the inverter diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 8a41e147..2ddda761 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -127,14 +127,14 @@ class wordline_driver(design.design): mirror=inst_mirror)) self.connect_inst(["en_bar[{0}]".format(row), "in[{0}]".format(row), - "net[{0}]".format(row), + "wl_bar[{0}]".format(row), "vdd", "gnd"]) # add inv2 self.inv2_inst.append(self.add_inst(name=name_inv2, mod=self.inv, offset=inv2_offset, mirror=inst_mirror)) - self.connect_inst(["net[{0}]".format(row), + self.connect_inst(["wl_bar[{0}]".format(row), "wl[{0}]".format(row), "vdd", "gnd"]) diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index 94ec2a6f..3f483e05 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -15,20 +15,31 @@ class pinvbuf(design.design): c = reload(__import__(OPTS.bitcell)) bitcell = getattr(c, OPTS.bitcell) - def __init__(self, inv1_size=2, inv2_size=4, height=bitcell.height, name=""): + def __init__(self, driver_size=4, height=bitcell.height, name=""): + + stage_effort = 4 + # FIXME: Change the number of stages to support high drives. + + # stage effort of 4 or less + # The pinvbuf has a FO of 2 for the first stage, so the second stage + # should be sized "half" to prevent loading of the first stage + predriver_size = max(int(driver_size/(stage_effort/2)),1) if name=="": - name = "pinvbuf_{0}_{1}".format(inv1_size, inv2_size) + name = "pinvbuf_{0}_{1}".format(predriver_size, driver_size) design.design.__init__(self, name) debug.info(1, "Creating {}".format(self.name)) - self.inv = pinv(size=1, height=height) + + # Shield the cap, but have at least a stage effort of 4 + input_size = max(1,int(predriver_size/stage_effort)) + self.inv = pinv(size=input_size, height=height) self.add_mod(self.inv) - self.inv1 = pinv(size=inv1_size, height=height) + self.inv1 = pinv(size=predriver_size, height=height) self.add_mod(self.inv1) - self.inv2 = pinv(size=inv2_size, height=height) + self.inv2 = pinv(size=driver_size, height=height) self.add_mod(self.inv2) self.width = 2*self.inv1.width + self.inv2.width