Skip to content

Conversation

@uenoku
Copy link
Member

@uenoku uenoku commented Aug 18, 2025

This commit implements a cut-based rewriting framework for combinational logic optimization
and adds the TechMapper pass that uses NPN-equivalence matching with area and delay
metrics to map AIG circuits to technology libraries. The implementation is based on:

  • "Combinational and Sequential Mapping with Priority Cuts", Alan Mishchenko, Sungmin Cho, Satrajit Chatterjee and Robert Brayton, ICCAD 2007
  • "Fast Boolean matching based on NPN classification", Zheng Huang Lingli Wang Yakov Nasikovskiy and Alan Mishchenko, FPT 2013

The Technology Mapping Pass shows how to use this framework in practice by
mapping generic logic operations to specific hardware gates from a technology
library. This pass also serves as a test for the framework since
testing the cut rewriting algorithms directly would be very difficult without
a real application to exercise them.
The TechMapper pass processes HWModuleOp instances with hw.techlib.info
attributes as library patterns for now. This must be replaced with more well-designed representation.

The framework is designed to be easily extended with new optimization patterns
and strategies while maintaining good performance for cut enumeration and
pattern matching.

@uenoku uenoku force-pushed the dev/hidetou/rebased-cut-rewriter branch from 062ec9e to 6787948 Compare August 18, 2025 06:43
This commit implements a cut-based rewriting framework for combinational logic
optimization and adds the TechMapper pass that uses NPN-equivalence matching
with area and delay metrics to map AIG circuits to technology libraries.

The TechMapper pass processes HWModuleOp instances with hw.techlib.info
attributes as library patterns and maps non-library modules to optimal
gate implementations. The framework includes comprehensive test coverage
for both functionality and error handling scenarios.

The implementation adapts to the current Synth dialect structure and
integrates with the circt-synth command-line tool.
@uenoku uenoku force-pushed the dev/hidetou/rebased-cut-rewriter branch from 6787948 to 18c6b10 Compare August 18, 2025 06:57
Copy link
Contributor

@cowardsa cowardsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work - so much interesting stuff in here - my only major concern is around useTruthTableMatcher - where it seems to return false always? (But expect I've misunderstood)

I really like the interface for defining a technology library - very cool! You could even take this further and allow users to define higher-level custom patterns that help them bring their own component library - a bit like the pulp library!

Comment on lines 189 to 190
/// Get the best matched pattern for this cut set.
std::optional<MatchedPattern> getMatchedPattern() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: getBestMatchedPattern(), could also have a getMatchedPatterns() function - as presumably there will be some area/delay tradeoff to balance?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good point. Will change to getBestMatchedPattern. I think keeping few matched patterns are great and will do in the follow-up

Comment on lines 467 to 468
/// Enumerate cuts for all nodes in the given module.
LogicalResult enumerateCuts(Operation *topOp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: will the current implementation will preserve module boundaries? Namely, there will be no rewriting across the hierarchy?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it preserves module boundaries. Rewriting across module boundaries would be very complicated (and also it's hard to parallelize across modules) so currently I don't have a plan. Users are expected to perform inlining or flattening if context-sensitivity is important. I think we can still use global timing analysis results as arrival times of inputs (input ports or instance results).

Comment on lines +11 to +15
// Set delay for binary and inv op to 5 so that others will be prioritized
hw.module @and_inv(in %a : i1, in %b : i1, out result : i1) attributes {hw.techlib.info = {area = 1.0 : f64, delay = [[5], [5]]}} {
%0 = aig.and_inv %a, %b : i1
hw.output %0 : i1
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool - like the idea of specifying the technology library within the IR itself! Maybe its added elsewhere but perhaps a safety mechanism would be useful to check that a pattern's techlib.info is only being set once?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah eventually we would like to introduce a cell operation but using attributes on hw.module would be good enough until then. The hw.techlib.info is an attribute so MLIR verifier should ensure the uniqueness.

Comment on lines +223 to +225
std::unique_ptr<CutRewritePattern> pattern =
std::make_unique<TechLibraryPattern>(hwModule, area, std::move(delay),
std::move(*npnClass));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: do we have any checks on unique names and unique pattern definitions? Does it matter if we have two patterns implementing the same circuit with different costs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's possible that there are multiple patterns that are equivalent circuit with different costs, e.g. pattern A/B has smallest delay from input 0/1 respectively. CutRewriter will try all available patterns and picks a best pattern.

Comment on lines 49 to 50
// expected-error@+1 {{All input ports must be single bit}}
hw.module @multibit(in %a : i1, in %b: i2, out result : i2) attributes {hw.techlib.info = {area = 1.0 : f64, delay = [[1], [2]]}} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: are multi-bit outputs supported?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. It's not supported now. I'll add a test. It's possible to support but it will be simply treated as multiple single bits outputs.

Comment on lines 85 to 86
// This is a test that needs area-flow to get an optimal result.
// It produces sub-optimal mappings since currently area-flow is not implemented.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: What is area-flow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment and reference to "Heuristics for Area Minimization in LUT-Based FPGA Technology Mapping" which proposed area-flow.

@uenoku
Copy link
Member Author

uenoku commented Aug 19, 2025

my only major concern is around useTruthTableMatcher

Good point, this is is not used in the current PR so I removed a handling useTrtuTableMatcher in CutRewritePatternSet constructor. This is used when a pattern is for LUT where it doesn't need truth table while matching. In the follow-up I will add (generic) LUT mapper so I'd like to test there.

@uenoku uenoku merged commit 43bdb06 into llvm:main Aug 20, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants