Skip to content

Commit

Permalink
- Allow internal channels to be declared within subroutines and refer…
Browse files Browse the repository at this point in the history
…ences passed up

- Add token dependencies between IO ops to enforce C ordering within a channel or memory (using --io_op_token_ordering channel_wise flag to xlscc)
- Add __xls_channel_dir_InOut to allow internal channels to be declared within classes
- Working toward enabling ping-pong architecture

PiperOrigin-RevId: 551662211
  • Loading branch information
Sean Purser-Haskell authored and copybara-github committed Jul 27, 2023
1 parent 471cf94 commit 28170b4
Show file tree
Hide file tree
Showing 12 changed files with 1,034 additions and 100 deletions.
3 changes: 2 additions & 1 deletion xls/contrib/xlscc/cc_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,8 @@ struct __xls_bits { };
enum __xls_channel_dir {
__xls_channel_dir_Unknown=0, // OpType::kNull
__xls_channel_dir_Out=1, // OpType::kSend
__xls_channel_dir_In=2 // OpType::kRecv
__xls_channel_dir_In=2, // OpType::kRecv
__xls_channel_dir_InOut=3 // OpType::kSendRecv
};
template<typename T, __xls_channel_dir Dir=__xls_channel_dir_Unknown>
Expand Down
19 changes: 18 additions & 1 deletion xls/contrib/xlscc/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <streambuf>
#include <string>

#include "absl/container/flat_hash_map.h"
#include "absl/flags/flag.h"
Expand Down Expand Up @@ -96,16 +98,31 @@ ABSL_FLAG(int, warn_unroll_iters, 100,
ABSL_FLAG(int, z3_rlimit, -1,
"rlimit to set for z3 solver (eg for loop unrolling)");

ABSL_FLAG(std::string, io_op_token_ordering, "none",
"none (default), channel_wise");

namespace xlscc {

static absl::Status Run(std::string_view cpp_path) {
// Warnings should print by default
absl::SetFlag(&FLAGS_logtostderr, true);

xlscc::IOOpOrdering io_op_token_ordering = IOOpOrdering::kNone;

if (absl::GetFlag(FLAGS_io_op_token_ordering) == "none") {
io_op_token_ordering = IOOpOrdering::kNone;
} else if (absl::GetFlag(FLAGS_io_op_token_ordering) == "channel_wise") {
io_op_token_ordering = IOOpOrdering::kChannelWise;
} else {
std::cerr << "Unknown --io_op_token_ordering: "
<< absl::GetFlag(FLAGS_io_op_token_ordering) << std::endl;
}

xlscc::Translator translator(absl::GetFlag(FLAGS_error_on_init_interval),
absl::GetFlag(FLAGS_max_unroll_iters),
absl::GetFlag(FLAGS_warn_unroll_iters),
absl::GetFlag(FLAGS_z3_rlimit));
absl::GetFlag(FLAGS_z3_rlimit),
io_op_token_ordering);

const std::string block_pb_name = absl::GetFlag(FLAGS_block_pb);

Expand Down
25 changes: 16 additions & 9 deletions xls/contrib/xlscc/translate_block.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ absl::Status Translator::GenerateExternalChannels(
const auto xls_channel_op = top_decl.is_input
? xls::ChannelOps::kReceiveOnly
: xls::ChannelOps::kSendOnly;

XLS_ASSIGN_OR_RETURN(
new_channel.regular,
package_->CreateStreamingChannel(
Expand Down Expand Up @@ -329,7 +330,6 @@ absl::StatusOr<xls::Proc*> Translator::GenerateIR_Block(
static_next_values.push_back(next_val);
}
XLS_CHECK_EQ(static_next_values.size(), prepared.state_init_count);
// const xls::BValue next_state = pb.Tuple(static_next_values);

return pb.Build(prepared.token, static_next_values);
}
Expand Down Expand Up @@ -405,6 +405,12 @@ absl::StatusOr<xls::Proc*> Translator::GenerateIR_BlockFromClass(
if (auto channel_type =
std::dynamic_pointer_cast<CChannelType>(field->type())) {
if (channel_type->GetOpType() != OpType::kNull) {
if (channel_type->GetOpType() == OpType::kSendRecv) {
return absl::UnimplementedError(
ErrorMessage(GetLoc(*field->name()),
"Internal (InOut) channels in top class"));
}

xlscc::HLSChannel* channel_spec = block_spec_out->add_channels();
channel_spec->set_name(field->name()->getNameAsString());
channel_spec->set_width_in_bits(resolved_field_type->GetBitWidth());
Expand All @@ -430,10 +436,11 @@ absl::StatusOr<xls::Proc*> Translator::GenerateIR_BlockFromClass(
.interface_type = InterfaceType::kMemory};
top_decls.push_back(channel_info);
} else {
return absl::InvalidArgumentError(ErrorMessage(
GetLoc(*field->name()),
"Direction or depth unspecified for external channel or memory %s",
field->name()->getNameAsString().c_str()));
return absl::InvalidArgumentError(
ErrorMessage(GetLoc(*field->name()),
"Direction or depth unspecified for external channel "
"or memory '%s'",
field->name()->getNameAsString().c_str()));
}
} else if (auto channel_type =
std::dynamic_pointer_cast<CReferenceType>(field->type())) {
Expand Down Expand Up @@ -934,10 +941,10 @@ absl::Status Translator::GenerateIRBlockPrepare(
}

if (!prepared.xls_channel_by_function_channel.contains(op.channel)) {
XLSCC_CHECK_EQ(
external_channels_by_internal_channel_.contains(op.channel) &&
external_channels_by_internal_channel_.count(op.channel),
1, body_loc);
XLSCC_CHECK(external_channels_by_internal_channel_.contains(op.channel),
body_loc);
XLSCC_CHECK_EQ(external_channels_by_internal_channel_.count(op.channel),
1, body_loc);
const ChannelBundle bundle =
external_channels_by_internal_channel_.find(op.channel)->second;
prepared.xls_channel_by_function_channel[op.channel] = bundle;
Expand Down
34 changes: 34 additions & 0 deletions xls/contrib/xlscc/translate_io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ absl::StatusOr<IOOp*> Translator::AddOpToChannel(IOOp& op, IOChannel* channel,
op.input_value = CValue(pbval, channel_item_type);
}

// Sequence after the previous op on the channel
// TODO(seanhaskell): This is inefficient for memories. Parallelize operations
// once "token phi" type features are available.
if (op_ordering_ == IOOpOrdering::kChannelWise) {
std::vector<const IOOp*> previous_ops_on_channel;

for (const IOOp& existing_op : context().sf->io_ops) {
if (existing_op.channel != op.channel) {
continue;
}
previous_ops_on_channel.push_back(&existing_op);
}

if (!previous_ops_on_channel.empty()) {
const IOOp* last_op = previous_ops_on_channel.back();
op.after_ops.push_back(last_op);
}
} else if (op_ordering_ == IOOpOrdering::kNone) {
// No ordering
} else {
return absl::UnimplementedError(
ErrorMessage(loc, "IO op ordering %i", static_cast<int>(op_ordering_)));
}

context().sf->io_ops.push_back(op);

if (op.op == OpType::kRecv || op.op == OpType::kRead) {
Expand Down Expand Up @@ -568,6 +592,11 @@ absl::StatusOr<xls::BValue> Translator::AddConditionToIOReturn(

switch (op.op) {
case OpType::kNull:
case OpType::kSendRecv:
XLSCC_CHECK(
"AddConditionToIOReturn() unsupported for Null and InOut "
"directions" == nullptr,
loc);
break;
case OpType::kRecv:
op_condition = retval;
Expand Down Expand Up @@ -612,6 +641,11 @@ absl::StatusOr<xls::BValue> Translator::AddConditionToIOReturn(

switch (op.op) {
case OpType::kNull:
case OpType::kSendRecv:
XLSCC_CHECK(
"AddConditionToIOReturn() unsupported for Null and InOut "
"directions" == nullptr,
loc);
break;
case OpType::kRecv:
new_retval = op_condition;
Expand Down
Loading

0 comments on commit 28170b4

Please sign in to comment.