@@ -48,7 +48,26 @@ def FlattenModules : Pass<"hw-flatten-modules", "mlir::ModuleOp"> {
4848 degenerate into a purely cosmetic construct, at which point it is beneficial
4949 to fully flatten the module hierarchy to simplify further analysis and
5050 optimization of state transfer arcs.
51+
52+ By default, all private modules are inlined. The pass supports heuristics to
53+ control which modules are inlined based on their characteristics.
5154 }];
55+ let options = [
56+ Option<"inlineEmpty", "hw-inline-empty", "bool", "true",
57+ "Inline modules that are empty (only contain hw.output)">,
58+ Option<"inlineNoOutputs", "hw-inline-no-outputs", "bool", "true",
59+ "Inline modules that have no output ports">,
60+ Option<"inlineSingleUse", "hw-inline-single-use", "bool", "true",
61+ "Inline modules that have only one use">,
62+ Option<"inlineSmall", "hw-inline-small", "bool", "true",
63+ "Inline modules that are small (fewer than smallThreshold operations)">,
64+ Option<"smallThreshold", "hw-small-threshold", "unsigned", "8",
65+ "Maximum number of operations for a module to be considered small">,
66+ Option<"inlineWithState", "hw-inline-with-state", "bool", "false",
67+ "Allow inlining of modules that contain state (seq.firreg operations)">,
68+ Option<"inlineAll", "hw-inline-all", "bool", "true",
69+ "Inline all private modules regardless of heuristics (default behavior)">
70+ ];
5271}
5372
5473def HWSpecialize : Pass<"hw-specialize", "mlir::ModuleOp"> {
@@ -92,4 +111,49 @@ def HWAggregateToComb : Pass<"hw-aggregate-to-comb", "hw::HWModuleOp"> {
92111 let dependentDialects = ["comb::CombDialect"];
93112}
94113
95- #endif // CIRCT_DIALECT_HW_PASSES_TD
114+ def HWParameterizeConstantPorts : Pass<"hw-parameterize-constant-ports",
115+ "mlir::ModuleOp"> {
116+ let summary = "Parametize constant ports on private modules";
117+ let description = [{
118+ This pass converts input ports on private modules into parameters when all
119+ instances pass constant values (or parameter values) to those ports.
120+
121+ By converting constant ports to parameters, synthesis pipelines can
122+ recognize these values as compile-time constants through local analysis
123+ alone, without requiring inter-module analysis. This enables more precise
124+ timing information and better optimization of each instance independently,
125+ since the constant values are immediately visible at the module interface.
126+ }];
127+ }
128+
129+ def HWBypassInnerSymbols : Pass<"hw-bypass-inner-symbols", "hw::HWModuleOp"> {
130+ let summary = "Pass through values through inner symbols";
131+ let description = [{
132+ This pass moves inner symbols from ports to wires, then bypasses wire
133+ operations with inner symbols by replacing uses with their inputs while
134+ keeping the wire to preserve the symbol. This enables optimizations to
135+ cross symbol boundaries while maintaining symbol references.
136+
137+ Warning: This transformation assumes that values associated with inner
138+ symbols are not mutated through inner symbols (e.g. force). This assumption
139+ may not hold in simulation, but is safe in synthesis. This pass treats
140+ inner symbols differently from the optimization-blocking semantics that
141+ other parts of CIRCT use, so it is opt-in and should only be used when
142+ the above assumptions hold.
143+ }];
144+
145+ let statistics = [
146+ Statistic<"numPortsMoved", "num-ports-moved",
147+ "Number of inner symbols moved from ports to wires">
148+ ];
149+ }
150+
151+ def HWVectorization : Pass<"hw-vectorization", "hw::HWModuleOp"> {
152+ let summary = "Vectorizes bit-level operations in HW dialect";
153+ let description = [{
154+ This pass performs structural vectorization of hardware modules,
155+ merging scalar bit-level assignments into vectorized operations.
156+ }];
157+ }
158+
159+ #endif // CIRCT_DIALECT_HW_PASSES_TD
0 commit comments