@@ -480,6 +480,7 @@ absl::Status FunctionConverter::Visit(const AstNode* node) {
480
480
ChannelDirectionToString (ci->direction ()),
481
481
ci);
482
482
},
483
+ [](ChannelArray* ca) { return absl::StrFormat (" %p" , ca); },
483
484
},
484
485
value);
485
486
}
@@ -745,6 +746,23 @@ absl::Status FunctionConverter::HandleTupleIndex(const TupleIndex* node) {
745
746
746
747
absl::Status FunctionConverter::HandleXlsTuple (const XlsTuple* node) {
747
748
VLOG (5 ) << " FunctionConverter::HandleXlsTuple: " << node->ToString ();
749
+ if (current_fn_tag_ == FunctionTag::kProcConfig ) {
750
+ std::vector<IrValue> ir_operands;
751
+ std::vector<BValue> b_operands;
752
+ for (Expr* operand : node->members ()) {
753
+ std::optional<IrValue> v = GetNodeToIr (operand);
754
+ XLS_RET_CHECK (v.has_value ());
755
+ if (std::holds_alternative<BValue>(*v)) {
756
+ b_operands.push_back (std::get<BValue>(*v));
757
+ }
758
+ ir_operands.push_back (*v);
759
+ }
760
+ last_tuple_ = ir_operands;
761
+ Def (node, [this , &b_operands](const SourceInfo& loc) {
762
+ return function_builder_->Tuple (b_operands, loc);
763
+ });
764
+ return absl::OkStatus ();
765
+ }
748
766
std::vector<BValue> operands;
749
767
for (Expr* o : node->members ()) {
750
768
XLS_ASSIGN_OR_RETURN (BValue v, Use (o));
@@ -753,9 +771,6 @@ absl::Status FunctionConverter::HandleXlsTuple(const XlsTuple* node) {
753
771
Def (node, [this , &operands](const SourceInfo& loc) {
754
772
return function_builder_->Tuple (operands, loc);
755
773
});
756
- if (current_fn_tag_ == FunctionTag::kProcConfig ) {
757
- last_tuple_ = operands;
758
- }
759
774
return absl::OkStatus ();
760
775
}
761
776
@@ -850,9 +865,7 @@ absl::Status FunctionConverter::HandleNameRef(const NameRef* node) {
850
865
} else if (std::holds_alternative<ChannelArray*>(v)) {
851
866
VLOG (4 ) << " Reference to Proc member: " << k << " : Chan array : "
852
867
<< std::get<ChannelArray*>(v)->ToString ();
853
- // There is no IR equivalent for a channel array. The Index nodes
854
- // that refer to it have to be lowered to refer to specific channels.
855
- return absl::OkStatus ();
868
+ SetNodeToIr (from, std::get<ChannelArray*>(v));
856
869
} else if (std::holds_alternative<Channel*>(v)) {
857
870
VLOG (4 ) << " Reference to Proc member: " << k
858
871
<< " : Chan : " << std::get<Channel*>(v)->ToString ();
@@ -2635,6 +2648,10 @@ absl::StatusOr<ChanRef> FunctionConverter::IrValueToChannelRef(
2635
2648
return absl::InvalidArgumentError (
2636
2649
" Unexpected ChannelInterface in IrValue." );
2637
2650
},
2651
+ [](ChannelArray* chan) -> absl::StatusOr<ChanRef> {
2652
+ return absl::InvalidArgumentError (
2653
+ " Unexpected ChannelArray in IrValue." );
2654
+ },
2638
2655
},
2639
2656
ir_value);
2640
2657
}
@@ -3198,20 +3215,30 @@ absl::Status FunctionConverter::HandleSpawn(const Spawn* node) {
3198
3215
3199
3216
const Invocation* invocation = node->config ();
3200
3217
XLS_RET_CHECK (package_data_.invocation_to_ir_proc .contains (invocation));
3201
- xls::Proc* ir_proc = package_data_.invocation_to_ir_proc [invocation];
3202
3218
3203
- // Lookup the channel interface for each actual arg and add it to the args
3204
- // vector.
3205
3219
std::vector<ChannelInterface*> channel_args;
3220
+ channel_args.reserve (invocation->args ().size ());
3206
3221
for (Expr* arg : invocation->args ()) {
3207
3222
XLS_RETURN_IF_ERROR (Visit (arg));
3208
- std::optional<IrValue> arg_value = GetNodeToIr (arg);
3209
- XLS_RET_CHECK (arg_value.has_value ());
3210
- XLS_ASSIGN_OR_RETURN (ChannelInterface * channel_interface,
3211
- IrValueToChannelInterface (*arg_value));
3212
- channel_args.push_back (channel_interface);
3223
+ std::optional<IrValue> arg_value_opt = GetNodeToIr (arg);
3224
+ XLS_RET_CHECK (arg_value_opt.has_value ());
3225
+ IrValue arg_value = *arg_value_opt;
3226
+ if (std::holds_alternative<ChannelArray*>(arg_value)) {
3227
+ // Get all the channel interfaces of this array and
3228
+ // add them to the channel_args
3229
+ ChannelArray* channel_array = std::get<ChannelArray*>(arg_value);
3230
+ for (ChannelRef channel : channel_array->channels ()) {
3231
+ XLS_RET_CHECK (std::holds_alternative<ChannelInterface*>(channel));
3232
+ channel_args.push_back (std::get<ChannelInterface*>(channel));
3233
+ }
3234
+ } else {
3235
+ XLS_ASSIGN_OR_RETURN (ChannelInterface * channel_interface,
3236
+ IrValueToChannelInterface (arg_value));
3237
+ channel_args.push_back (channel_interface);
3238
+ }
3213
3239
}
3214
3240
3241
+ xls::Proc* ir_proc = package_data_.invocation_to_ir_proc [invocation];
3215
3242
xls::Proc* current_proc = builder_ptr->proc ();
3216
3243
XLS_RETURN_IF_ERROR (
3217
3244
current_proc
@@ -3449,8 +3476,8 @@ absl::Status FunctionConverter::HandleProcNextFunction(
3449
3476
proc_scoped_channel_scope_->DefineBoundaryChannelOrArray (
3450
3477
param, type_info));
3451
3478
XLS_RET_CHECK (std::holds_alternative<ChannelArray*>(channel_or_array));
3452
- // TODO: davidplass - assign the param name to an appropriate BValue
3453
- // for this channel or array, for the Def call.
3479
+ SetNodeToIr ( param-> name_def (),
3480
+ std::get<ChannelArray*>(channel_or_array));
3454
3481
} else {
3455
3482
ChannelType* channel_type = dynamic_cast <ChannelType*>(type);
3456
3483
XLS_RET_CHECK_NE (channel_type, nullptr )
@@ -3509,28 +3536,39 @@ absl::Status FunctionConverter::HandleProcNextFunction(
3509
3536
XLS_RET_CHECK_EQ (last_tuple_.size (), proc->members ().size ());
3510
3537
int i = 0 ;
3511
3538
for (const ProcMember* member : proc->members ()) {
3512
- BValue tuple_entry = last_tuple_[i++];
3513
- Def (member, [tuple_entry](const SourceInfo& loc) { return tuple_entry; });
3514
-
3515
- // Store the ChannelInterface for this entry in the id_to_members map.
3516
- Node* node = tuple_entry.node ();
3517
- switch (node->op ()) {
3518
- case Op::kSendChannelEnd : {
3519
- SendChannelEnd* sce = node->As <SendChannelEnd>();
3520
- proc_data_->id_to_members .at (proc_id)[member->identifier ()] =
3521
- sce->channel_interface ();
3522
- break ;
3523
- }
3524
- case Op::kRecvChannelEnd : {
3525
- RecvChannelEnd* rce = node->As <RecvChannelEnd>();
3526
- proc_data_->id_to_members .at (proc_id)[member->identifier ()] =
3527
- rce->channel_interface ();
3528
- break ;
3539
+ IrValue tuple_entry = last_tuple_[i++];
3540
+ if (std::holds_alternative<ChannelArray*>(tuple_entry)) {
3541
+ ChannelArray* channel_array = std::get<ChannelArray*>(tuple_entry);
3542
+ SetNodeToIr (member->name_def (), tuple_entry);
3543
+ proc_data_->id_to_members .at (proc_id)[member->identifier ()] =
3544
+ channel_array;
3545
+ XLS_RETURN_IF_ERROR (channel_scope_->AssociateWithExistingChannelOrArray (
3546
+ *proc_id_, member->name_def (), channel_array));
3547
+ } else {
3548
+ BValue bvalue = std::get<BValue>(tuple_entry);
3549
+ Def (member->name_def (),
3550
+ [bvalue](const SourceInfo& loc) { return bvalue; });
3551
+
3552
+ // Store the ChannelInterface for this entry in the id_to_members map.
3553
+ Node* node = bvalue.node ();
3554
+ switch (node->op ()) {
3555
+ case Op::kSendChannelEnd : {
3556
+ SendChannelEnd* sce = node->As <SendChannelEnd>();
3557
+ proc_data_->id_to_members .at (proc_id)[member->identifier ()] =
3558
+ sce->channel_interface ();
3559
+ break ;
3560
+ }
3561
+ case Op::kRecvChannelEnd : {
3562
+ RecvChannelEnd* rce = node->As <RecvChannelEnd>();
3563
+ proc_data_->id_to_members .at (proc_id)[member->identifier ()] =
3564
+ rce->channel_interface ();
3565
+ break ;
3566
+ }
3567
+ default :
3568
+ return absl::InternalError (absl::StrFormat (
3569
+ " Cannot process config return tuple element %d of type %s" ,
3570
+ i - 1 , OpToString (node->op ())));
3529
3571
}
3530
- default :
3531
- return absl::InternalError (absl::StrFormat (
3532
- " Cannot process config return tuple element %d of type %s" , i - 1 ,
3533
- OpToString (node->op ())));
3534
3572
}
3535
3573
}
3536
3574
}
0 commit comments