@@ -266,6 +266,67 @@ GetLoopbackChannels(ScheduledBlock* block) {
266266 return loopback_channels;
267267}
268268
269+ FlopKind GetDefaultFlopKind (bool enabled,
270+ ::xls::verilog::CodegenOptions::IOKind kind) {
271+ if (!enabled) {
272+ return FlopKind::kNone ;
273+ }
274+ return ::xls::verilog::CodegenOptions::IOKindToFlopKind (kind);
275+ }
276+
277+ absl::StatusOr<FlopKind> GetFlopKind (
278+ ChannelRef channel, ChannelDirection direction, ScheduledBlock* block,
279+ const BlockConversionPassOptions& options) {
280+ if (ChannelRefKind (channel) == ChannelKind::kSingleValue ) {
281+ // NOTE: We control the flop insertion for single-value channels globally,
282+ // with no per-channel configuration. This matches the behavior in codegen
283+ // v1.0.
284+ if (!options.codegen_options .flop_single_value_channels ()) {
285+ return FlopKind::kNone ;
286+ }
287+ switch (direction) {
288+ case ChannelDirection::kSend : {
289+ if (!options.codegen_options .flop_outputs ()) {
290+ return FlopKind::kNone ;
291+ }
292+ return FlopKind::kFlop ;
293+ }
294+ case ChannelDirection::kReceive : {
295+ if (!options.codegen_options .flop_inputs ()) {
296+ return FlopKind::kNone ;
297+ }
298+ return FlopKind::kFlop ;
299+ }
300+ }
301+ ABSL_UNREACHABLE ();
302+ return absl::InternalError (
303+ absl::StrFormat (" Unknown channel direction %d" , direction));
304+ }
305+
306+ if (std::holds_alternative<Channel*>(channel)) {
307+ XLS_RET_CHECK (!block->package ()->ChannelsAreProcScoped ())
308+ << " For proc-scoped channels, the flop kind is set on the interface." ;
309+ XLS_RET_CHECK_EQ (ChannelRefKind (channel), ChannelKind::kStreaming );
310+ StreamingChannel* streaming_channel =
311+ down_cast<StreamingChannel*>(std::get<Channel*>(channel));
312+ switch (direction) {
313+ case ChannelDirection::kSend :
314+ return streaming_channel->channel_config ().output_flop_kind ().value_or (
315+ GetDefaultFlopKind (options.codegen_options .flop_outputs (),
316+ options.codegen_options .flop_outputs_kind ()));
317+ case ChannelDirection::kReceive :
318+ return streaming_channel->channel_config ().input_flop_kind ().value_or (
319+ GetDefaultFlopKind (options.codegen_options .flop_inputs (),
320+ options.codegen_options .flop_inputs_kind ()));
321+ }
322+ ABSL_UNREACHABLE ();
323+ return absl::InternalError (
324+ absl::StrFormat (" Unknown channel direction %d" , direction));
325+ } else {
326+ return std::get<ChannelInterface*>(channel)->flop_kind ();
327+ }
328+ }
329+
269330absl::StatusOr<Connector> AddPortsForSend (
270331 ChannelRef channel, ScheduledBlock* block,
271332 const BlockConversionPassOptions& options) {
@@ -317,12 +378,15 @@ absl::StatusOr<Connector> AddPortsForSend(
317378 .valid = valid,
318379 .ready = ready};
319380
381+ XLS_ASSIGN_OR_RETURN (
382+ FlopKind flop_kind,
383+ GetFlopKind (channel, ChannelDirection::kSend , block, options));
320384 XLS_RETURN_IF_ERROR (block->AddChannelPortMetadata (
321385 ChannelPortMetadata{.channel_name = std::string (ChannelRefName (channel)),
322386 .type = ChannelRefType (channel),
323387 .direction = ChannelDirection::kSend ,
324388 .channel_kind = ChannelRefKind (channel),
325- .flop_kind = FlopKind:: kNone ,
389+ .flop_kind = flop_kind ,
326390 .data_port = data->GetName (),
327391 .valid_port = GetOptionalNodeName (valid),
328392 .ready_port = GetOptionalNodeName (ready)}));
@@ -378,12 +442,15 @@ absl::StatusOr<Connector> AddPortsForReceive(
378442 .valid = valid,
379443 .ready = ready};
380444
445+ XLS_ASSIGN_OR_RETURN (
446+ FlopKind flop_kind,
447+ GetFlopKind (channel, ChannelDirection::kReceive , block, options));
381448 XLS_RETURN_IF_ERROR (block->AddChannelPortMetadata (
382449 ChannelPortMetadata{.channel_name = std::string (ChannelRefName (channel)),
383450 .type = ChannelRefType (channel),
384451 .direction = ChannelDirection::kReceive ,
385452 .channel_kind = ChannelRefKind (channel),
386- .flop_kind = FlopKind:: kNone ,
453+ .flop_kind = flop_kind ,
387454 .data_port = data->GetName (),
388455 .valid_port = GetOptionalNodeName (valid),
389456 .ready_port = GetOptionalNodeName (ready)}));
@@ -1123,67 +1190,6 @@ absl::flat_hash_set<std::string> GetRamChannelNames(
11231190 return ram_channel_names;
11241191}
11251192
1126- FlopKind GetDefaultFlopKind (bool enabled,
1127- ::xls::verilog::CodegenOptions::IOKind kind) {
1128- if (!enabled) {
1129- return FlopKind::kNone ;
1130- }
1131- return ::xls::verilog::CodegenOptions::IOKindToFlopKind (kind);
1132- }
1133-
1134- absl::StatusOr<FlopKind> GetFlopKind (
1135- ChannelRef channel, ChannelDirection direction, ScheduledBlock* block,
1136- const BlockConversionPassOptions& options) {
1137- if (ChannelRefKind (channel) == ChannelKind::kSingleValue ) {
1138- // NOTE: We control the flop insertion for single-value channels globally,
1139- // with no per-channel configuration. This matches the behavior in codegen
1140- // v1.0.
1141- if (!options.codegen_options .flop_single_value_channels ()) {
1142- return FlopKind::kNone ;
1143- }
1144- switch (direction) {
1145- case ChannelDirection::kSend : {
1146- if (!options.codegen_options .flop_outputs ()) {
1147- return FlopKind::kNone ;
1148- }
1149- return FlopKind::kFlop ;
1150- }
1151- case ChannelDirection::kReceive : {
1152- if (!options.codegen_options .flop_inputs ()) {
1153- return FlopKind::kNone ;
1154- }
1155- return FlopKind::kFlop ;
1156- }
1157- }
1158- ABSL_UNREACHABLE ();
1159- return absl::InternalError (
1160- absl::StrFormat (" Unknown channel direction %d" , direction));
1161- }
1162-
1163- if (std::holds_alternative<Channel*>(channel)) {
1164- XLS_RET_CHECK (!block->package ()->ChannelsAreProcScoped ())
1165- << " For proc-scoped channels, the flop kind is set on the interface." ;
1166- XLS_RET_CHECK_EQ (ChannelRefKind (channel), ChannelKind::kStreaming );
1167- StreamingChannel* streaming_channel =
1168- down_cast<StreamingChannel*>(std::get<Channel*>(channel));
1169- switch (direction) {
1170- case ChannelDirection::kSend :
1171- return streaming_channel->channel_config ().output_flop_kind ().value_or (
1172- GetDefaultFlopKind (options.codegen_options .flop_outputs (),
1173- options.codegen_options .flop_outputs_kind ()));
1174- case ChannelDirection::kReceive :
1175- return streaming_channel->channel_config ().input_flop_kind ().value_or (
1176- GetDefaultFlopKind (options.codegen_options .flop_inputs (),
1177- options.codegen_options .flop_inputs_kind ()));
1178- }
1179- ABSL_UNREACHABLE ();
1180- return absl::InternalError (
1181- absl::StrFormat (" Unknown channel direction %d" , direction));
1182- } else {
1183- return std::get<ChannelInterface*>(channel)->flop_kind ();
1184- }
1185- }
1186-
11871193// Adds a register between the node and all its downstream users.
11881194// Returns the new register added.
11891195absl::StatusOr<RegisterRead*> AddRegisterAfterNode (
0 commit comments