16 #include "mlir/IR/Attributes.h"
17 #include "mlir/IR/DialectImplementation.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/TypeSwitch.h"
22 using namespace circt;
29 StringAttr name, Type into,
30 ArrayRef<WindowFrameType> frames) {
31 auto structInto = hw::type_dyn_cast<hw::StructType>(into);
33 return emitError() <<
"only windows into structs are currently supported";
35 auto fields = structInto.getElements();
36 for (
auto frame : frames) {
38 DenseMap<StringAttr, WindowFieldType> frameFields;
39 for (
auto field : frame.getMembers())
40 frameFields[field.getFieldName()] = field;
44 while (!fields.empty() && !frameFields.empty()) {
45 hw::StructType::FieldInfo field = fields.front();
46 fields = fields.drop_front();
47 auto f = frameFields.find(field.name);
51 if (f == frameFields.end())
55 uint64_t numItems = f->getSecond().getNumItems();
57 auto arrField = hw::type_dyn_cast<hw::ArrayType>(field.type);
59 return emitError() <<
"cannot specify num items on non-array field "
61 if (numItems > arrField.getNumElements())
62 return emitError() <<
"num items is larger than array size in field "
64 if (frame.getMembers().size() != 1)
66 <<
"array with size specified must be in their own frame (in "
75 if (!frameFields.empty())
76 return emitError() <<
"invalid field name: "
77 << frameFields.begin()->getSecond().getFieldName();
82 hw::UnionType WindowType::getLoweredType()
const {
84 auto into = hw::type_cast<hw::StructType>(getInto());
86 for (hw::StructType::FieldInfo field : into.getElements())
87 intoFields[field.name] = field.type;
90 SmallVector<hw::UnionType::FieldInfo, 4> unionFields;
91 for (WindowFrameType frame : getFrames()) {
94 SmallVector<hw::StructType::FieldInfo, 4> fields;
95 for (WindowFieldType field : frame.getMembers()) {
96 auto fieldTypeIter = intoFields.find(field.getFieldName());
97 assert(fieldTypeIter != intoFields.end());
100 if (field.getNumItems() == 0) {
101 fields.push_back({field.getFieldName(), fieldTypeIter->getSecond()});
105 auto array = hw::type_cast<hw::ArrayType>(fieldTypeIter->getSecond());
110 {field.getFieldName(),
112 unionFields.push_back(
118 size_t leftOver = array.getNumElements() % field.getNumItems();
121 {field.getFieldName(),
124 unionFields.push_back(
126 Twine(frame.getName().getValue(),
"_leftOver")),
134 unionFields.push_back(
144 static FailureOr<::BundledChannel>
parse(AsmParser &p) {
147 if (p.parseType(type))
149 auto dir = FieldParser<::ChannelDirection>::parse(p);
152 if (p.parseKeywordOrString(&name))
160 inline ::llvm::raw_ostream &
operator<<(::llvm::raw_ostream &p,
167 ChannelBundleType ChannelBundleType::getReversed()
const {
168 SmallVector<BundledChannel, 4> reversed;
169 for (
auto channel : getChannels())
170 reversed.push_back({channel.name,
flip(channel.direction), channel.type});
174 #define GET_TYPEDEF_CLASSES
175 #include "circt/Dialect/ESI/ESITypes.cpp.inc"
177 void ESIDialect::registerTypes() {
179 #define GET_TYPEDEF_LIST
180 #include "circt/Dialect/ESI/ESITypes.cpp.inc"
185 circt::esi::ChannelType chan =
186 dyn_cast_or_null<circt::esi::ChannelType>(type);
188 type = chan.getInner();
assert(baseType &&"element must be base type")
static LogicalResult verify(Value clock, bool eventExists, mlir::Location loc)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
mlir::Type innerType(mlir::Type type)
Direction flip(Direction direction)
Flip a port direction.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
raw_ostream & operator<<(raw_ostream &os, const FVInt &value)
ChannelDirection direction
static FailureOr<::BundledChannel > parse(AsmParser &p)