15
15
#include " xls/interpreter/channel_queue.h"
16
16
17
17
#include < algorithm>
18
+ #include < cstdint>
18
19
#include < memory>
19
20
#include < optional>
20
21
#include < string_view>
21
22
#include < utility>
22
23
#include < vector>
23
24
25
+ #include " absl/container/flat_hash_set.h"
26
+ #include " absl/memory/memory.h"
24
27
#include " absl/status/status.h"
25
28
#include " absl/status/statusor.h"
29
+ #include " absl/strings/str_format.h"
30
+ #include " absl/synchronization/mutex.h"
31
+ #include " xls/common/logging/logging.h"
26
32
#include " xls/common/status/status_macros.h"
27
- #include " xls/ir/type.h"
33
+ #include " xls/ir/channel.h"
34
+ #include " xls/ir/elaboration.h"
35
+ #include " xls/ir/package.h"
36
+ #include " xls/ir/value.h"
28
37
#include " xls/ir/value_helpers.h"
29
38
30
39
namespace xls {
@@ -34,7 +43,7 @@ absl::Status ChannelQueue::AttachGenerator(GeneratorFn generator) {
34
43
if (generator_.has_value ()) {
35
44
return absl::InternalError (" ChannelQueue already has a generator attached" );
36
45
}
37
- if (channel_ ->kind () == ChannelKind::kSingleValue ) {
46
+ if (channel () ->kind () == ChannelKind::kSingleValue ) {
38
47
return absl::InternalError (
39
48
absl::StrFormat (" ChannelQueues for single-value channels cannot have a "
40
49
" generator. Channel: %s" ,
@@ -45,17 +54,18 @@ absl::Status ChannelQueue::AttachGenerator(GeneratorFn generator) {
45
54
}
46
55
47
56
absl::Status ChannelQueue::Write (const Value& value) {
48
- XLS_VLOG (4 ) << absl::StreamFormat (" Writing value to channel %s: { %s }" ,
49
- channel_->name (), value.ToString ());
57
+ XLS_VLOG (4 ) << absl::StreamFormat (
58
+ " Writing value to channel instance `%s`: { %s }" ,
59
+ channel_instance ()->ToString (), value.ToString ());
50
60
absl::MutexLock lock (&mutex_);
51
61
if (generator_.has_value ()) {
52
62
return absl::InternalError (
53
63
" Cannot write to ChannelQueue because it has a generator function." );
54
64
}
55
- if (!ValueConformsToType (value, channel_ ->type ())) {
65
+ if (!ValueConformsToType (value, channel () ->type ())) {
56
66
return absl::InvalidArgumentError (absl::StrFormat (
57
- " Channel %s expects values to have type %s, got: %s" , channel_-> name () ,
58
- channel_ ->type ()->ToString (), value.ToString ()));
67
+ " Channel `%s` expects values to have type %s, got: %s" ,
68
+ channel ()-> name (), channel () ->type ()->ToString (), value.ToString ()));
59
69
}
60
70
61
71
WriteInternal (value);
@@ -90,7 +100,8 @@ std::optional<Value> ChannelQueue::Read() {
90
100
}
91
101
std::optional<Value> value = ReadInternal ();
92
102
XLS_VLOG (4 ) << absl::StreamFormat (
93
- " Reading data from channel %s: %s" , channel_->name (),
103
+ " Reading data from channel instance %s: %s" ,
104
+ channel_instance ()->ToString (),
94
105
value.has_value () ? value->ToString () : " (none)" );
95
106
XLS_VLOG (4 ) << absl::StreamFormat (" Channel now has %d elements" ,
96
107
queue_.size ());
@@ -110,62 +121,76 @@ std::optional<Value> ChannelQueue::ReadInternal() {
110
121
return std::move (value);
111
122
}
112
123
124
+ /* static */ absl::StatusOr<std::unique_ptr<ChannelQueueManager>>
125
+ ChannelQueueManager::Create (Package* package) {
126
+ XLS_ASSIGN_OR_RETURN (Elaboration elaboration,
127
+ Elaboration::ElaborateOldStylePackage (package));
128
+ return Create (std::move (elaboration));
129
+ }
130
+
113
131
/* static */
114
132
absl::StatusOr<std::unique_ptr<ChannelQueueManager>>
115
133
ChannelQueueManager::Create (std::vector<std::unique_ptr<ChannelQueue>>&& queues,
116
- Package* package ) {
134
+ Elaboration elaboration ) {
117
135
// Verify there is exactly one queue per channel.
118
- absl::flat_hash_set<Channel*> proc_channels (package->channels ().begin (),
119
- package->channels ().end ());
120
- absl::flat_hash_set<Channel*> queue_channels;
136
+ absl::flat_hash_set<ChannelInstance*> channel_instances (
137
+ elaboration.channel_instances ().begin (),
138
+ elaboration.channel_instances ().end ());
139
+ absl::flat_hash_set<ChannelInstance*> queue_chan_instances;
121
140
for (const std::unique_ptr<ChannelQueue>& queue : queues) {
122
- if (!proc_channels .contains (queue->channel ())) {
141
+ if (!channel_instances .contains (queue->channel_instance ())) {
123
142
return absl::InvalidArgumentError (absl::StrFormat (
124
- " Channel `%s` for queue does not exist in package `%s`" ,
125
- queue->channel ()->name (), package->name ()));
143
+ " Channel instance `%s` for queue does not exist in package `%s`" ,
144
+ queue->channel_instance ()->ToString (),
145
+ elaboration.package ()->name ()));
126
146
}
127
- auto [ir, inserted] = queue_channels.insert (queue->channel ());
147
+ auto [ir, inserted] =
148
+ queue_chan_instances.insert (queue->channel_instance ());
128
149
if (!inserted) {
129
150
return absl::InvalidArgumentError (
130
- absl::StrFormat (" Multiple queues specified for channel `%s`" ,
131
- queue->channel ()->name ()));
151
+ absl::StrFormat (" Multiple queues specified for channel instance `%s`" ,
152
+ queue->channel_instance ()->ToString ()));
132
153
}
133
154
}
134
- for (Channel* channel : package->channels ()) {
135
- if (!queue_channels.contains (channel)) {
136
- return absl::InvalidArgumentError (absl::StrFormat (
137
- " No queue specified for channel `%s`" , channel->name ()));
155
+ for (ChannelInstance* instance : elaboration.channel_instances ()) {
156
+ if (!queue_chan_instances.contains (instance)) {
157
+ return absl::InvalidArgumentError (
158
+ absl::StrFormat (" No queue specified for channel instance `%s`" ,
159
+ instance->ToString ()));
138
160
}
139
161
}
140
162
141
- return absl::WrapUnique (new ChannelQueueManager (package, std::move (queues)));
163
+ return absl::WrapUnique (
164
+ new ChannelQueueManager (std::move (elaboration), std::move (queues)));
142
165
}
143
166
144
167
/* static */
145
168
absl::StatusOr<std::unique_ptr<ChannelQueueManager>>
146
- ChannelQueueManager::Create (Package* package ) {
169
+ ChannelQueueManager::Create (Elaboration elaboration ) {
147
170
std::vector<std::unique_ptr<ChannelQueue>> queues;
148
171
149
- // Create a queue per channel in the package .
150
- for (Channel* channel : package-> channels ()) {
151
- if (channel->kind () != ChannelKind::kStreaming &&
152
- channel->kind () != ChannelKind::kSingleValue ) {
172
+ // Create a queue per channel instance in the elaboration .
173
+ for (ChannelInstance* channel_instance : elaboration. channel_instances ()) {
174
+ if (channel_instance-> channel ->kind () != ChannelKind::kStreaming &&
175
+ channel_instance-> channel ->kind () != ChannelKind::kSingleValue ) {
153
176
return absl::UnimplementedError (
154
177
" Only streaming and single-value channels are supported." );
155
178
}
156
- queues.push_back (std::make_unique<ChannelQueue>(channel ));
179
+ queues.push_back (std::make_unique<ChannelQueue>(channel_instance ));
157
180
}
158
181
159
- return absl::WrapUnique (new ChannelQueueManager (package, std::move (queues)));
182
+ return absl::WrapUnique (
183
+ new ChannelQueueManager (std::move (elaboration), std::move (queues)));
160
184
}
161
185
162
186
ChannelQueueManager::ChannelQueueManager (
163
- Package* package, std::vector<std::unique_ptr<ChannelQueue>>&& queues)
164
- : package_(package) {
187
+ Elaboration elaboration,
188
+ std::vector<std::unique_ptr<ChannelQueue>>&& queues)
189
+ : elaboration_(std::move(elaboration)) {
165
190
for (std::unique_ptr<ChannelQueue>& queue : queues) {
166
- Channel* channel = queue->channel ();
167
- queues_[channel ] = std::move (queue);
168
- queue_vec_.push_back (queues_[channel ].get ());
191
+ ChannelInstance* instance = queue->channel_instance ();
192
+ queues_[instance ] = std::move (queue);
193
+ queue_vec_.push_back (queues_[instance ].get ());
169
194
}
170
195
// Stably sort the queues by channel ID.
171
196
std::sort (queue_vec_.begin (), queue_vec_.end (),
@@ -176,14 +201,18 @@ ChannelQueueManager::ChannelQueueManager(
176
201
177
202
absl::StatusOr<ChannelQueue*> ChannelQueueManager::GetQueueById (
178
203
int64_t channel_id) {
179
- XLS_ASSIGN_OR_RETURN (Channel * channel, package_->GetChannel (channel_id));
180
- return queues_.at (channel).get ();
204
+ XLS_ASSIGN_OR_RETURN (Channel * channel, package ()->GetChannel (channel_id));
205
+ XLS_ASSIGN_OR_RETURN (ChannelInstance * instance,
206
+ elaboration ().GetUniqueInstance (channel));
207
+ return queues_.at (instance).get ();
181
208
}
182
209
183
210
absl::StatusOr<ChannelQueue*> ChannelQueueManager::GetQueueByName (
184
211
std::string_view name) {
185
- XLS_ASSIGN_OR_RETURN (Channel * channel, package_->GetChannel (name));
186
- return queues_.at (channel).get ();
212
+ XLS_ASSIGN_OR_RETURN (Channel * channel, package ()->GetChannel (name));
213
+ XLS_ASSIGN_OR_RETURN (ChannelInstance * instance,
214
+ elaboration ().GetUniqueInstance (channel));
215
+ return queues_.at (instance).get ();
187
216
}
188
217
189
218
} // namespace xls
0 commit comments