13 #include "mlir/Pass/Pass.h"
17 #define GEN_PASS_DEF_ADDTAPS
18 #include "circt/Dialect/Arc/ArcPasses.h.inc"
22 using namespace circt;
27 struct AddTapsPass :
public arc::impl::AddTapsBase<AddTapsPass> {
28 void runOnOperation()
override {
29 getOperation().walk([&](Operation *op) {
30 TypeSwitch<Operation *>(op)
32 .Default([&](
auto) { tapIfNamed(op); });
40 auto *outputOp = moduleOp.getBodyBlock()->getTerminator();
41 ModulePortInfo ports(moduleOp.getPortList());
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());
50 builder.setInsertionPoint(outputOp);
51 for (
auto [port, result] :
52 llvm::zip(ports.getOutputs(), outputOp->getOperands()))
53 buildTap(
builder, result.getLoc(), result, port.getName());
61 for (
auto *user : wireOp->getUsers())
62 if (
auto op = dyn_cast<sv::ReadInOutOp>(user))
68 buildTap(
builder, readOp.getLoc(), readOp, wireOp.getName());
72 void tap(hw::WireOp wireOp) {
73 if (
auto name = wireOp.getName(); name && tapWires) {
75 buildTap(
builder, wireOp.getLoc(), wireOp, *name);
77 wireOp.getResult().replaceAllUsesWith(wireOp.getInput());
82 void tapIfNamed(Operation *op) {
83 if (!tapNamedValues || op->getNumResults() != 1)
85 if (
auto name = op->getAttrOfType<StringAttr>(
"sv.namehint")) {
87 buildTap(
builder, op->getLoc(), op->getResult(0), name);
91 void buildTap(OpBuilder &
builder, Location loc, Value
value, StringRef name) {
94 if (isa<seq::ClockType>(
value.getType()))
99 using AddTapsBase::tapNamedValues;
100 using AddTapsBase::tapPorts;
101 using AddTapsBase::tapWires;
105 std::unique_ptr<Pass>
107 std::optional<bool> tapWires,
108 std::optional<bool> tapNamedValues) {
109 auto pass = std::make_unique<AddTapsPass>();
111 pass->tapPorts = *tapPorts;
113 pass->tapWires = *tapWires;
115 pass->tapNamedValues = *tapNamedValues;
std::unique_ptr< mlir::Pass > createAddTapsPass(std::optional< bool > tapPorts={}, std::optional< bool > tapWires={}, std::optional< bool > tapNamedValues={})
This file defines an intermediate representation for circuits acting as an abstraction for constraint...