@@ -823,8 +823,6 @@ absl::StatusOr<std::string> StreamingIOName(Node* node) {
823
823
}
824
824
}
825
825
826
-
827
-
828
826
// For each output streaming channel add a corresponding ready port (input
829
827
// port). Combinationally combine those ready signals with their predicates to
830
828
// generate an all_active_outputs_ready signal.
@@ -1366,41 +1364,42 @@ static absl::StatusOr<RegisterRead*> AddRegisterToRDVNodes(
1366
1364
}
1367
1365
1368
1366
// Adds a register after the input streaming channel's data and valid.
1369
- static absl::StatusOr<Node*> AddRegisterAfterStreamingInput (
1370
- StreamingInput& input, const CodegenOptions& options, Block* block,
1367
+ static absl::Status AddRegisterAfterStreamingInput (
1368
+ StreamingInput& input, FlopKind flop,
1369
+ const std::optional<xls::Reset>& reset_behavior, Block* block,
1371
1370
std::vector<std::optional<Node*>>& valid_nodes) {
1372
- const std::optional<xls::Reset> reset_behavior = options.ResetBehavior ();
1373
-
1374
1371
XLS_ASSIGN_OR_RETURN (std::string port_name, StreamingIOName (*input.port ));
1375
- if (options.flop_inputs_kind () ==
1376
- CodegenOptions::IOKind::kZeroLatencyBuffer ) {
1377
- return AddZeroLatencyBufferToRDVNodes (*input.port , input.port_valid ,
1378
- input.port_ready , port_name,
1379
- reset_behavior, block, valid_nodes);
1380
- }
1381
-
1382
- if (options.flop_inputs_kind () == CodegenOptions::IOKind::kSkidBuffer ) {
1383
- return AddSkidBufferToRDVNodes (*input.port , input.port_valid ,
1372
+ switch (flop) {
1373
+ case FlopKind::kZeroLatency :
1374
+ return AddZeroLatencyBufferToRDVNodes (*input.port , input.port_valid ,
1375
+ input.port_ready , port_name,
1376
+ reset_behavior, block, valid_nodes)
1377
+ .status ();
1378
+ case FlopKind::kSkid :
1379
+ return AddSkidBufferToRDVNodes (*input.port , input.port_valid ,
1380
+ input.port_ready , port_name,
1381
+ reset_behavior, block, valid_nodes)
1382
+ .status ();
1383
+ case FlopKind::kFlop :
1384
+ return AddRegisterToRDVNodes (*input.port , input.port_valid ,
1384
1385
input.port_ready , port_name, reset_behavior,
1385
- block, valid_nodes);
1386
- }
1387
-
1388
- if (options.flop_inputs_kind () == CodegenOptions::IOKind::kFlop ) {
1389
- return AddRegisterToRDVNodes (*input.port , input.port_valid ,
1390
- input.port_ready , port_name, reset_behavior,
1391
- block, valid_nodes);
1386
+ block, valid_nodes)
1387
+ .status ();
1388
+ case FlopKind::kNone :
1389
+ return absl::OkStatus ();
1392
1390
}
1393
-
1394
- return absl::UnimplementedError (absl::StrFormat (
1395
- " Block conversion does not support registering input with kind %d" ,
1396
- options.flop_inputs_kind ()));
1397
1391
}
1398
1392
1399
1393
// Adds a register after the input streaming channel's data and valid.
1400
1394
// Returns the node for the register_read of the data.
1401
- static absl::StatusOr<Node*> AddRegisterBeforeStreamingOutput (
1402
- StreamingOutput& output, const CodegenOptions& options, Block* block,
1395
+ static absl::Status AddRegisterBeforeStreamingOutput (
1396
+ StreamingOutput& output, FlopKind flop,
1397
+ const std::optional<xls::Reset>& reset_behavior, Block* block,
1403
1398
std::vector<std::optional<Node*>>& valid_nodes) {
1399
+ if (flop == FlopKind::kNone ) {
1400
+ // Non-flopped outputs need no additional buffers/logic
1401
+ return absl::OkStatus ();
1402
+ }
1404
1403
// Add buffers before the data/valid output ports and after
1405
1404
// the ready input port to serve as points where the
1406
1405
// additional logic from AddRegisterToRDVNodes() can be inserted.
@@ -1435,30 +1434,28 @@ static absl::StatusOr<Node*> AddRegisterBeforeStreamingOutput(
1435
1434
XLS_RETURN_IF_ERROR (
1436
1435
output.port_ready ->ReplaceUsesWith (output_port_ready_buf));
1437
1436
1438
- const std::optional<xls::Reset> reset_behavior = options.ResetBehavior ();
1439
-
1440
- if (options.flop_outputs_kind () ==
1441
- CodegenOptions::IOKind::kZeroLatencyBuffer ) {
1442
- return AddZeroLatencyBufferToRDVNodes (
1443
- output_port_data_buf, output_port_valid_buf, output_port_ready_buf,
1444
- port_name, reset_behavior, block, valid_nodes);
1445
- }
1446
-
1447
- if (options.flop_outputs_kind () == CodegenOptions::IOKind::kSkidBuffer ) {
1448
- return AddSkidBufferToRDVNodes (output_port_data_buf, output_port_valid_buf,
1437
+ switch (flop) {
1438
+ case FlopKind::kZeroLatency :
1439
+ return AddZeroLatencyBufferToRDVNodes (output_port_data_buf,
1440
+ output_port_valid_buf,
1441
+ output_port_ready_buf, port_name,
1442
+ reset_behavior, block, valid_nodes)
1443
+ .status ();
1444
+ case FlopKind::kSkid :
1445
+ return AddSkidBufferToRDVNodes (output_port_data_buf,
1446
+ output_port_valid_buf,
1447
+ output_port_ready_buf, port_name,
1448
+ reset_behavior, block, valid_nodes)
1449
+ .status ();
1450
+ case FlopKind::kFlop :
1451
+ return AddRegisterToRDVNodes (output_port_data_buf, output_port_valid_buf,
1449
1452
output_port_ready_buf, port_name,
1450
- reset_behavior, block, valid_nodes);
1453
+ reset_behavior, block, valid_nodes)
1454
+ .status ();
1455
+ case FlopKind::kNone :
1456
+ LOG (FATAL)
1457
+ << " Unreachable condition. Non-flopped should have short circuited." ;
1451
1458
}
1452
-
1453
- if (options.flop_outputs_kind () == CodegenOptions::IOKind::kFlop ) {
1454
- return AddRegisterToRDVNodes (output_port_data_buf, output_port_valid_buf,
1455
- output_port_ready_buf, port_name,
1456
- reset_behavior, block, valid_nodes);
1457
- }
1458
-
1459
- return absl::UnimplementedError (absl::StrFormat (
1460
- " Block conversion does not support registering output with kind %d" ,
1461
- options.flop_outputs_kind ()));
1462
1459
}
1463
1460
1464
1461
// Adds an input and/or output flop and related signals.
@@ -1476,10 +1473,14 @@ static absl::Status AddInputOutputFlops(
1476
1473
// Flop streaming inputs.
1477
1474
for (auto & vec : streaming_io.inputs ) {
1478
1475
for (StreamingInput& input : vec) {
1479
- if (options.flop_inputs ()) {
1480
- XLS_RETURN_IF_ERROR (
1481
- AddRegisterAfterStreamingInput (input, options, block, valid_nodes)
1482
- .status ());
1476
+ StreamingChannel* channel = down_cast<StreamingChannel*>(input.channel );
1477
+ FlopKind kind = channel->channel_config ().input_flop_kind ().value_or (
1478
+ options.flop_inputs ()
1479
+ ? CodegenOptions::IOKindToFlopKind (options.flop_inputs_kind ())
1480
+ : FlopKind::kNone );
1481
+ if (kind != FlopKind::kNone ) {
1482
+ XLS_RETURN_IF_ERROR (AddRegisterAfterStreamingInput (
1483
+ input, kind, options.ResetBehavior (), block, valid_nodes));
1483
1484
1484
1485
handled_io_nodes.insert (*input.port );
1485
1486
handled_io_nodes.insert (input.port_valid );
@@ -1494,10 +1495,14 @@ static absl::Status AddInputOutputFlops(
1494
1495
// Flop streaming outputs.
1495
1496
for (auto & vec : streaming_io.outputs ) {
1496
1497
for (StreamingOutput& output : vec) {
1497
- if (options.flop_outputs ()) {
1498
- XLS_RETURN_IF_ERROR (AddRegisterBeforeStreamingOutput (output, options,
1499
- block, valid_nodes)
1500
- .status ());
1498
+ StreamingChannel* channel = down_cast<StreamingChannel*>(output.channel );
1499
+ FlopKind kind = channel->channel_config ().output_flop_kind ().value_or (
1500
+ options.flop_outputs ()
1501
+ ? CodegenOptions::IOKindToFlopKind (options.flop_outputs_kind ())
1502
+ : FlopKind::kNone );
1503
+ if (kind != FlopKind::kNone ) {
1504
+ XLS_RETURN_IF_ERROR (AddRegisterBeforeStreamingOutput (
1505
+ output, kind, options.ResetBehavior (), block, valid_nodes));
1501
1506
1502
1507
handled_io_nodes.insert (*output.port );
1503
1508
handled_io_nodes.insert (output.port_valid );
@@ -1884,7 +1889,6 @@ static absl::Status AddBubbleFlowControl(
1884
1889
return absl::OkStatus ();
1885
1890
}
1886
1891
1887
-
1888
1892
// Send/receive nodes are not cloned from the proc into the block, but the
1889
1893
// network of tokens connecting these send/receive nodes *is* cloned. This
1890
1894
// function removes the token operations.
@@ -2088,7 +2092,8 @@ class CloneNodesIntoBlockHandler {
2088
2092
channel->kind () == ChannelKind::kStreaming ) {
2089
2093
StreamingChannel* streaming_channel =
2090
2094
down_cast<StreamingChannel*>(channel);
2091
- XLS_RET_CHECK (streaming_channel->fifo_config ().has_value ())
2095
+ XLS_RET_CHECK (
2096
+ streaming_channel->channel_config ().fifo_config ().has_value ())
2092
2097
<< absl::StreamFormat (" Channel %s has no fifo config." ,
2093
2098
channel->name ());
2094
2099
@@ -2102,7 +2107,8 @@ class CloneNodesIntoBlockHandler {
2102
2107
block ()->AddInstantiation (
2103
2108
inst_name,
2104
2109
std::make_unique<xls::FifoInstantiation>(
2105
- inst_name, *streaming_channel->fifo_config (),
2110
+ inst_name,
2111
+ *streaming_channel->channel_config ().fifo_config (),
2106
2112
streaming_channel->type (), streaming_channel->name (),
2107
2113
block ()->package ())));
2108
2114
itr->second = instantiation;
@@ -3092,10 +3098,8 @@ absl::Status SingleProcToPipelinedBlock(const PipelineSchedule& schedule,
3092
3098
VLOG (3 ) << absl::StrFormat (" After Output Triggers" );
3093
3099
XLS_VLOG_LINES (3 , block->DumpIr ());
3094
3100
3095
- if (options.flop_inputs () || options.flop_outputs ()) {
3096
- XLS_RETURN_IF_ERROR (AddInputOutputFlops (options, streaming_io_and_pipeline,
3097
- block, proc_metadata.valid_flops ));
3098
- }
3101
+ XLS_RETURN_IF_ERROR (AddInputOutputFlops (options, streaming_io_and_pipeline,
3102
+ block, proc_metadata.valid_flops ));
3099
3103
VLOG (3 ) << " After Input or Output Flops" ;
3100
3104
XLS_VLOG_LINES (3 , block->DumpIr ());
3101
3105
0 commit comments