CIRCT 20.0.0git
Loading...
Searching...
No Matches
HWOpInterfaces.cpp
Go to the documentation of this file.
1//===- HWOpInterfaces.cpp - Implement the HW op interfaces ----------------===//
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 file implement the HW operation interfaces.
10//
11//===----------------------------------------------------------------------===//
12
16#include "circt/Support/LLVM.h"
17#include "mlir/IR/BuiltinAttributes.h"
18#include "mlir/IR/BuiltinTypes.h"
19#include "llvm/ADT/SmallBitVector.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/StringRef.h"
22
23using namespace circt;
24
25hw::InnerSymAttr hw::PortInfo::getSym() const {
26 if (attrs)
27 return attrs.getAs<::circt::hw::InnerSymAttr>(
28 hw::HWModuleLike::getPortSymbolAttrName());
29 return {};
30}
31
32void hw::PortInfo::setSym(InnerSymAttr sym, MLIRContext *ctx) {
33 auto portSymAttr =
34 StringAttr::get(ctx, hw::HWModuleLike::getPortSymbolAttrName());
35 NamedAttrList pattr(attrs);
36 Attribute oldValue;
37 if (!sym)
38 oldValue = pattr.erase(portSymAttr);
39 else
40 oldValue = pattr.set(portSymAttr, sym);
41 if (oldValue != sym) {
42 attrs = pattr.getDictionary(ctx);
43 }
44}
45
47 if (attrs)
48 if (auto updatedName = attrs.get("hw.verilogName"))
49 return cast<StringAttr>(updatedName).getValue();
50 return name.getValue();
51}
52
53LogicalResult hw::verifyInnerSymAttr(InnerSymbolOpInterface op) {
54 auto innerSym = op.getInnerSymAttr();
55 // If does not have any inner sym then ignore.
56 if (!innerSym)
57 return success();
58
59 if (innerSym.empty())
60 return op->emitOpError("has empty list of inner symbols");
61
62 if (!op.supportsPerFieldSymbols()) {
63 // The inner sym can only be specified on fieldID=0.
64 if (innerSym.size() > 1 || !innerSym.getSymName()) {
65 op->emitOpError("does not support per-field inner symbols");
66 return failure();
67 }
68 return success();
69 }
70
71 auto result = op.getTargetResult();
72 // If op supports per-field symbols, but does not have a target result,
73 // its up to the operation to verify itself.
74 // (there are no uses for this presently, but be open to this anyway.)
75 if (!result)
76 return success();
77 auto resultType = result.getType();
78 auto maxFields = FieldIdImpl::getMaxFieldID(resultType);
79 llvm::SmallBitVector indices(maxFields + 1);
80 llvm::SmallPtrSet<Attribute, 8> symNames;
81 // Ensure fieldID and symbol names are unique.
82 auto uniqSyms = [&](InnerSymPropertiesAttr p) {
83 if (maxFields < p.getFieldID()) {
84 op->emitOpError("field id:'" + Twine(p.getFieldID()) +
85 "' is greater than the maximum field id:'" +
86 Twine(maxFields) + "'");
87 return false;
88 }
89 if (indices.test(p.getFieldID())) {
90 op->emitOpError("cannot assign multiple symbol names to the field id:'" +
91 Twine(p.getFieldID()) + "'");
92 return false;
93 }
94 indices.set(p.getFieldID());
95 auto it = symNames.insert(p.getName());
96 if (!it.second) {
97 op->emitOpError("cannot reuse symbol name:'" + p.getName().getValue() +
98 "'");
99 return false;
100 }
101 return true;
102 };
103
104 if (!llvm::all_of(innerSym.getProps(), uniqSyms))
105 return failure();
106
107 return success();
108}
109
110raw_ostream &circt::hw::operator<<(raw_ostream &printer, PortInfo port) {
111 StringRef dirstr;
112 switch (port.dir) {
113 case ModulePort::Direction::Input:
114 dirstr = "input";
115 break;
116 case ModulePort::Direction::Output:
117 dirstr = "output";
118 break;
119 case ModulePort::Direction::InOut:
120 dirstr = "inout";
121 break;
122 }
123 printer << dirstr << " " << port.name << " : " << port.type << " (argnum "
124 << port.argNum << ", sym " << port.getSym() << ", loc " << port.loc
125 << ", args " << port.attrs << ")";
126 return printer;
127}
128
129#include "circt/Dialect/HW/HWOpInterfaces.cpp.inc"
OS & operator<<(OS &os, const InnerSymTarget &target)
Printing InnerSymTarget's.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
mlir::Type type
Definition HWTypes.h:31
mlir::StringAttr name
Definition HWTypes.h:30
This holds the name, type, direction of a module's ports.
StringRef getVerilogName() const
DictionaryAttr attrs
The optional symbol for this port.
size_t argNum
This is the argument index or the result index depending on the direction.
void setSym(InnerSymAttr sym, MLIRContext *ctx)
InnerSymAttr getSym() const