Skip to content

Commit d7cd7a8

Browse files
ericastorcopybara-github
authored andcommitted
Add a test case for a "join" Proc in block conversion.
This test case demonstrates the current behavior of converting a Proc that receives from two channels and sends to one. It highlights an issue where one of the receive-ready signals can be asserted even when the other input is not yet valid, potentially leading to data loss. Documents #3605 PiperOrigin-RevId: 850189387
1 parent 676bf95 commit d7cd7a8

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

xls/codegen/block_conversion_test.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,46 @@ TEST_F(BlockConversionTest, TwoToOneProc) {
14111411
Pair("out", 123), Pair("a_rdy", 1))));
14121412
}
14131413

1414+
// TODO: https://github.com/google/xls/issues/3605 - combinational codegen for
1415+
// procs can produce data loss if we receive from two channels, but only one is
1416+
// valid. `a_rdy` is currently 1 in the case below (with unflopped inputs),
1417+
// despite the pipeline being unable to progress or store the data.
1418+
TEST_F(BlockConversionTest, DISABLED_JoinProc) {
1419+
Package package(TestName());
1420+
Type* u32 = package.GetBitsType(32);
1421+
XLS_ASSERT_OK_AND_ASSIGN(
1422+
Channel * ch_a,
1423+
package.CreateStreamingChannel("a", ChannelOps::kReceiveOnly, u32));
1424+
XLS_ASSERT_OK_AND_ASSIGN(
1425+
Channel * ch_b,
1426+
package.CreateStreamingChannel("b", ChannelOps::kReceiveOnly, u32));
1427+
XLS_ASSERT_OK_AND_ASSIGN(
1428+
Channel * ch_out,
1429+
package.CreateStreamingChannel("out", ChannelOps::kSendOnly, u32));
1430+
1431+
TokenlessProcBuilder pb(TestName(), /*token_name=*/"tkn", &package);
1432+
BValue a = pb.Receive(ch_a);
1433+
BValue b = pb.Receive(ch_b);
1434+
pb.Send(ch_out, pb.Add(a, b));
1435+
1436+
XLS_ASSERT_OK_AND_ASSIGN(Proc * proc, pb.Build({}));
1437+
1438+
XLS_ASSERT_OK_AND_ASSIGN(CodegenContext context,
1439+
ProcToCombinationalBlock(proc, codegen_options()));
1440+
Block* block = context.top_block();
1441+
1442+
// A is valid, C is ready, B is not yet valid.
1443+
// We expect a_rdy to be 0 since the pipeline is not ready to progress, and
1444+
// otherwise we would consume data from A and then have no place to put it,
1445+
// resulting in data loss.
1446+
EXPECT_THAT(
1447+
InterpretCombinationalBlock(
1448+
block,
1449+
{{"a", 10}, {"a_vld", 1}, {"b", 20}, {"b_vld", 0}, {"out_rdy", 1}}),
1450+
IsOkAndHolds(UnorderedElementsAre(Pair("out_vld", 0), Pair("a_rdy", 0),
1451+
Pair("b_rdy", 0), Pair("out", 30))));
1452+
}
1453+
14141454
TEST_F(BlockConversionTest, OneToTwoProc) {
14151455
Package package(TestName());
14161456
Type* u32 = package.GetBitsType(32);

0 commit comments

Comments
 (0)