6from ._synth_ops_gen
import *
7from .._mlir_libs._circt._synth
import _LongestPathAnalysis, _LongestPathCollection, _LongestPathDataflowPath, _LongestPathHistory, _LongestPathObject
9from dataclasses
import dataclass
10from typing
import Any, Dict, List, Union
20 Represents a single element in a hierarchical instance path.
21 In hardware design, modules are instantiated hierarchically. This class
22 represents one level in that hierarchy, containing both the module type
23 and the specific instance name.
25 instance_name: The name of this specific instance
26 module_name: The type/name of the module being instantiated
28 _instance: hw.InstanceOp
45 Represents a signal or port object in the dataflow graph.
46 This class encapsulates a specific signal within the hardware hierarchy,
47 including its location in the instance hierarchy, signal name, and bit position
48 for multi-bit signals.
50 instance_path: Hierarchical path to the module containing this object
51 name: The signal/port name within the module
52 bit_pos: Bit position for multi-bit signals (0 for single-bit)
55 _object: _LongestPathObject
61 Generate a human-readable string representation of this object.
62 Format: "module1:instance1/module2:instance2 signal_name[bit_pos]"
64 path =
"/".join(f
"{elem.module_name}:{elem.instance_name}"
66 return f
"{path} {self.name}[{self.bit_pos}]"
69 return f
"Object({self.instance_path}, {self.name}, {self.bit_pos})"
73 """Get the hierarchical instance path to this object."""
74 operations = self.
_object.instance_path
76 return [
Instance(op)
for op
in operations]
80 """Get the name of this signal/port."""
85 """Get the bit position for multi-bit signals."""
92 Represents a debug point in the timing path history.
93 Debug points are intermediate points along a timing path that provide
94 insight into the delay accumulation and signal propagation through
95 the circuit. Each point captures the state at a specific location.
97 object: The signal/object at this debug point
98 delay: Accumulated delay up to this point (in timing units)
99 comment: Optional descriptive comment about this point
107 def from_dict(cls, data: Dict[str, Any]) ->
"DebugPoint":
108 """Create a DebugPoint from a dictionary representation."""
110 object=Object.from_dict(data[
"object"]),
112 comment=data[
"comment"],
119 Represents a complete dataflow path from fan-out to fan-in.
120 A dataflow path captures the complete timing path through a circuit,
121 from an output point (fan-out) back to an input point (fan-in), including
122 all intermediate debug points and the total delay.
124 fan_out: The output signal/object where this path ends
125 path: The OpenPath containing the detailed path information
126 root: The root module name for this analysis
129 _path: _LongestPathDataflowPath
133 """Get the total delay of this path in timing units."""
134 return self.
_path.delay
138 """Get the input signal/object where this path begins."""
143 """Get the output signal/object where this path ends."""
148 """Get the history of debug points along this path."""
153 """Get the root module name for this analysis."""
154 return self.
_path.root.attributes[
"sym_name"].value
162 Convert this path to FlameGraph format for visualization.
163 FlameGraphs are a visualization technique that shows call stacks or
164 in this case, timing paths through the circuit hierarchy. Each line
165 represents a segment of the path with its associated delay.
166 The format is: "hierarchy_path delay_increment"
167 where hierarchy_path uses semicolons to separate hierarchy levels.
169 String in FlameGraph format showing the timing path progression
172 prefix = f
"top:{self.root}"
179 current_hierarchy = fan_in_hierarchy
183 for debug_point
in self.
history[::-1]:
186 if history_hierarchy:
188 delay_increment = debug_point.delay - current_delay
189 trace.append(f
"{current_hierarchy} {delay_increment}")
192 current_hierarchy = history_hierarchy
193 current_delay = debug_point.delay
196 if current_delay != self.
delay:
197 final_delay = self.
delay - current_delay
198 trace.append(f
"{fan_out_hierarchy} {final_delay}")
200 return "\n".join(trace)
204 Build a hierarchical string representation of an Object for FlameGraph format.
205 This method constructs a semicolon-separated hierarchy string that represents
206 the full path from the top-level module down to the specific signal. This
207 format is compatible with FlameGraph visualization tools.
209 obj: Object to represent in the hierarchy
210 prefix: Top-level prefix (typically "top:module_name")
212 Hierarchical string in format: "top:root;module1:inst1;module2:inst2;signal[bit]"
217 for elem
in obj.instance_path:
218 parts.append(f
"{elem.instance_name}:{elem.module_name}")
221 signal_part = obj.name
222 signal_part += f
"[{obj.bit_pos}]"
223 parts.append(signal_part)
225 return ";".join(parts)
235 A collection of timing paths sorted by delay (longest first).
236 This class provides a Python wrapper around the C++ LongestPathCollection,
237 offering convenient access to timing paths with caching for performance.
238 The paths are pre-sorted by delay in descending order.
240 collection: The underlying C++ collection object
241 length: Number of paths in the collection
246 Initialize the collection wrapper.
248 collection: The underlying C++ LongestPathCollection object
258 """Get the number of paths in the collection."""
262 self, index: Union[slice,
263 int]) -> Union[DataflowPath, List[DataflowPath]]:
265 Get a specific path from the collection by index.
266 Supports both integer and slice indexing. Integer indices can be negative.
269 index: Integer index or slice object to access paths
272 DataflowPath or list of DataflowPaths for slice access
275 IndexError: If index is out of range
277 if isinstance(index, slice):
278 return [self[i]
for i
in range(*index.indices(len(self)))]
283 if index < 0
or index >= self.
length:
284 raise IndexError(
"Index out of range")
294 """Get the path with the maximum delay (first element since sorted)."""
299 Get the path at the specified position in the delay-sorted collection.
300 Since paths are sorted by delay in descending order, higher ratios
301 correspond to paths with higher delays (closer to the critical path).
303 ratio: Position ratio between 0.0 and 1.0
304 (e.g., 1.0 = longest delay path, 0.0 = shortest delay path,
305 0.95 = path among the top 5% slowest paths)
307 DataflowPath at the specified position ratio
309 assert ratio >= 0.0
and ratio <= 1.0,
"Ratio must be between 0.0 and 1.0"
310 index = int(len(self) * (1 - ratio))
314 """Print a statistical summary of path delays in the collection."""
315 print(f
"Total paths: {len(self)}")
316 print(f
"Max delay: {self.longest_path.delay}")
317 print(f
"Min delay: {self[-1].delay}")
318 print(f
"50th percentile delay: {self.get_by_delay_ratio(0.5).delay}")
319 print(f
"90th percentile delay: {self.get_by_delay_ratio(0.9).delay}")
320 print(f
"95th percentile delay: {self.get_by_delay_ratio(0.95).delay}")
321 print(f
"99th percentile delay: {self.get_by_delay_ratio(0.99).delay}")
322 print(f
"99.9th percentile delay: {self.get_by_delay_ratio(0.999).delay}")
324 def merge(self, src:
"LongestPathCollection"):
326 Merge another collection into this one.
328 src: The collection to merge into this one
342 Main interface for performing longest path analysis on Synth dialect.
343 This class provides a Python wrapper around the C++ LongestPathAnalysis,
344 enabling timing analysis of Synth dialect. It can identify critical timing
345 paths and provide detailed path information.
347 analysis: The underlying C++ analysis object
352 collect_debug_info: bool =
True,
353 keep_only_max_delay_paths: bool =
False,
354 lazy_computation: bool =
False):
356 Initialize the longest path analysis for a given module.
358 module: The MLIR module to analyze
359 collect_debug_info: Whether to include debug points in the analysis.
360 Debug points provide additional information about the path,
361 but increase analysis time and memory usage.
362 keep_only_max_delay_paths: Keep only maximum-delay paths in collections.
363 lazy_computation: Enable lazy (on-demand) computation.
365 self.
analysis = synth._LongestPathAnalysis(module, collect_debug_info,
366 keep_only_max_delay_paths,
372 elaborate_paths: bool =
True) -> LongestPathCollection:
374 Perform longest path analysis and return all timing paths to the
375 specified value and bit position.
377 value: The value to analyze
378 bit_pos: The bit position to analyze
379 elaborate_paths: Whether to elaborate the paths with detailed information
381 LongestPathCollection containing all paths sorted by delay
388 elaborate_paths: bool =
True) -> LongestPathCollection:
390 Perform longest path analysis and return all timing paths inside
391 the module hierarchy.
392 This method analyzes the specified module and returns a collection
393 of all timing paths, sorted by delay in descending order.
395 module_name: Name of the module to analyze
397 LongestPathCollection containing all paths sorted by delay
406 Represents the history of a timing path, including intermediate debug points.
407 This class provides a Python wrapper around the C++ LongestPathHistory,
408 enabling iteration over the path's history and access to debug points.
410 history: The underlying C++ history object
412 history: _LongestPathHistory
415 """Iterate over the debug points in the history."""
static void print(TypedAttr val, llvm::raw_ostream &os)
List[DebugPoint] history(self)
_LongestPathDataflowPath _path
str _build_hierarchy_string(self, Object obj, str prefix="")
"DebugPoint" from_dict(cls, Dict[str, Any] data)
__init__(self, hw.InstanceOp instance)
LongestPathCollection get_paths(self, value, int bit_pos, bool elaborate_paths=True)
LongestPathCollection get_all_paths(self, str module_name, bool elaborate_paths=True)
__init__(self, module, bool collect_debug_info=True, bool keep_only_max_delay_paths=False, bool lazy_computation=False)
merge(self, "LongestPathCollection" src)
Union[DataflowPath, List[DataflowPath]] __getitem__(self, Union[slice, int] index)
DataflowPath longest_path(self)
DataflowPath get_by_delay_ratio(self, float ratio)
__init__(self, collection)
_LongestPathHistory history
List[Instance] instance_path(self)
_LongestPathObject _object