11#include "mlir/IR/Builders.h"
12#include "mlir/IR/DialectImplementation.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/ADT/StringExtras.h"
16#include "llvm/ADT/TypeSwitch.h"
17#include "llvm/Support/MathExtras.h"
23#include "circt/Dialect/AXI4/AXI4Enums.cpp.inc"
25#define GET_ATTRDEF_CLASSES
26#include "circt/Dialect/AXI4/AXI4Attributes.cpp.inc"
29BurstSpecAttr::verify(function_ref<InFlightDiagnostic()> emitError,
30 BurstKind kind, uint32_t len) {
34 case BurstKind::Fixed:
35 if (len == 0 || len > 16)
36 return emitError() <<
"'fixed' burst 'len' must be between 1 and 16, got "
40 if (len == 0 || len > 256)
41 return emitError() <<
"'incr' burst 'len' must be between 1 and 256, got "
45 if (len < 2 || len > 16 || !llvm::isPowerOf2_32(len))
46 return emitError() <<
"'wrap' burst 'len' must be 2, 4, 8, or 16, got "
54bool BurstSpecAttr::compareCanonical(BurstSpecAttr lhs, BurstSpecAttr rhs) {
55 if (lhs.getKind() != rhs.getKind())
56 return lhs.getKind() < rhs.getKind();
57 return lhs.getLen() < rhs.getLen();
60LogicalResult BurstSetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
61 ArrayRef<BurstSpecAttr> burstSpecs) {
62 if (burstSpecs.empty())
63 return emitError() <<
"'burst_set' must be non-empty";
67LogicalResult WindowAttr::verify(function_ref<InFlightDiagnostic()> emitError,
68 uint64_t base, uint64_t last,
69 BurstSetAttr burstSpecs) {
71 return emitError() <<
"window 'last' address 0x"
72 << llvm::utohexstr(last,
true)
73 <<
" must not be less than 'base' address 0x"
74 << llvm::utohexstr(base,
true);
78SmallVector<WindowAttr> WindowSetAttr::normalize(MLIRContext *ctx,
79 ArrayRef<WindowAttr> windows) {
85 SmallVector<uint64_t> cuts;
86 for (WindowAttr window : windows) {
87 cuts.push_back(window.getBase());
88 if (window.getLast() != UINT64_MAX)
89 cuts.push_back(window.getLast() + 1);
92 cuts.erase(llvm::unique(cuts), cuts.end());
94 SmallVector<WindowAttr> normalized;
95 SmallVector<BurstSpecAttr> specs;
96 for (
size_t i = 0; i < cuts.size(); ++i) {
97 uint64_t lo = cuts[i];
98 uint64_t hi = i + 1 < cuts.size() ? cuts[i + 1] - 1 : UINT64_MAX;
102 for (WindowAttr window : windows)
103 if (window.getBase() <= lo && lo <= window.getLast())
104 llvm::append_range(specs, window.getBurstSpecs().getBurstSpecs());
111 auto burstSpecs = BurstSetAttr::get(ctx, specs);
115 if (!normalized.empty() && normalized.back().getLast() + 1 == lo &&
116 normalized.back().getBurstSpecs() == burstSpecs)
117 lo = normalized.pop_back_val().getBase();
118 normalized.push_back(WindowAttr::get(ctx, lo, hi, burstSpecs));
124WindowSetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
125 ArrayRef<WindowAttr> windows) {
127 return emitError() <<
"'window_set' must be non-empty";
131void AXI4Dialect::registerAttributes() {
133#define GET_ATTRDEF_LIST
134#include "circt/Dialect/AXI4/AXI4Attributes.cpp.inc"
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.