CIRCT  20.0.0git
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 
14 #include "circt/Dialect/HW/HWOps.h"
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 
23 using namespace circt;
24 
25 hw::InnerSymAttr hw::PortInfo::getSym() const {
26  if (attrs)
27  return attrs.getAs<::circt::hw::InnerSymAttr>(
28  hw::HWModuleLike::getPortSymbolAttrName());
29  return {};
30 }
31 
32 void 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 
46 StringRef hw::PortInfo::getVerilogName() const {
47  if (attrs)
48  if (auto updatedName = attrs.get("hw.verilogName"))
49  return cast<StringAttr>(updatedName).getValue();
50  return name.getValue();
51 }
52 
53 LogicalResult 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 
110 raw_ostream &circt::hw::operator<<(raw_ostream &printer, PortInfo port) {
111  StringRef dirstr;
112  switch (port.dir) {
114  dirstr = "input";
115  break;
117  dirstr = "output";
118  break;
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"
@ Input
Definition: HW.h:35
@ Output
Definition: HW.h:35
@ InOut
Definition: HW.h:35
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
uint64_t getMaxFieldID(Type)
OS & operator<<(OS &os, const InnerSymTarget &target)
Printing InnerSymTarget's.
LogicalResult verifyInnerSymAttr(InnerSymbolOpInterface op)
Verification hook for verifying InnerSym Attribute.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
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