Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion xls/codegen/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings:str_format",
],
Expand Down Expand Up @@ -953,7 +954,6 @@ proto_library(
name = "module_signature_proto",
srcs = ["module_signature.proto"],
deps = [
":xls_metrics_proto",
"//xls/ir:channel_proto",
"//xls/ir:foreign_function_data_proto",
"//xls/ir:xls_type_proto",
Expand Down Expand Up @@ -2011,6 +2011,7 @@ cc_library(
"//xls/ir:channel",
"//xls/passes:pass_base",
"@com_google_absl//absl/base",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
)
Expand Down
5 changes: 5 additions & 0 deletions xls/codegen/block_stitching_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,11 @@ absl::Status StitchSingleValueChannel(
absl::Status StitchStreamingChannel(
Block* container, StreamingChannel* channel, const ChannelMap& channel_map,
const absl::flat_hash_map<Block*, ::xls::Instantiation*>& instantiations) {
if (channel->flow_control() == FlowControl::kValidData) {
return absl::UnimplementedError(
"Channels with valid_data flow control are not supported in codegen "
"v1.0.");
}
auto input_iter = channel_map.channel_to_streaming_input().find(channel);
auto output_iter = channel_map.channel_to_streaming_output().find(channel);
bool has_input = input_iter != channel_map.channel_to_streaming_input().end();
Expand Down
16 changes: 16 additions & 0 deletions xls/codegen/clone_nodes_into_block_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@ AddPortsForReceive(ChannelRef channel, Block* block,
std::optional<Node*> valid;
std::optional<Node*> ready;
if (ChannelRefKind(channel) == ChannelKind::kStreaming) {
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control not supported in codegen v1.0");
}
XLS_ASSIGN_OR_RETURN(
valid, block->AddInputPort(
absl::StrCat(ChannelRefName(channel),
Expand Down Expand Up @@ -290,6 +294,10 @@ absl::StatusOr<CloneNodesIntoBlockHandler::ChannelConnection> AddPortsForSend(
std::optional<Node*> valid;
std::optional<Node*> ready;
if (ChannelRefKind(channel) == ChannelKind::kStreaming) {
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control not supported in codegen v1.0");
}
XLS_ASSIGN_OR_RETURN(Node * one, block->MakeNode<xls::Literal>(
SourceInfo(), Value(UBits(1, 1))));
XLS_ASSIGN_OR_RETURN(
Expand Down Expand Up @@ -875,6 +883,10 @@ absl::StatusOr<Node*> CloneNodesIntoBlockHandler::HandleReceiveNode(
}

XLS_RET_CHECK_EQ(ChannelRefKind(connection.channel), ChannelKind::kStreaming);
if (ChannelRefFlowControl(connection.channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control not supported in codegen v1.0");
}
XLS_RET_CHECK_EQ(ChannelRefFlowControl(connection.channel),
FlowControl::kReadyValid)
<< " channel " << ChannelRefToString(connection.channel);
Expand Down Expand Up @@ -999,6 +1011,10 @@ absl::StatusOr<Node*> CloneNodesIntoBlockHandler::HandleSendNode(
}

XLS_RET_CHECK_EQ(ChannelRefKind(connection.channel), ChannelKind::kStreaming);
if (ChannelRefFlowControl(connection.channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control not supported in codegen v1.0");
}
XLS_RET_CHECK_EQ(ChannelRefFlowControl(connection.channel),
FlowControl::kReadyValid);

Expand Down
4 changes: 4 additions & 0 deletions xls/codegen/conversion_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ absl::Status CheckForMultiplexingCycle(Channel* channel,
}
StreamingChannel* streaming_channel =
absl::down_cast<StreamingChannel*>(channel);
if (streaming_channel->flow_control() == FlowControl::kValidData) {
return absl::UnimplementedError(
"Channels with flow control valid_data are not yet supported.");
}
if (!streaming_channel->channel_config().fifo_config().has_value()) {
return absl::InvalidArgumentError(
absl::StrCat("Cannot allow multiple operations from proc `", proc_name,
Expand Down
6 changes: 6 additions & 0 deletions xls/codegen/mark_channel_fifos_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "xls/codegen/mark_channel_fifos_pass.h"

#include "absl/base/casts.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "xls/codegen/codegen_options.h"
#include "xls/codegen/codegen_pass.h"
Expand Down Expand Up @@ -45,6 +46,11 @@ absl::StatusOr<bool> MarkChannelFifosPass::RunInternal(
continue;
}
StreamingChannel* schan = absl::down_cast<StreamingChannel*>(chan);
if (schan->flow_control() == FlowControl::kValidData) {
return absl::UnimplementedError(
"Channels with flow control valid_data are not supported in codegen "
"v1.0.");
}
if (!schan->channel_config().input_flop_kind()) {
schan->SetChannelConfig(schan->channel_config().WithInputFlopKind(
GetRealFlopKind(options.codegen_options.flop_inputs(),
Expand Down
4 changes: 4 additions & 0 deletions xls/codegen/module_signature.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ ModuleSignatureBuilder& ModuleSignatureBuilder::AddStreamingChannel(
ChannelProto* channel = proto_.add_channels();
channel->set_name(name);
channel->set_kind(CHANNEL_KIND_STREAMING);
CHECK_NE(flow_control, FlowControl::kValidData)
<< "valid_data flow control not supported in codegen v1.0";
if (flow_control == FlowControl::kReadyValid) {
channel->set_flow_control(CHANNEL_FLOW_CONTROL_READY_VALID);
} else {
Expand Down Expand Up @@ -212,6 +214,8 @@ ModuleSignatureBuilder& ModuleSignatureBuilder::AddStreamingChannelInterface(
interface->set_direction(direction);
*interface->mutable_type() = type->ToProto();
interface->set_kind(CHANNEL_KIND_STREAMING);
CHECK_NE(flow_control, FlowControl::kValidData)
<< "valid_data flow control not supported in codegen v1.0";
interface->mutable_streaming()->set_flow_control(
flow_control == FlowControl::kReadyValid
? CHANNEL_FLOW_CONTROL_READY_VALID
Expand Down
1 change: 1 addition & 0 deletions xls/codegen/module_signature.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ enum ChannelKindProto {
enum ChannelFlowControlProto {
CHANNEL_FLOW_CONTROL_NONE = 0;
CHANNEL_FLOW_CONTROL_READY_VALID = 1;
CHANNEL_FLOW_CONTROL_VALID_DATA = 2;
}

// Data structure describing a port on a module.
Expand Down
9 changes: 9 additions & 0 deletions xls/codegen/passes_ng/stage_to_block_conversion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ RDVNodeGroupName CreatePortNamesForChannel(
? options.streaming_channel_data_suffix()
: "";
std::string_view valid_suffix = options.streaming_channel_valid_suffix();
CHECK_NE(chan_interface->flow_control(), FlowControl::kValidData)
<< "valid_data flow control not supported in codegen v2.0";

// Construct names for the ports.
std::string port_ready_name =
Expand Down Expand Up @@ -530,6 +532,13 @@ class TopProcToBlockCloner : public ProcToBlockClonerBase {
absl::Status CreateWiresForChannel(const Channel* chan, Block* block) {
Proc* proc = proc_metadata_.proc();

if (chan->kind() == ChannelKind::kStreaming &&
absl::down_cast<const StreamingChannel*>(chan)->flow_control() ==
FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control not supported in codegen v2.0");
}

// Retrieve the suffix for the ports associated with the channel.
std::string_view data_suffix =
(chan->kind() == ChannelKind::kStreaming)
Expand Down
6 changes: 6 additions & 0 deletions xls/codegen/signature_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "xls/codegen/codegen_options.h"
Expand Down Expand Up @@ -150,6 +151,11 @@ absl::StatusOr<ModuleSignature> GenerateSignature(
: CHANNEL_DIRECTION_RECEIVE;
switch (metadata.channel_kind) {
case ChannelKind::kStreaming: {
if (metadata.ready_port.has_value() !=
metadata.valid_port.has_value()) {
return absl::UnimplementedError(
"Codegen v1.0 only supports ready_valid or no flow control.");
}
FlowControl flow_control =
(metadata.ready_port.has_value() && metadata.valid_port.has_value())
? FlowControl::kReadyValid
Expand Down
1 change: 1 addition & 0 deletions xls/codegen_v_1_5/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,7 @@ cc_library(
"@com_google_absl//absl/base",
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings:str_format",
],
Expand Down
20 changes: 20 additions & 0 deletions xls/codegen_v_1_5/channel_to_port_io_lowering_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ absl::StatusOr<Connector> AddPortsForSend(
std::optional<Node*> valid;
std::optional<Node*> ready;
if (ChannelRefKind(channel) == ChannelKind::kStreaming) {
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control is not yet supported.");
}
XLS_ASSIGN_OR_RETURN(
Node * placeholder_valid,
block->MakeNode<xls::Literal>(SourceInfo(), Value(UBits(1, 1))));
Expand Down Expand Up @@ -416,6 +420,10 @@ absl::StatusOr<Connector> AddPortsForReceive(
std::optional<Node*> valid;
std::optional<Node*> ready;
if (ChannelRefKind(channel) == ChannelKind::kStreaming) {
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"valid_data flow control is not yet supported.");
}
XLS_ASSIGN_OR_RETURN(
valid,
block->AddInputPort(
Expand Down Expand Up @@ -1076,6 +1084,10 @@ absl::Status AddOneShotLogic(Connector& connector, ScheduledBlock* block,
const BlockConversionPassOptions& options,
std::string_view channel_name = "") {
XLS_RET_CHECK_EQ(connector.direction, ChannelDirection::kSend);
if (connector.valid.has_value() && !connector.ready.has_value()) {
return absl::UnimplementedError(
"valid_data flow control is not yet supported.");
}
XLS_RET_CHECK(connector.ready.has_value());
XLS_RET_CHECK(connector.valid.has_value());

Expand Down Expand Up @@ -1505,6 +1517,10 @@ absl::Status AddIOFlopsForReceive(Connector& connector, FlopKind flop_kind,
return absl::OkStatus();
}
CHECK_EQ(ChannelRefKind(channel), ChannelKind::kStreaming);
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"Valid-data flow control is not yet supported.");
}

if (flop_kind == FlopKind::kNone) {
return absl::OkStatus();
Expand Down Expand Up @@ -1558,6 +1574,10 @@ absl::Status AddIOFlopsForSend(Connector& connector, FlopKind flop_kind,
.status();
}
CHECK_EQ(ChannelRefKind(channel), ChannelKind::kStreaming);
if (ChannelRefFlowControl(channel) == FlowControl::kValidData) {
return absl::UnimplementedError(
"Valid-data flow control is not yet supported.");
}
CHECK(connector.valid.has_value());
CHECK(connector.ready.has_value());

Expand Down
20 changes: 20 additions & 0 deletions xls/codegen_v_1_5/global_channel_block_stitching_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ absl::Status StitchStreamingOutputToFifo(
SourceInfo(), block_valid, fifo,
FifoInstantiation::kPushValidPortName)
.status());
if (!output.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
XLS_RET_CHECK(output.ready_port.has_value());
XLS_RETURN_IF_ERROR(caller
->MakeNode<xls::InstantiationInput>(
Expand All @@ -168,6 +173,11 @@ absl::Status StitchStreamingInputToFifo(
xls::Node * fifo_valid,
caller->MakeNode<xls::InstantiationOutput>(
SourceInfo(), fifo, FifoInstantiation::kPopValidPortName));
if (!input.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
XLS_RET_CHECK(input.ready_port.has_value());

XLS_ASSIGN_OR_RETURN(
Expand Down Expand Up @@ -205,6 +215,11 @@ absl::Status ExposeStreamingOutput(
VLOG(5) << "Exposing output port valid: " << name_or_none(output.valid_port);
VLOG(5) << "Exposing output port ready: " << name_or_none(output.ready_port);

if (!output.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
XLS_RET_CHECK(output.data_port.has_value());
XLS_RET_CHECK(output.ready_port.has_value());
XLS_RET_CHECK(output.valid_port.has_value());
Expand Down Expand Up @@ -246,6 +261,11 @@ absl::Status ExposeStreamingOutput(
absl::Status ExposeStreamingInput(
StreamingChannel* channel, const ChannelPortMetadata& input, Block* block,
::xls::BlockInstantiation* block_instantiation) {
if (!input.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
XLS_RET_CHECK(input.data_port.has_value());
XLS_RET_CHECK(input.ready_port.has_value());
XLS_RET_CHECK(input.valid_port.has_value());
Expand Down
18 changes: 18 additions & 0 deletions xls/codegen_v_1_5/proc_lowering_block_eval_psc_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,12 @@ absl::StatusOr<BlockEvaluationResults> EvalBlock(
// Only process streaming channels in this block
continue;
}
if (!metadata.data_port.has_value() || !metadata.valid_port.has_value() ||
!metadata.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
// If this channel isn't in the input, skip it.
if (!inputs.contains(channel_name)) {
continue;
Expand Down Expand Up @@ -845,6 +851,12 @@ absl::StatusOr<BlockEvaluationResults> EvalBlock(
// Only process streaming channels in this block
continue;
}
if (!metadata.data_port.has_value() || !metadata.valid_port.has_value() ||
!metadata.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
sinks.push_back(ChannelSink(
*metadata.data_port, *metadata.valid_port, *metadata.ready_port, 0.5,
block, ChannelSink::BehaviorDuringReset::kIgnoreValid));
Expand Down Expand Up @@ -880,6 +892,12 @@ absl::StatusOr<BlockEvaluationResults> EvalBlock(
// Only process streaming channels in this block
continue;
}
if (!metadata.data_port.has_value() || !metadata.valid_port.has_value() ||
!metadata.ready_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid are not yet "
"supported.");
}
if (!actual_outputs.contains(*metadata.data_port)) {
continue;
}
Expand Down
7 changes: 7 additions & 0 deletions xls/codegen_v_1_5/signature_generation_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "absl/base/casts.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "xls/codegen/codegen_options.h"
Expand Down Expand Up @@ -151,6 +152,12 @@ absl::StatusOr<verilog::ModuleSignature> GenerateSignature(
: verilog::ChannelDirectionProto::CHANNEL_DIRECTION_RECEIVE;
switch (metadata.channel_kind) {
case ChannelKind::kStreaming: {
if (metadata.ready_port.has_value() !=
metadata.valid_port.has_value()) {
return absl::UnimplementedError(
"Channels with flow control other than ready_valid or none are "
"not yet supported.");
}
FlowControl flow_control =
(metadata.ready_port.has_value() && metadata.valid_port.has_value())
? FlowControl::kReadyValid
Expand Down
7 changes: 6 additions & 1 deletion xls/ir/channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ std::string FlowControlToString(FlowControl fc) {
return "none";
case FlowControl::kReadyValid:
return "ready_valid";
case FlowControl::kValidData:
return "valid_data";
}
LOG(FATAL) << "Invalid flow control value: " << static_cast<int64_t>(fc);
}
Expand All @@ -273,8 +275,11 @@ absl::StatusOr<FlowControl> StringToFlowControl(std::string_view str) {
if (str == "ready_valid") {
return FlowControl::kReadyValid;
}
if (str == "valid_data") {
return FlowControl::kValidData;
}
return absl::InvalidArgumentError(
absl::StrFormat("Invalid channel kind '%s'", str));
absl::StrFormat("Invalid flow control '%s'", str));
}

std::ostream& operator<<(std::ostream& os, FlowControl fc) {
Expand Down
9 changes: 9 additions & 0 deletions xls/ir/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ enum class FlowControl : uint8_t {
// signal is valid. When both ready and valid are asserted a transaction
// occurs.
kReadyValid,

// The channel uses a valid-data handshake. A valid signal indicates that the
// data is valid, and the receiver is presumed to always be ready to accept
// data. A transaction occurs whenever valid is asserted.
//
// This is used when the channel doesn't want to support backpressure. Safe
// use requires ensuring that the receiver can always accept data when the
// sender is sending, and can optionally be checked with an assert.
kValidData,
};

std::string FlowControlToString(FlowControl fc);
Expand Down
Loading