From 653ab3eda421dc03c24a6bfe3e2d331da77f6877 Mon Sep 17 00:00:00 2001 From: Jennifer Eve Sowash Date: Thu, 6 Dec 2018 19:34:19 -0800 Subject: [PATCH] Changed method of determining number of inverters. --- compiler/pgates/pdriver.py | 64 +++++++++++++++++++++++-------- compiler/tests/04_pdriver_test.py | 6 +-- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index bdf06050..74d21376 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -14,6 +14,7 @@ class pdriver(pgate.pgate): unique_id = 1 inv_list = [] inv_inst_list = [] + calc_size_list = [] def __init__(self, height=None, name="", neg_polarity=False, c_load=8, size_list = []): @@ -29,8 +30,7 @@ class pdriver(pgate.pgate): self.compute_sizes() if name=="": - name = "pdriver_{0}_{1}_{2}".format(self.stage_effort, self.num_inv, - pdriver.unique_id) + name = "pdriver_{0}_{1}_".format(self.num_inv, pdriver.unique_id) pdriver.unique_id += 1 pgate.pgate.__init__(self, name) @@ -47,20 +47,54 @@ class pdriver(pgate.pgate): neg_polarity = True self.num_inv = len(self.size_list) else: - # rho with p_inv = 1 - rho = 3.59 - num_stages = max(1, int(math.log1p(self.stage_effort)/math.log1p(rho))) + # find the number of stages + c_prev = int(round(self.c_load/self.stage_effort)) + num_stages = 1 + while c_prev > 1: #stop when the first stage is 1 + c_prev = int(round(c_prev/self.stage_effort)) + num_stages+=1 + + # find inv_num and compute sizes if self.neg_polarity: if (num_stages % 2 == 0): # if num_stages is even - self.num_inv = int(num_stages)+1 + self.diff_polarity(num_stages=num_stages) else: # if num_stages is odd - self.num_inv = int(num_stages) + self.same_polarity(num_stages=num_stages) else: # positive polarity if (num_stages % 2 == 0): - self.num_inv = int(num_stages) + self.same_polarity(num_stages=num_stages) else: - self.num_inv = int(num_stages)+1 - + self.diff_polarity(num_stages=num_stages) + + + def same_polarity(self, num_stages): + self.num_inv = num_stages + # compute sizes + c_prev = self.c_load + for x in range(self.num_inv-1,-1,-1): + c_prev = int(round(c_prev/self.stage_effort)) + self.calc_size_list.append(c_prev) + + + def diff_polarity(self, num_stages): + # find which delay is smaller + delay_below = ((num_stages-1)*(self.c_load**(1/num_stages-1))) + num_stages-1 + delay_above = ((num_stages+1)*(self.c_load**(1/num_stages+1))) + num_stages+1 + if (delay_above < delay_below): + # recompute stage_effort for this delay + self.num_inv = num_stages+1 + polarity_stage_effort = self.c_load**(1/self.num_inv) + else: + self.num_inv = num_stages-1 + polarity_stage_effort = self.c_load**(1/self.num_inv) + + # compute sizes + c_prev = self.c_load + for x in range(self.num_inv-1,-1,-1): + c_prev = int(round(c_prev/polarity_stage_effort)) + self.calc_size_list.append(c_prev) + + def create_netlist(self): self.add_pins() self.add_modules() @@ -88,13 +122,11 @@ class pdriver(pgate.pgate): self.inv_list.append(pinv(size=self.size_list[x], height=self.row_height)) self.add_mod(self.inv_list[x]) else: # find inv sizes - # work backwards to find the size of each stage - for x in range(self.num_inv-1, -1, -1): - c_in = max(1, int(round(self.c_load/self.stage_effort,0))) - self.c_load = c_in - self.inv_list.append(pinv(size=c_in, height=self.row_height)) + for x in range(len(self.calc_size_list)): + self.inv_list.append(pinv(size=self.calc_size_list[x], height=self.row_height)) self.add_mod(self.inv_list[x]) - + + def create_insts(self): for x in range(1,self.num_inv+1): # Create first inverter diff --git a/compiler/tests/04_pdriver_test.py b/compiler/tests/04_pdriver_test.py index 16dce58a..1cd450c5 100644 --- a/compiler/tests/04_pdriver_test.py +++ b/compiler/tests/04_pdriver_test.py @@ -24,10 +24,10 @@ class pdriver_test(openram_test): # a tests the error message for specifying conflicting conditions #a = pdriver.pdriver(c_load = 4,size_list = [1,2,4,8]) b = pdriver.pdriver(size_list = [1,2,4,8]) - c = pdriver.pdriver(c_load = 4) - d = pdriver.pdriver(c_load = 4, neg_polarity = True) + c = pdriver.pdriver(c_load = 50) + d = pdriver.pdriver(c_load = 50, neg_polarity = True) e = pdriver.pdriver(c_load = 64) - f = pdriver.pdriver(c_load = 64, neg_polarity = False) + f = pdriver.pdriver(c_load = 64, neg_polarity = True) #self.local_check(a) self.local_check(b) self.local_check(c)