CIRCT 20.0.0git
Loading...
Searching...
No Matches
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
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
23namespace circt {
24namespace sv {
25#define GEN_PASS_DEF_SVTRACEIVERILOG
26#include "circt/Dialect/SV/SVPasses.h.inc"
27} // namespace sv
28} // namespace circt
29
30using namespace circt;
31using namespace sv;
32using namespace hw;
33
34//===----------------------------------------------------------------------===//
35// SVTraceIVerilogPass
36//===----------------------------------------------------------------------===//
37
38namespace {
39
40struct SVTraceIVerilogPass
41 : public circt::sv::impl::SVTraceIVerilogBase<SVTraceIVerilogPass> {
42 void runOnOperation() override;
43};
44
45} // end anonymous namespace
46
47void 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
81std::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 hw.py:1
Definition sv.py:1