Skip to content
Draft
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
9 changes: 7 additions & 2 deletions xls/codegen/verilog_conversion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1147,8 +1147,13 @@ class BlockGenerator {
return a.port_name < b.port_name;
});

std::string_view wrapper_name =
have_data ? options_.fifo_module() : options_.nodata_fifo_module();
std::string wrapper_name;
if (fifo_instantiation->fifo_config().fifo_wrapper().has_value()) {
wrapper_name = *fifo_instantiation->fifo_config().fifo_wrapper();
} else {
wrapper_name = have_data ? options_.fifo_module()
: options_.nodata_fifo_module();
}
if (wrapper_name.empty()) {
return absl::InvalidArgumentError(absl::StrFormat(
"No FIFO module specified, but %sFIFO instantiation required.",
Expand Down
12 changes: 12 additions & 0 deletions xls/codegen/verilog_conversion_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,18 @@ TEST_P(VerilogConversionTest, MultiProcWithInternalNoDataFifo) {
absl_testing::IsOkAndHolds(output_values));
}

TEST_P(VerilogConversionTest, MultiProcWithCustomFifoWrapper) {
FifoConfig fifo_config(/*depth=*/1, /*bypass=*/false,
/*register_push_outputs=*/false,
/*register_pop_outputs=*/false,
/*fifo_wrapper=*/"my_custom_fifo");
XLS_ASSERT_OK_AND_ASSIGN(CodegenResult result,
MakeMultiProc(fifo_config,
/*data_width=*/32));

EXPECT_THAT(result.verilog_text, ::testing::HasSubstr("my_custom_fifo"));
}

TEST_P(VerilogConversionTest, MultiProcDirectConnect) {
XLS_ASSERT_OK_AND_ASSIGN(CodegenResult result,
MakeMultiProc(kDepth0Fifo.config,
Expand Down
10 changes: 8 additions & 2 deletions xls/dslx/frontend/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ absl::StatusOr<ChannelConfig> Parser::ParseExprAttribute(Bindings& bindings,
std::optional<bool> register_pop_outputs;
std::optional<FlopKind> input_flop_kind;
std::optional<FlopKind> output_flop_kind;
std::optional<std::string> fifo_wrapper;
auto parse_kv_pair = [&]() -> absl::StatusOr<std::monostate> {
XLS_ASSIGN_OR_RETURN(Token key_tok,
PopTokenOrError(TokenKind::kIdentifier));
Expand Down Expand Up @@ -778,6 +779,10 @@ absl::StatusOr<ChannelConfig> Parser::ParseExprAttribute(Bindings& bindings,
flop_kind.status().message(), value));
}
output_flop_kind.emplace(*flop_kind);
} else if (key == "fifo_wrapper") {
XLS_ASSIGN_OR_RETURN(Token value_tok,
PopTokenOrError(TokenKind::kString));
fifo_wrapper.emplace(value_tok.GetStringValue());
} else if (key == "strictness") {
return ParseErrorStatus(key_tok.span(),
"Channel strictness must be specified via "
Expand All @@ -797,13 +802,14 @@ absl::StatusOr<ChannelConfig> Parser::ParseExprAttribute(Bindings& bindings,
XLS_RETURN_IF_ERROR(DropTokenOrError(TokenKind::kCBrack));
std::optional<FifoConfig> fifo_config;
if (depth.has_value() || bypass.has_value() ||
register_push_outputs.has_value() || register_pop_outputs.has_value()) {
register_push_outputs.has_value() || register_pop_outputs.has_value() ||
fifo_wrapper.has_value()) {
depth = depth.value_or(1);
bypass = bypass.value_or(*depth == 0 ? true : false);
register_push_outputs = register_push_outputs.value_or(false);
register_pop_outputs = register_pop_outputs.value_or(false);
fifo_config.emplace(*depth, *bypass, *register_push_outputs,
*register_pop_outputs);
*register_pop_outputs, fifo_wrapper);
}
ChannelConfig channel_config;
if (fifo_config.has_value() || input_flop_kind.has_value() ||
Expand Down
16 changes: 16 additions & 0 deletions xls/dslx/frontend/parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4380,6 +4380,22 @@ proc AProc {
})");
}

TEST_F(ParserTest, ChannelAttributeFifoWrapper) {
RoundTrip(R"(#![feature(channel_attributes)]

proc AProc {
a: chan<u32> out;
b: chan<u32> in;
config() {
let (a, b) =
#[channel(depth=1, bypass=false, register_push_outputs=false, register_pop_outputs=false, fifo_wrapper="custom_fifo")]
chan<u32>("foo");
}
init {}
next(_: ()) {}
})");
}

TEST_F(ParserTest, CannotUseOldDepthSyntaxWithChannelAttributes) {
constexpr std::string_view kProgram = (R"(#![feature(channel_attributes)]

Expand Down
15 changes: 13 additions & 2 deletions xls/ir/channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ namespace xls {
if (!proto.has_depth()) {
return absl::InvalidArgumentError("FifoConfigProto.depth is required.");
}
std::optional<std::string> fifo_wrapper;
if (proto.has_fifo_wrapper()) {
fifo_wrapper = proto.fifo_wrapper();
}
return FifoConfig(proto.depth(), proto.bypass(),
proto.register_push_outputs(),
proto.register_pop_outputs());
proto.register_push_outputs(), proto.register_pop_outputs(),
fifo_wrapper);
}
FifoConfigProto FifoConfig::ToProto(int64_t width) const {
FifoConfigProto proto;
Expand All @@ -58,6 +62,9 @@ FifoConfigProto FifoConfig::ToProto(int64_t width) const {
proto.set_bypass(bypass_);
proto.set_register_push_outputs(register_push_outputs_);
proto.set_register_pop_outputs(register_pop_outputs_);
if (fifo_wrapper_.has_value()) {
proto.set_fifo_wrapper(*fifo_wrapper_);
}
return proto;
}

Expand Down Expand Up @@ -106,6 +113,10 @@ std::vector<std::pair<std::string, std::string>> FifoConfig::GetDslxKwargs()
{"register_push_outputs", register_push_outputs_ ? "true" : "false"});
kwargs.push_back(
{"register_pop_outputs", register_pop_outputs_ ? "true" : "false"});
if (fifo_wrapper_.has_value()) {
kwargs.push_back(
{"fifo_wrapper", absl::StrCat("\"", *fifo_wrapper_, "\"")});
}
return kwargs;
}

Expand Down
10 changes: 7 additions & 3 deletions xls/ir/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,19 @@ enum class ChannelKind : uint8_t {
class FifoConfig {
public:
constexpr FifoConfig(int64_t depth, bool bypass, bool register_push_outputs,
bool register_pop_outputs)
bool register_pop_outputs,
std::optional<std::string> fifo_wrapper = std::nullopt)
: depth_(depth),
bypass_(bypass),
register_push_outputs_(register_push_outputs),
register_pop_outputs_(register_pop_outputs) {}
register_pop_outputs_(register_pop_outputs),
fifo_wrapper_(std::move(fifo_wrapper)) {}

int64_t depth() const { return depth_; }
bool bypass() const { return bypass_; }
bool register_push_outputs() const { return register_push_outputs_; }
bool register_pop_outputs() const { return register_pop_outputs_; }
std::optional<std::string> fifo_wrapper() const { return fifo_wrapper_; }
absl::Status Validate() const;

bool operator==(const FifoConfig& other) const = default;
Expand All @@ -84,14 +87,15 @@ class FifoConfig {
friend H AbslHashValue(H h, const FifoConfig& config) {
return H::combine(std::move(h), config.depth_, config.bypass_,
config.register_push_outputs_,
config.register_pop_outputs_);
config.register_pop_outputs_, config.fifo_wrapper_);
}

private:
int64_t depth_;
bool bypass_;
bool register_push_outputs_;
bool register_pop_outputs_;
std::optional<std::string> fifo_wrapper_;
};

enum class FlopKind : int8_t {
Expand Down
1 change: 1 addition & 0 deletions xls/ir/channel.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ message FifoConfigProto {
optional bool bypass = 3;
optional bool register_push_outputs = 4;
optional bool register_pop_outputs = 5;
optional string fifo_wrapper = 6;
}

// The kinds of flops a channels input/output may have.
Expand Down
16 changes: 16 additions & 0 deletions xls/ir/channel_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ TEST(ChannelTest, StreamingChannelWithFifoConfigSerializesFifoConfigCorrectly) {
HasSubstr("register_pop_outputs=true")));
}

TEST(ChannelTest, StreamingChannelWithFifoWrapper) {
Package p("my_package");
StreamingChannel ch(
"my_channel", 42, ChannelOps::kSendReceive, p.GetBitsType(32), {},
ChannelConfig(FifoConfig(/*depth=*/123, /*bypass=*/true,
/*register_push_outputs=*/true,
/*register_pop_outputs=*/false,
/*fifo_wrapper=*/"custom_fifo")),
FlowControl::kNone, ChannelStrictness::kProvenMutuallyExclusive);

EXPECT_EQ(ch.name(), "my_channel");
EXPECT_EQ(ch.GetFifoDepth(), 123);
ASSERT_TRUE(ch.channel_config().fifo_config().has_value());
EXPECT_EQ(ch.channel_config().fifo_config()->fifo_wrapper(), "custom_fifo");
}

TEST(ChannelTest, StreamingToStringParses) {
Package p("my_package");
std::vector<Value> initial_values = {
Expand Down
29 changes: 20 additions & 9 deletions xls/ir/instantiation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,29 @@ absl::StatusOr<InstantiationPort> FifoInstantiation::GetOutputPort(
}

std::string FifoInstantiation::ToString() const {
std::string channel_str;
std::vector<std::string> args;
args.push_back(absl::StrFormat("data_type=%s", data_type_->ToString()));
args.push_back(absl::StrFormat("depth=%d", fifo_config_.depth()));
args.push_back(
absl::StrFormat("bypass=%s", fifo_config_.bypass() ? "true" : "false"));
args.push_back(
absl::StrFormat("register_push_outputs=%s",
fifo_config_.register_push_outputs() ? "true" : "false"));
args.push_back(
absl::StrFormat("register_pop_outputs=%s",
fifo_config_.register_pop_outputs() ? "true" : "false"));

if (fifo_config_.fifo_wrapper().has_value()) {
args.push_back(
absl::StrFormat("fifo_wrapper=%s", *fifo_config_.fifo_wrapper()));
}
if (channel_name_.has_value()) {
channel_str = absl::StrFormat("channel=%s, ", *channel_name_);
args.push_back(absl::StrFormat("channel=%s", *channel_name_));
}
args.push_back("kind=fifo");

return absl::StrFormat(
"instantiation %s(data_type=%s, depth=%d, bypass=%s, "
"register_push_outputs=%s, register_pop_outputs=%s, %skind=fifo)",
name(), data_type_->ToString(), fifo_config_.depth(),
fifo_config_.bypass() ? "true" : "false",
fifo_config_.register_push_outputs() ? "true" : "false",
fifo_config_.register_pop_outputs() ? "true" : "false", channel_str);
return absl::StrFormat("instantiation %s(%s)", name(),
absl::StrJoin(args, ", "));
}

DelayLineInstantiation::DelayLineInstantiation(
Expand Down
11 changes: 10 additions & 1 deletion xls/ir/ir_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,14 @@ absl::StatusOr<Instantiation*> Parser::ParseInstantiation(Block* block) {
return absl::OkStatus();
};

std::optional<std::string> fifo_wrapper;
handlers["fifo_wrapper"] = [&]() -> absl::Status {
XLS_ASSIGN_OR_RETURN(Token wrapper_token,
scanner_.PopTokenOrError(LexicalTokenType::kIdent));
fifo_wrapper = wrapper_token.value();
return absl::OkStatus();
};

XLS_RETURN_IF_ERROR(ParseKeywordArguments(handlers,
/*mandatory_keywords=*/{"kind"}));

Expand Down Expand Up @@ -1752,7 +1760,8 @@ absl::StatusOr<Instantiation*> Parser::ParseInstantiation(Block* block) {
FifoConfig(/*depth=*/*depth,
/*bypass=*/*bypass,
/*register_push_outputs=*/*register_push_outputs,
/*register_pop_outputs=*/*register_pop_outputs),
/*register_pop_outputs=*/*register_pop_outputs,
/*fifo_wrapper=*/fifo_wrapper),
*data_type, channel);
}

Expand Down
Loading