mirror of https://github.com/VLSIDA/OpenRAM.git
Sometimes round down pdriver to fix polarity
This commit is contained in:
parent
35e65fc6f2
commit
a2422cc8d4
|
|
@ -65,9 +65,9 @@ class wordline_driver(design.design):
|
|||
self.add_mod(self.nand2)
|
||||
|
||||
def route_vdd_gnd(self):
|
||||
"""
|
||||
Add a pin for each row of vdd/gnd which
|
||||
are must-connects next level up.
|
||||
"""
|
||||
Add a pin for each row of vdd/gnd which
|
||||
are must-connects next level up.
|
||||
"""
|
||||
|
||||
# Find the x offsets for where the vias/pins should be placed
|
||||
|
|
@ -91,8 +91,8 @@ class wordline_driver(design.design):
|
|||
self.add_power_pin(name, pin_pos)
|
||||
|
||||
def create_drivers(self):
|
||||
self.nand_inst = []
|
||||
self.inv2_inst = []
|
||||
self.nand_inst = []
|
||||
self.inv2_inst = []
|
||||
for row in range(self.rows):
|
||||
name_nand = "wl_driver_nand{}".format(row)
|
||||
name_inv2 = "wl_driver_inv{}".format(row)
|
||||
|
|
@ -164,7 +164,7 @@ class wordline_driver(design.design):
|
|||
# Nand2 out to 2nd inv
|
||||
zr_pos = nand_inst.get_pin("Z").rc()
|
||||
al_pos = inv2_inst.get_pin("A").lc()
|
||||
# ensure the bend is in the middle
|
||||
# ensure the bend is in the middle
|
||||
mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y)
|
||||
mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y)
|
||||
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ class pdriver(pgate.pgate):
|
|||
self.size_list = size_list
|
||||
self.fanout = fanout
|
||||
|
||||
if not size_list and self.fanout == 0:
|
||||
debug.error("Either fanout or size list must be specified.", -1)
|
||||
if self.size_list and self.fanout != 0:
|
||||
debug.error("Cannot specify both size_list and fanout.", -1)
|
||||
if self.size_list and self.neg_polarity:
|
||||
debug.error("Cannot specify both size_list and neg_polarity.", -1)
|
||||
debug.check(self.size_list or self.fanout > 0,
|
||||
"Either fanout or size list must be specified.")
|
||||
debug.check(not (self.size_list and self.fanout > 0),
|
||||
"Cannot specify both size_list and fanout.")
|
||||
debug.check(not (self.size_list and self.neg_polarity),
|
||||
"Cannot specify both size_list and neg_polarity.")
|
||||
|
||||
# Creates the netlist and layout
|
||||
pgate.pgate.__init__(self, name, height)
|
||||
|
|
@ -43,21 +43,44 @@ class pdriver(pgate.pgate):
|
|||
self.num_stages = len(self.size_list)
|
||||
else:
|
||||
# Find the optimal number of stages for the given effort
|
||||
self.num_stages = max(1,
|
||||
int(round(self.fanout ** (1 / self.stage_effort))))
|
||||
optimal_stages = self.fanout ** (1 / self.stage_effort)
|
||||
rounded_stages = int(round(optimal_stages))
|
||||
difference = optimal_stages - rounded_stages
|
||||
|
||||
# Increase the number of stages if we need to fix polarity
|
||||
if self.neg_polarity and (self.num_stages % 2 == 0):
|
||||
self.num_stages += 1
|
||||
elif not self.neg_polarity and (self.num_stages % 2):
|
||||
self.num_stages += 1
|
||||
|
||||
# Determine if we need to fix the polarity
|
||||
if self.neg_polarity and (rounded_stages % 2 == 0):
|
||||
wrong_polarity = True
|
||||
elif not self.neg_polarity and (optimal_stages % 2):
|
||||
wrong_polarity = True
|
||||
else:
|
||||
wrong_polarity = False
|
||||
|
||||
# Depending on the difference, round up or down.
|
||||
if wrong_polarity:
|
||||
# If we rounded up and can round down, do it.
|
||||
if difference < 0 and rounded_stages > 1:
|
||||
rounded_stages -= 1
|
||||
else:
|
||||
# Otherwise, we must round up
|
||||
rounded_stages += 1
|
||||
|
||||
if self.neg_polarity:
|
||||
# Need at least one stage for negative
|
||||
self.num_stages = max(1, rounded_stages)
|
||||
else:
|
||||
# Need at least two stages for positive
|
||||
self.num_stages = max(2, rounded_stages)
|
||||
|
||||
# Use the actual stage effort
|
||||
actual_stage_effort = self.fanout / self.num_stages
|
||||
|
||||
self.size_list = []
|
||||
# compute sizes backwards from the fanout
|
||||
fanout_prev = self.fanout
|
||||
for x in range(self.num_stages):
|
||||
fanout_prev = max(round(fanout_prev / self.stage_effort), 1)
|
||||
self.size_list.append(fanout_prev)
|
||||
fanout_prev = fanout_prev / actual_stage_effort
|
||||
self.size_list.append(max(round(fanout_prev), 1))
|
||||
|
||||
# reverse the sizes to be from input to output
|
||||
self.size_list.reverse()
|
||||
|
|
|
|||
Loading…
Reference in New Issue