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 end point to start point.
120 A dataflow path captures the complete timing path through a circuit,
121 from an output point (end-point) back to an input point (start-point), including
122 all intermediate debug points and the total delay.
124 end_point: 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}"
180 current_hierarchy = start_point_hierarchy
184 for debug_point
in self.
history[::-1]:
187 if history_hierarchy:
189 delay_increment = debug_point.delay - current_delay
190 trace.append(f
"{current_hierarchy} {delay_increment}")
193 current_hierarchy = history_hierarchy
194 current_delay = debug_point.delay
197 if current_delay != self.
delay:
198 final_delay = self.
delay - current_delay
199 trace.append(f
"{end_point_hierarchy} {final_delay}")
201 return "\n".join(trace)
205 Build a hierarchical string representation of an Object for FlameGraph format.
206 This method constructs a semicolon-separated hierarchy string that represents
207 the full path from the top-level module down to the specific signal. This
208 format is compatible with FlameGraph visualization tools.
210 obj: Object to represent in the hierarchy
211 prefix: Top-level prefix (typically "top:module_name")
213 Hierarchical string in format: "top:root;module1:inst1;module2:inst2;signal[bit]"
218 for elem
in obj.instance_path:
219 parts.append(f
"{elem.instance_name}:{elem.module_name}")
222 signal_part = obj.name
223 signal_part += f
"[{obj.bit_pos}]"
224 parts.append(signal_part)
226 return ";".join(parts)
236 A collection of timing paths sorted by delay (longest first).
237 This class provides a Python wrapper around the C++ LongestPathCollection,
238 offering convenient access to timing paths with caching for performance.
239 The paths are pre-sorted by delay in descending order.
241 collection: The underlying C++ collection object
242 length: Number of paths in the collection
247 Initialize the collection wrapper.
249 collection: The underlying C++ LongestPathCollection object
259 """Get the number of paths in the collection."""
263 self, index: Union[slice,
264 int]) -> Union[DataflowPath, List[DataflowPath]]:
266 Get a specific path from the collection by index.
267 Supports both integer and slice indexing. Integer indices can be negative.
270 index: Integer index or slice object to access paths
273 DataflowPath or list of DataflowPaths for slice access
276 IndexError: If index is out of range
278 if isinstance(index, slice):
279 return [self[i]
for i
in range(*index.indices(len(self)))]
284 if index < 0
or index >= self.
length:
285 raise IndexError(
"Index out of range")
295 """Get the path with the maximum delay (first element since sorted)."""
300 Get the path at the specified position in the delay-sorted collection.
301 Since paths are sorted by delay in descending order, higher ratios
302 correspond to paths with higher delays (closer to the critical path).
304 ratio: Position ratio between 0.0 and 1.0
305 (e.g., 1.0 = longest delay path, 0.0 = shortest delay path,
306 0.95 = path among the top 5% slowest paths)
308 DataflowPath at the specified position ratio
310 assert ratio >= 0.0
and ratio <= 1.0,
"Ratio must be between 0.0 and 1.0"
311 index = int(len(self) * (1 - ratio))
315 """Print a statistical summary of path delays in the collection."""
316 print(f
"Total paths: {len(self)}")
317 print(f
"Max delay: {self.longest_path.delay}")
318 print(f
"Min delay: {self[-1].delay}")
319 print(f
"50th percentile delay: {self.get_by_delay_ratio(0.5).delay}")
320 print(f
"90th percentile delay: {self.get_by_delay_ratio(0.9).delay}")
321 print(f
"95th percentile delay: {self.get_by_delay_ratio(0.95).delay}")
322 print(f
"99th percentile delay: {self.get_by_delay_ratio(0.99).delay}")
323 print(f
"99.9th percentile delay: {self.get_by_delay_ratio(0.999).delay}")
325 def merge(self, src:
"LongestPathCollection"):
327 Merge another collection into this one.
329 src: The collection to merge into this one
337 Drop all paths except the longest path per end point or start point.
339 per_end_point: Whether to keep only the longest path per end point
340 (True) or per start point (False)
354 Main interface for performing longest path analysis on Synth dialect.
355 This class provides a Python wrapper around the C++ LongestPathAnalysis,
356 enabling timing analysis of Synth dialect. It can identify critical timing
357 paths and provide detailed path information.
359 analysis: The underlying C++ analysis object
364 collect_debug_info: bool =
True,
365 keep_only_max_delay_paths: bool =
False,
366 lazy_computation: bool =
False,
367 top_module_name: str =
""):
369 Initialize the longest path analysis for a given module.
371 module: The MLIR module to analyze
372 collect_debug_info: Whether to include debug points in the analysis.
373 Debug points provide additional information about the path,
374 but increase analysis time and memory usage.
375 keep_only_max_delay_paths: Keep only maximum-delay paths in collections.
376 lazy_computation: Enable lazy (on-demand) computation.
378 self.
analysis = synth._LongestPathAnalysis(module, collect_debug_info,
379 keep_only_max_delay_paths,
386 elaborate_paths: bool =
True) -> LongestPathCollection:
388 Perform longest path analysis and return all timing paths to the
389 specified value and bit position.
391 value: The value to analyze
392 bit_pos: The bit position to analyze
393 elaborate_paths: Whether to elaborate the paths with detailed information
395 LongestPathCollection containing all paths sorted by delay
402 elaborate_paths: bool =
True) -> LongestPathCollection:
404 Get internal paths within the module.
406 Internal paths are paths that start and end at sequential elements
407 (registers/flip-flops), forming complete paths through combinational
408 logic. These paths may cross module boundaries but both endpoints are
409 sequential elements, not ports.
412 module_name: Name of the module to analyze
413 elaborate_paths: Whether to include full hierarchical instance information
416 LongestPathCollection containing all internal paths sorted by delay
422 self, module_name: str) -> LongestPathCollection:
424 Get external paths from module input ports to internal sequential elements.
426 These are input-to-register paths that start at module input ports and end
427 at internal sequential elements (registers/flip-flops).
430 module_name: Name of the module to analyze
433 LongestPathCollection containing input-to-internal paths sorted by delay
439 self, module_name: str) -> LongestPathCollection:
441 Get external paths from internal sequential elements to module output ports.
443 These are register-to-output paths that start at internal sequential elements
444 (registers/flip-flops) and end at module output ports.
447 module_name: Name of the module to analyze
450 LongestPathCollection containing internal-to-output paths sorted by delay
457 elaborate_paths: bool =
True) -> LongestPathCollection:
459 Get all paths in the module (internal and external paths combined).
462 module_name: Name of the module to analyze
463 elaborate_paths: Whether to include full hierarchical instance information
464 (only applies to internal paths)
467 LongestPathCollection containing all paths sorted by delay
478 Represents the history of a timing path, including intermediate debug points.
479 This class provides a Python wrapper around the C++ LongestPathHistory,
480 enabling iteration over the path's history and access to debug points.
482 history: The underlying C++ history object
484 history: _LongestPathHistory
487 """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_from_internal_to_output_ports(self, str module_name)
LongestPathCollection get_paths_from_input_ports_to_internal(self, str module_name)
LongestPathCollection get_paths(self, value, int bit_pos, bool elaborate_paths=True)
LongestPathCollection get_all_paths(self, str module_name, bool elaborate_paths=True)
LongestPathCollection get_internal_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, str top_module_name="")
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)
drop_non_critical_paths(self, bool per_end_point=True)
__init__(self, collection)
_LongestPathHistory history
List[Instance] instance_path(self)
_LongestPathObject _object