CIRCT  19.0.0git
SVTraceIVerilog.cpp
Go to the documentation of this file.
1 //===- SVTraceIVerilog.cpp - Generator Callout Pass -----------------------===//
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 //
9 // This pass adds the necessary instrumentation to a HWModule to trigger
10 // tracing in an iverilog simulation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "PassDetail.h"
16 #include "circt/Dialect/HW/HWOps.h"
18 #include "mlir/IR/Builders.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/Process.h"
21 
22 using namespace circt;
23 using namespace sv;
24 using namespace hw;
25 
26 //===----------------------------------------------------------------------===//
27 // SVTraceIVerilogPass
28 //===----------------------------------------------------------------------===//
29 
30 namespace {
31 
32 struct SVTraceIVerilogPass
33  : public sv::SVTraceIVerilogBase<SVTraceIVerilogPass> {
34  void runOnOperation() override;
35 };
36 
37 } // end anonymous namespace
38 
39 void SVTraceIVerilogPass::runOnOperation() {
40  mlir::ModuleOp mod = getOperation();
41 
42  if (topOnly) {
43  auto &graph = getAnalysis<InstanceGraph>();
44  auto topLevelNodes = graph.getInferredTopLevelNodes();
45  if (failed(topLevelNodes) || topLevelNodes->size() != 1) {
46  mod.emitError("Expected exactly one top level node");
47  return signalPassFailure();
48  }
49  hw::HWModuleOp top =
50  dyn_cast_or_null<hw::HWModuleOp>(*topLevelNodes->front()->getModule());
51  if (!top) {
52  mod.emitError("top module is not a HWModuleOp");
53  return signalPassFailure();
54  }
55  targetModuleName.setValue(top.getName().str());
56  }
57 
58  for (auto hwmod : mod.getOps<hw::HWModuleOp>()) {
59  if (!targetModuleName.empty() &&
60  hwmod.getName() != targetModuleName.getValue())
61  continue;
62  OpBuilder builder(hwmod.getBodyBlock(), hwmod.getBodyBlock()->begin());
63  std::string traceMacro;
64  llvm::raw_string_ostream ss(traceMacro);
65  auto modName = hwmod.getName();
66  ss << "initial begin\n $dumpfile (\"" << directoryName.getValue()
67  << modName << ".vcd\");\n $dumpvars (0, " << modName
68  << ");\n #1;\nend\n";
69  builder.create<sv::VerbatimOp>(hwmod.getLoc(), ss.str());
70  }
71 }
72 
73 std::unique_ptr<Pass> circt::sv::createSVTraceIVerilogPass() {
74  return std::make_unique<SVTraceIVerilogPass>();
75 }
Builder builder
std::unique_ptr< mlir::Pass > createSVTraceIVerilogPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: hw.py:1
Definition: sv.py:1