mirror of https://github.com/openXC7/prjxray.git
Run make format.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
b14952e1da
commit
af8c1884d4
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue