CIRCT  18.0.0git
AddTaps.cpp
Go to the documentation of this file.
1 //===- AddTaps.cpp --------------------------------------------------------===//
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 
11 #include "circt/Dialect/SV/SVOps.h"
13 #include "mlir/Pass/Pass.h"
14 
15 namespace circt {
16 namespace arc {
17 #define GEN_PASS_DEF_ADDTAPS
18 #include "circt/Dialect/Arc/ArcPasses.h.inc"
19 } // namespace arc
20 } // namespace circt
21 
22 using namespace circt;
23 using namespace arc;
24 using namespace hw;
25 
26 namespace {
27 struct AddTapsPass : public arc::impl::AddTapsBase<AddTapsPass> {
28  void runOnOperation() override {
29  getOperation().walk([&](Operation *op) {
30  TypeSwitch<Operation *>(op)
31  .Case<HWModuleOp, sv::WireOp, hw::WireOp>([&](auto op) { tap(op); })
32  .Default([&](auto) { tapIfNamed(op); });
33  });
34  }
35 
36  // Add taps for all module ports.
37  void tap(HWModuleOp moduleOp) {
38  if (!tapPorts)
39  return;
40  auto *outputOp = moduleOp.getBodyBlock()->getTerminator();
41  ModulePortInfo ports(moduleOp.getPortList());
42 
43  // Add taps to inputs.
44  auto builder = OpBuilder::atBlockBegin(moduleOp.getBodyBlock());
45  for (auto [port, arg] :
46  llvm::zip(ports.getInputs(), moduleOp.getBodyBlock()->getArguments()))
47  buildTap(builder, arg.getLoc(), arg, port.getName());
48 
49  // Add taps to outputs.
50  builder.setInsertionPoint(outputOp);
51  for (auto [port, result] :
52  llvm::zip(ports.getOutputs(), outputOp->getOperands()))
53  buildTap(builder, result.getLoc(), result, port.getName());
54  }
55 
56  // Add taps for SV wires.
57  void tap(sv::WireOp wireOp) {
58  if (!tapWires)
59  return;
60  sv::ReadInOutOp readOp;
61  for (auto *user : wireOp->getUsers())
62  if (auto op = dyn_cast<sv::ReadInOutOp>(user))
63  readOp = op;
64 
65  OpBuilder builder(wireOp);
66  if (!readOp)
67  readOp = builder.create<sv::ReadInOutOp>(wireOp.getLoc(), wireOp);
68  buildTap(builder, readOp.getLoc(), readOp, wireOp.getName());
69  }
70 
71  // Add taps for HW wires.
72  void tap(hw::WireOp wireOp) {
73  if (auto name = wireOp.getName(); name && tapWires) {
74  OpBuilder builder(wireOp);
75  buildTap(builder, wireOp.getLoc(), wireOp, *name);
76  }
77  wireOp.getResult().replaceAllUsesWith(wireOp.getInput());
78  wireOp->erase();
79  }
80 
81  // Add taps for named values.
82  void tapIfNamed(Operation *op) {
83  if (!tapNamedValues || op->getNumResults() != 1)
84  return;
85  if (auto name = op->getAttrOfType<StringAttr>("sv.namehint")) {
86  OpBuilder builder(op);
87  buildTap(builder, op->getLoc(), op->getResult(0), name);
88  }
89  }
90 
91  void buildTap(OpBuilder &builder, Location loc, Value value, StringRef name) {
92  if (name.empty())
93  return;
94  if (isa<seq::ClockType>(value.getType()))
95  value = builder.createOrFold<seq::FromClockOp>(loc, value);
96  builder.create<arc::TapOp>(loc, value, name);
97  }
98 
99  using AddTapsBase::tapNamedValues;
100  using AddTapsBase::tapPorts;
101  using AddTapsBase::tapWires;
102 };
103 } // namespace
104 
105 std::unique_ptr<Pass>
106 arc::createAddTapsPass(std::optional<bool> tapPorts,
107  std::optional<bool> tapWires,
108  std::optional<bool> tapNamedValues) {
109  auto pass = std::make_unique<AddTapsPass>();
110  if (tapPorts)
111  pass->tapPorts = *tapPorts;
112  if (tapWires)
113  pass->tapWires = *tapWires;
114  if (tapNamedValues)
115  pass->tapNamedValues = *tapNamedValues;
116  return pass;
117 }
lowerAnnotationsNoRefTypePorts FirtoolPreserveValuesMode value
Definition: Firtool.cpp:95
Builder builder
Definition: sv.py:35
std::unique_ptr< mlir::Pass > createAddTapsPass(std::optional< bool > tapPorts={}, std::optional< bool > tapWires={}, std::optional< bool > tapNamedValues={})
Definition: AddTaps.cpp:106
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21
Definition: hw.py:1