Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LowerFormalToHW.cpp
Go to the documentation of this file.
1//===- LowerFormalToHW.cpp - Formal Preparations --*- C++ -*---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// Lower verif.formal to hw.module.
9//
10//===----------------------------------------------------------------------===//
13
14#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
15
16using namespace circt;
17
18namespace circt {
19namespace verif {
20#define GEN_PASS_DEF_LOWERFORMALTOHWPASS
21#include "circt/Dialect/Verif/Passes.h.inc"
22} // namespace verif
23} // namespace circt
24
25using namespace mlir;
26using namespace verif;
27
28namespace {
29struct LowerFormalToHWPass
30 : verif::impl::LowerFormalToHWPassBase<LowerFormalToHWPass> {
31 void runOnOperation() override;
32};
33
34static LogicalResult lowerFormalToHW(FormalOp op) {
35 IRRewriter rewriter(op);
36
37 // Create the ports for all the symbolic values
38 SmallVector<hw::PortInfo> ports;
39 for (auto symOp : op.getBody().front().getOps<verif::SymbolicValueOp>()) {
40 ports.push_back(
41 hw::PortInfo({{rewriter.getStringAttr("symbolic_value_" +
42 std::to_string(ports.size())),
43 symOp.getType(), hw::ModulePort::Input}}));
44 }
45
46 auto moduleOp =
47 rewriter.create<hw::HWModuleOp>(op.getLoc(), op.getNameAttr(), ports);
48
49 rewriter.inlineBlockBefore(&op.getBody().front(),
50 &moduleOp.getBodyBlock()->front(),
51 op.getBody().getArguments());
52
53 // Replace symbolic values with module arguments
54 size_t i = 0;
55 for (auto symOp : make_early_inc_range(
56 moduleOp.getBodyBlock()->getOps<SymbolicValueOp>())) {
57 rewriter.replaceAllUsesWith(symOp.getResult(),
58 moduleOp.getArgumentForInput(i));
59 i++;
60 rewriter.eraseOp(symOp);
61 }
62
63 rewriter.eraseOp(op);
64 return success();
65}
66} // namespace
67
68void LowerFormalToHWPass::runOnOperation() {
69 bool changed = false;
70 for (auto op :
71 llvm::make_early_inc_range(getOperation().getOps<FormalOp>())) {
72 if (failed(lowerFormalToHW(op)))
73 return signalPassFailure();
74 changed = true;
75 }
76 if (!changed)
77 return markAllAnalysesPreserved();
78}
static Block * getBodyBlock(FModuleLike mod)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition verif.py:1
This holds the name, type, direction of a module's ports.