CIRCT  20.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 
15 #include "circt/Dialect/HW/HWOps.h"
16 #include "circt/Dialect/SV/SVOps.h"
18 #include "mlir/IR/Builders.h"
19 #include "mlir/Pass/Pass.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/Support/Process.h"
22 
23 namespace circt {
24 namespace sv {
25 #define GEN_PASS_DEF_SVTRACEIVERILOG
26 #include "circt/Dialect/SV/SVPasses.h.inc"
27 } // namespace sv
28 } // namespace circt
29 
30 using namespace circt;
31 using namespace sv;
32 using namespace hw;
33 
34 //===----------------------------------------------------------------------===//
35 // SVTraceIVerilogPass
36 //===----------------------------------------------------------------------===//
37 
38 namespace {
39 
40 struct SVTraceIVerilogPass
41  : public circt::sv::impl::SVTraceIVerilogBase<SVTraceIVerilogPass> {
42  void runOnOperation() override;
43 };
44 
45 } // end anonymous namespace
46 
47 void SVTraceIVerilogPass::runOnOperation() {
48  mlir::ModuleOp mod = getOperation();
49 
50  if (topOnly) {
51  auto &graph = getAnalysis<InstanceGraph>();
52  auto topLevelNodes = graph.getInferredTopLevelNodes();
53  if (failed(topLevelNodes) || topLevelNodes->size() != 1) {
54  mod.emitError("Expected exactly one top level node");
55  return signalPassFailure();
56  }
57  hw::HWModuleOp top =
58  dyn_cast_or_null<hw::HWModuleOp>(*topLevelNodes->front()->getModule());
59  if (!top) {
60  mod.emitError("top module is not a HWModuleOp");
61  return signalPassFailure();
62  }
63  targetModuleName.setValue(top.getName().str());
64  }
65 
66  for (auto hwmod : mod.getOps<hw::HWModuleOp>()) {
67  if (!targetModuleName.empty() &&
68  hwmod.getName() != targetModuleName.getValue())
69  continue;
70  OpBuilder builder(hwmod.getBodyBlock(), hwmod.getBodyBlock()->begin());
71  std::string traceMacro;
72  llvm::raw_string_ostream ss(traceMacro);
73  auto modName = hwmod.getName();
74  ss << "initial begin\n $dumpfile (\"" << directoryName.getValue()
75  << modName << ".vcd\");\n $dumpvars (0, " << modName
76  << ");\n #1;\nend\n";
77  builder.create<sv::VerbatimOp>(hwmod.getLoc(), ss.str());
78  }
79 }
80 
81 std::unique_ptr<Pass> circt::sv::createSVTraceIVerilogPass() {
82  return std::make_unique<SVTraceIVerilogPass>();
83 }
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