Run make format.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2019-05-07 12:37:14 -07:00
parent b14952e1da
commit af8c1884d4
2 changed files with 83 additions and 49 deletions

View File

@ -7,6 +7,7 @@ from prjxray.timing import fast_slow_tuple_to_corners, RcElement
TileDbs = namedtuple(
'TileDbs', 'segbits block_ram_segbits ppips mask tile_type')
class OutpinTiming(namedtuple('OutpinTiming', 'delays drive_resistance')):
""" Timing for site output pins.
@ -20,6 +21,7 @@ class OutpinTiming(namedtuple('OutpinTiming', 'delays drive_resistance')):
"""
pass
class InpinTiming(namedtuple('InpinTiming', 'delays capacitance')):
""" Timing for site input pins.
@ -33,7 +35,9 @@ class InpinTiming(namedtuple('InpinTiming', 'delays capacitance')):
"""
pass
class PipTiming(namedtuple('PipTiming', 'delays drive_resistance internal_capacitance')):
class PipTiming(namedtuple('PipTiming',
'delays drive_resistance internal_capacitance')):
""" Timing for pips.
Attributes
@ -48,9 +52,11 @@ class PipTiming(namedtuple('PipTiming', 'delays drive_resistance internal_capaci
"""
pass
class Pip(namedtuple(
'Pip', ('name', 'net_to', 'net_from', 'can_invert', 'is_directional',
'is_pseudo', 'is_pass_transitor', 'timing', 'backward_timing'))):
'Pip',
('name', 'net_to', 'net_from', 'can_invert', 'is_directional', 'is_pseudo',
'is_pass_transitor', 'timing', 'backward_timing'))):
""" Pip information.
Attributes
@ -85,6 +91,7 @@ class Pip(namedtuple(
"""
pass
class Site(namedtuple('Site', 'name prefix x y type site_pins')):
""" Represents an instance of a site within a tile.
@ -103,6 +110,7 @@ class Site(namedtuple('Site', 'name prefix x y type site_pins')):
"""
class SitePin(namedtuple('SitePin', 'name wire timing')):
""" Tuple representing a site pin within a tile.
@ -122,12 +130,14 @@ class SitePin(namedtuple('SitePin', 'name wire timing')):
"""
WireInfo = namedtuple('WireInfo', 'pips sites')
# Conversion factor from database to internal units.
RESISTANCE_FACTOR = 1
CAPACITANCE_FACTOR = 1e3
def get_pip_timing(pip_timing_json):
""" Convert pip_timing_json JSON into PipTiming object.
@ -149,19 +159,21 @@ def get_pip_timing(pip_timing_json):
in_cap = pip_timing_json.get('in_cap')
if in_cap is not None:
in_cap = float(in_cap)/CAPACITANCE_FACTOR
in_cap = float(in_cap) / CAPACITANCE_FACTOR
else:
in_cap = 0
res = pip_timing_json.get('res')
if res is not None:
res = float(res)/RESISTANCE_FACTOR
res = float(res) / RESISTANCE_FACTOR
else:
res = 0
return PipTiming(
delays=delays, drive_resistance=res, internal_capacitance=in_cap,
)
delays=delays,
drive_resistance=res,
internal_capacitance=in_cap,
)
def get_site_pin_timing(site_pin_info):
@ -187,15 +199,15 @@ def get_site_pin_timing(site_pin_info):
if 'cap' in site_pin_info:
assert 'res' not in site_pin_info
return wire, InpinTiming(
delays=delays,
capacitance=float(site_pin_info['cap'])/CAPACITANCE_FACTOR,
)
delays=delays,
capacitance=float(site_pin_info['cap']) / CAPACITANCE_FACTOR,
)
else:
assert 'res' in site_pin_info
return wire, OutpinTiming(
delays=delays,
drive_resistance=float(site_pin_info['res'])/RESISTANCE_FACTOR,
)
delays=delays,
drive_resistance=float(site_pin_info['res']) / RESISTANCE_FACTOR,
)
def get_wires(wires):
@ -212,17 +224,18 @@ def get_wires(wires):
for wire, rc_json in wires.items():
if rc_json is None:
output[wire] = RcElement(
resistance=0,
capacitance=0,
)
resistance=0,
capacitance=0,
)
else:
output[wire] = RcElement(
resistance=float(rc_json['res'])/RESISTANCE_FACTOR,
capacitance=float(rc_json['cap'])/CAPACITANCE_FACTOR,
)
resistance=float(rc_json['res']) / RESISTANCE_FACTOR,
capacitance=float(rc_json['cap']) / CAPACITANCE_FACTOR,
)
return output
def is_pass_transitor(pip_json):
""" Returns boolean if pip JSON indicates pip is a pass transistor.
@ -254,18 +267,18 @@ class Tile(object):
if site_pin_info is not None:
wire, timing = get_site_pin_timing(site_pin_info)
site_pins.append(
SitePin(
name=name,
wire=wire,
timing=timing,
))
SitePin(
name=name,
wire=wire,
timing=timing,
))
else:
site_pins.append(
SitePin(
name=name,
wire=None,
timing=None,
))
SitePin(
name=name,
wire=None,
timing=None,
))
yield Site(
name=site['name'],
@ -274,7 +287,7 @@ class Tile(object):
x=site['x_coord'],
y=site['y_coord'],
site_pins=site_pins,
)
)
def yield_pips(pips):
for name, pip in pips.items():

View File

@ -60,6 +60,7 @@ Example timing tree:
import enum
from collections import namedtuple
class PvtCorner(enum.Enum):
""" Process/voltage/temperature corner definitions. """
@ -69,6 +70,7 @@ class PvtCorner(enum.Enum):
# Corner where device operates with slowest intristic delays.
SLOW = "SLOW"
class IntristicDelay(namedtuple('IntristicDelay', 'min max')):
""" An intristic delay instance.
@ -91,6 +93,7 @@ class IntristicDelay(namedtuple('IntristicDelay', 'min max')):
Maximum instrinsic delay (nsec)
"""
class RcElement(namedtuple('RcElement', 'resistance capacitance')):
""" One part of an RcNode, embedded within an RcTree.
@ -122,23 +125,25 @@ def fast_slow_tuple_to_corners(arr):
fast_min, fast_max, slow_min, slow_max = map(float, arr)
return {
PvtCorner.FAST: IntristicDelay(
min=fast_min,
max=fast_max,
),
PvtCorner.SLOW: IntristicDelay(
min=slow_min,
max=slow_max,
),
}
PvtCorner.FAST: IntristicDelay(
min=fast_min,
max=fast_max,
),
PvtCorner.SLOW: IntristicDelay(
min=slow_min,
max=slow_max,
),
}
# Math models are used to represent abstract operations for the timing models.
# This is useful for creating excel workbooks that can update dynamically, or
# generating a model with symbolic constants to be backsolved.
class ExcelMathModel(object):
""" Math model used for outputting to an dyanmic Excel sheet. """
def __init__(self):
pass
@ -171,6 +176,7 @@ class ExcelMathModel(object):
def PythonMathModel(object):
""" Math model used for outputting values equalated immediately. """
def __init__(self):
pass
@ -184,17 +190,18 @@ def PythonMathModel(object):
return v
def divide(self, a, b):
return a/b
return a / b
def plus(self, a, b):
return a+b
return a + b
def multiply(self, a, b):
return a*b
return a * b
def eval(self, elem):
return elem
class TimingNode(object):
""" Base class for timing node models.
"""
@ -243,6 +250,7 @@ class DownstreamNode(TimingNode):
""" All non-root TimingNode's are DownstreamNode's.
"""
def propigate_delays(self, elements, math):
""" Propigates upstream delay elements to children of the tree.
@ -301,7 +309,8 @@ class Outpin(TimingNode):
def propigate_downstream_capacitance(self, math):
assert self.sink_wire is not None
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(math)
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(
math)
self.rc_delay = math.multiply(self.downstream_cap, self.resistance)
def propigate_delays(self, math):
@ -347,6 +356,7 @@ class Inpin(DownstreamNode):
Intristic delays on input pin.
"""
def __init__(self, capacitance, delays, name=None):
self.capacitance = capacitance
self.delays = delays
@ -393,6 +403,7 @@ class Wire(DownstreamNode):
Math model used to compute lumped resistance and capacitance.
"""
def __init__(self, rc_elements, math):
self.resistance = math.sum(elem.resistance for elem in rc_elements)
self.capacitance = math.sum(elem.capacitance for elem in rc_elements)
@ -417,11 +428,14 @@ class Wire(DownstreamNode):
self.children.append(child)
def propigate_downstream_capacitance(self, math):
downstream_cap = math.sum(child.propigate_downstream_capacitance(math) for child in self.children)
downstream_cap = math.sum(
child.propigate_downstream_capacitance(math)
for child in self.children)
# Pi-model is definied such that wire resistance only sees half of the
# wire capacitance.
self.downstream_cap = math.plus(math.divide(self.capacitance, 2), downstream_cap)
self.downstream_cap = math.plus(
math.divide(self.capacitance, 2), downstream_cap)
# Upstream seems all of the wires capacitance
return math.plus(downstream_cap, self.capacitance)
@ -445,6 +459,7 @@ class Wire(DownstreamNode):
assert self.downstream_cap is not None
return self.downstream_cap
class Buffer(DownstreamNode):
""" Represents an isolating switch.
@ -462,6 +477,7 @@ class Buffer(DownstreamNode):
Delay through switch
"""
def __init__(self, internal_capacitance, drive_resistance, delays):
self.internal_capacitance = internal_capacitance
self.drive_resistance = drive_resistance
@ -488,7 +504,8 @@ class Buffer(DownstreamNode):
def propigate_downstream_capacitance(self, math):
assert self.sink_wire is not None
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(math)
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(
math)
return self.internal_capacitance
def propigate_delays(self, elements, math):
@ -496,7 +513,8 @@ class Buffer(DownstreamNode):
assert self.sink_wire is not None
self.sink_wire.propigate_delays(self.propigated_delays + [self], math)
self.rc_delay = math.multiply(self.downstream_cap, self.drive_resistance)
self.rc_delay = math.multiply(
self.downstream_cap, self.drive_resistance)
def get_intrinsic_delays(self):
return self.delays
@ -521,6 +539,7 @@ class PassTransistor(DownstreamNode):
Delay through switch.
"""
def __init__(self, drive_resistance, delays):
self.drive_resistance = drive_resistance
self.delays = delays
@ -547,7 +566,8 @@ class PassTransistor(DownstreamNode):
def propigate_downstream_capacitance(self, math):
assert self.sink_wire is not None
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(math)
self.downstream_cap = self.sink_wire.propigate_downstream_capacitance(
math)
return self.downstream_cap
@ -556,7 +576,8 @@ class PassTransistor(DownstreamNode):
assert self.sink_wire is not None
self.sink_wire.propigate_delays(self.propigated_delays + [self], math)
self.rc_delay = math.multiply(self.downstream_cap, self.drive_resistance)
self.rc_delay = math.multiply(
self.downstream_cap, self.drive_resistance)
def get_intrinsic_delays(self):
return self.delays