CIRCT 24.0.0git
Loading...
Searching...
No Matches
AXI4Types.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
11#include "mlir/IR/Builders.h"
12#include "mlir/IR/DialectImplementation.h"
13#include "llvm/ADT/TypeSwitch.h"
14#include "llvm/Support/MathExtras.h"
15
16using namespace circt;
17using namespace axi4;
18using namespace mlir;
19
20#define GET_TYPEDEF_CLASSES
21#include "circt/Dialect/AXI4/AXI4Types.cpp.inc"
22
23LogicalResult PortType::verify(function_ref<InFlightDiagnostic()> emitError,
24 uint32_t addr_width, uint32_t data_width,
25 uint32_t write_id_width, uint32_t read_id_width,
26 uint32_t user_width, WindowSetAttr windows,
27 uint32_t outstanding_writes,
28 uint32_t outstanding_reads) {
29 if (addr_width > 64)
30 return emitError() << "port 'addr_width' must be at most 64, got "
31 << addr_width;
32 if (data_width < 8 || data_width > 1024 || !llvm::isPowerOf2_32(data_width))
33 return emitError() << "port 'data_width' must be a power of two between 8 "
34 "and 1024, got "
35 << data_width;
36 // Verify window addresses fit within address width
37 if (addr_width < 64)
38 for (WindowAttr window : windows.getWindows())
39 if (window.getLast() >> addr_width)
40 return emitError() << "port window " << window
41 << " does not fit in an 'addr_width' of "
42 << addr_width;
43 if (write_id_width > 32)
44 return emitError() << "port 'write_id_width' must be at most 32, got "
45 << write_id_width;
46 if (read_id_width > 32)
47 return emitError() << "port 'read_id_width' must be at most 32, got "
48 << read_id_width;
49 // Bounds computed in 64 bits to avoid 32-bit overflow if ID widths are 32.
50 if (outstanding_writes > (uint64_t{1} << write_id_width))
51 return emitError() << "port 'outstanding_writes' must be at most "
52 << (uint64_t{1} << write_id_width)
53 << " for a 'write_id_width' of " << write_id_width
54 << ", got " << outstanding_writes;
55 if (outstanding_reads > (uint64_t{1} << read_id_width))
56 return emitError() << "port 'outstanding_reads' must be at most "
57 << (uint64_t{1} << read_id_width)
58 << " for a 'read_id_width' of " << read_id_width
59 << ", got " << outstanding_reads;
60 return success();
61}
62
63hw::StructType axi4::getChannelPayloadType(PortType port, AXI4Channel channel) {
64 MLIRContext *ctx = port.getContext();
65 auto field = [&](StringRef name, unsigned width) {
66 return hw::StructType::FieldInfo{StringAttr::get(ctx, name),
67 IntegerType::get(ctx, width)};
68 };
69 // Address channels differ only in which ID width they carry.
70 auto addressFields = [&](unsigned idWidth) {
71 return SmallVector<hw::StructType::FieldInfo>{
72 field("id", idWidth),
73 field("addr", port.getAddrWidth()),
74 field("len", kLenWidth),
75 field("size", kSizeWidth),
76 field("burst", kBurstWidth),
77 field("lock", kLockWidth),
78 field("cache", kCacheWidth),
79 field("prot", kProtWidth),
80 field("qos", kQosWidth),
81 field("region", kRegionWidth),
82 field("user", port.getUserWidth())};
83 };
84
85 SmallVector<hw::StructType::FieldInfo> fields;
86 switch (channel) {
87 case AXI4Channel::AW:
88 fields = addressFields(port.getWriteIdWidth());
89 break;
90 case AXI4Channel::AR:
91 fields = addressFields(port.getReadIdWidth());
92 break;
93 case AXI4Channel::W:
94 fields = {field("data", port.getDataWidth()),
95 field("strb", port.getDataWidth() / 8), field("last", kLastWidth),
96 field("user", port.getUserWidth())};
97 break;
98 case AXI4Channel::B:
99 fields = {field("id", port.getWriteIdWidth()), field("resp", kRespWidth),
100 field("user", port.getUserWidth())};
101 break;
102 case AXI4Channel::R:
103 fields = {field("id", port.getReadIdWidth()),
104 field("data", port.getDataWidth()), field("resp", kRespWidth),
105 field("last", kLastWidth), field("user", port.getUserWidth())};
106 break;
107 }
108 return hw::StructType::get(ctx, fields);
109}
110
111void AXI4Dialect::registerTypes() {
112 addTypes<
113#define GET_TYPEDEF_LIST
114#include "circt/Dialect/AXI4/AXI4Types.cpp.inc"
115 >();
116}
return success()
constexpr unsigned kRespWidth
Definition AXI4Types.h:35
constexpr unsigned kProtWidth
Definition AXI4Types.h:32
constexpr unsigned kLastWidth
Definition AXI4Types.h:36
constexpr unsigned kQosWidth
Definition AXI4Types.h:33
hw::StructType getChannelPayloadType(PortType port, AXI4Channel channel)
Build the hw.struct payload type for one channel of an !axi4.port.
Definition AXI4Types.cpp:63
constexpr unsigned kRegionWidth
Definition AXI4Types.h:34
AXI4Channel
The five AXI4 channels.
Definition AXI4Types.h:24
constexpr unsigned kBurstWidth
Definition AXI4Types.h:29
constexpr unsigned kLenWidth
Definition AXI4Types.h:27
constexpr unsigned kSizeWidth
Definition AXI4Types.h:28
constexpr unsigned kCacheWidth
Definition AXI4Types.h:31
constexpr unsigned kLockWidth
Definition AXI4Types.h:30
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.