Skip to content

Commit f62bc6f

Browse files
committed
[xls][mlir] Support XLS fifo properties/config in MLIR channels.
This also adds support for converting these properties to/from XLS, and updates different passes (array_to_bits, index_type_conversion) to ensure these attributes are maintained when channels are modified. Finally, these properties are also exposed for sproc channels, and the proc elaboration pass is updated to assign said properties to all eproc channels that are generated from an sproc channel.
1 parent 2763b25 commit f62bc6f

File tree

13 files changed

+184
-28
lines changed

13 files changed

+184
-28
lines changed

xls/contrib/mlir/IR/xls_ops.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,11 @@ ParseResult SchanOp::parse(OpAsmParser& parser, OperationState& result) {
620620
result.addAttribute("type", TypeAttr::get(type));
621621
result.types.push_back(SchanType::get(parser.getContext(), type, false));
622622
result.types.push_back(SchanType::get(parser.getContext(), type, true));
623+
624+
if (parser.parseOptionalAttrDictWithKeyword(result.attributes)) {
625+
return failure();
626+
}
627+
623628
return success();
624629
}
625630

@@ -630,6 +635,8 @@ void SchanOp::print(OpAsmPrinter& printer) {
630635
printer << '(';
631636
printer.printString(getName());
632637
printer << ')';
638+
printer << ") ";
639+
printer.printOptionalAttrDictWithKeyword(getOperation()->getAttrs(), {"type", "name"});
633640
}
634641

635642
void SprocOp::print(OpAsmPrinter& printer) {

xls/contrib/mlir/IR/xls_ops.td

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,33 @@ def Xls_TranslationLinkage : Xls_Attr<"TranslationLinkage"> {
135135
let attrName = "xls.translation_linkage";
136136
}
137137

138+
def Xls_FlopKindNone : I32EnumAttrCase<"kNone", 0, "none">;
139+
def Xls_FlopKindFlop : I32EnumAttrCase<"kFlop", 1, "flop">;
140+
def Xls_FlopKindSkid : I32EnumAttrCase<"kSkid", 2, "skid">;
141+
def Xls_FlopKindZeroLatency : I32EnumAttrCase<"kZeroLatency", 3, "zero-latency">;
142+
def Xls_FlopKind : I32EnumAttr<"FlopKind", "XLS flop kind",
143+
[Xls_FlopKindNone, Xls_FlopKindFlop, Xls_FlopKindSkid, Xls_FlopKindZeroLatency]> {
144+
let genSpecializedAttr = 0;
145+
let cppNamespace = "::mlir::xls";
146+
}
147+
def Xls_FlopKindAttr : EnumAttr<Xls_Dialect, Xls_FlopKind, "flop_kind">;
148+
149+
def Xls_FifoConfig : Xls_Attr<"FifoConfig"> {
150+
let summary = "TODO";
151+
let description = [{TODO}];
152+
153+
let parameters = (ins
154+
"int64_t":$fifo_depth,
155+
"bool":$bypass,
156+
"bool":$register_push_outputs,
157+
"bool":$register_pop_outputs
158+
);
159+
160+
let mnemonic = "fifo_config";
161+
162+
let assemblyFormat = "`<` struct(params) `>`";
163+
}
164+
138165
class GetShapeSplat<string name> :
139166
StrFunc<"getShapeSplat($" # name # ".getType())">;
140167

@@ -1626,6 +1653,9 @@ def Xls_ChanOp : Xls_Op<"chan", [
16261653
let arguments = (ins
16271654
SymbolNameAttr:$sym_name,
16281655
TypeAttr:$type,
1656+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1657+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1658+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind,
16291659
DefaultValuedAttr<BoolAttr, "true">:$send_supported,
16301660
DefaultValuedAttr<BoolAttr, "true">:$recv_supported
16311661
);
@@ -1653,7 +1683,6 @@ def Xls_ChanOp : Xls_Op<"chan", [
16531683
void setArgAttrsAttr(ArrayAttr) { return; }
16541684
void setResAttrsAttr(ArrayAttr) { return; }
16551685
}];
1656-
16571686
}
16581687

16591688
def Xls_InstantiateEprocOp : Xls_Op<"instantiate_eproc", [DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
@@ -1753,7 +1782,10 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17531782
}];
17541783
let arguments = (ins
17551784
StrAttr:$name,
1756-
TypeAttr:$type
1785+
TypeAttr:$type,
1786+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1787+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1788+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind
17571789
);
17581790
let results = (outs
17591791
Xls_SchanType:$out,
@@ -1764,7 +1796,7 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17641796
OpBuilder<(ins "::mlir::StringRef":$name, "::mlir::Type":$element_type), [{
17651797
auto inChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/true);
17661798
auto outChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/false);
1767-
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type);
1799+
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type, /*fifo_config=*/nullptr, /*input_flop_kind=*/nullptr, /*output_flop_kind=*/nullptr);
17681800
}]>
17691801
];
17701802
}

xls/contrib/mlir/testdata/array_to_bits.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ func.func @tensor_empty() -> !xls.array<4 x i32> attributes {xls = true} {
215215
return %0 : !xls.array<4 x i32>
216216
}
217217

218-
// CHECK-LABEL: xls.chan @mychan : i24
219-
xls.chan @mychan : !xls.array<3 x i8>
218+
// CHECK-LABEL: xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : i24
219+
xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : !xls.array<3 x i8>
220220

221221
// CHECK-LABEL: xls.eproc @eproc(
222222
// CHECK-SAME: %[[VAL_0:.*]]: i32) zeroinitializer {

xls/contrib/mlir/testdata/index_type_conversion.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func.func @forloop(%arg0: i32, %arg1: i8, %arg2: i9) -> i32 attributes {xls = tr
164164
return %0 : i32
165165
}
166166

167-
// INDEX32-LABEL: xls.chan @mychan : i32
168-
// INDEX64-LABEL: xls.chan @mychan : i64
169-
xls.chan @mychan : index
167+
// INDEX32-LABEL: xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : i32
168+
// INDEX64-LABEL: xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : i64
169+
xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : index
170170

xls/contrib/mlir/testdata/proc_elaboration.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: xls_opt -elaborate-procs -split-input-file %s 2>&1 | FileCheck %s
22
// CHECK: xls.chan @req : i32
3-
// CHECK-NEXT: xls.chan @resp : i32
3+
// CHECK-NEXT: xls.chan @resp {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : i32
44
// CHECK-NEXT: xls.chan @rom1_req : i32
55
// CHECK-NEXT: xls.chan @rom1_resp : i32
66
// CHECK-NEXT: xls.eproc @rom(%arg0: i32) zeroinitializer discardable {
@@ -45,7 +45,7 @@
4545
xls.sproc @fetch() top {
4646
spawns {
4747
%req_out, %req_in = xls.schan<i32>("req")
48-
%resp_out, %resp_in = xls.schan<i32>("resp")
48+
%resp_out, %resp_in = xls.schan<i32>("resp") attributes { fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false> }
4949
xls.spawn @proxy(%req_in, %resp_out) : !xls.schan<i32, in>, !xls.schan<i32, out>
5050
xls.yield %req_out, %resp_in : !xls.schan<i32, out>, !xls.schan<i32, in>
5151
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: xls_translate --mlir-xls-to-xls %s -- 2>&1 | FileCheck %s
2+
3+
// CHECK-LABEL: chan ch_inp
4+
// CHECK-SAME: kind=streaming
5+
// CHECK-SAME: ops=receive_only
6+
xls.chan @ch_inp {send_supported = false} : i32
7+
8+
// CHECK-LABEL: chan ch_out
9+
// CHECK-SAME: kind=streaming
10+
// CHECK-SAME: ops=send_only
11+
// CHECK-SAME: fifo_depth=1
12+
// CHECK-SAME: bypass=true
13+
// CHECK-SAME: register_push_outputs=true
14+
// CHECK-SAME: register_pop_outputs=false
15+
xls.chan @ch_out {
16+
fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>,
17+
recv_supported = false
18+
} : i32
19+
20+
// CHECK: top proc eproc
21+
xls.eproc @eproc() zeroinitializer {
22+
%tok0 = xls.after_all : !xls.token
23+
%tok1, %val = xls.blocking_receive %tok0, @ch_inp : i32
24+
xls.send %tok1, %val, @ch_out : i32
25+
xls.yield
26+
}
27+

xls/contrib/mlir/testdata/translate_from_xls/proc.ir

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@ file_number 0 "./simple_proc.x"
77
// CHECK-LABEL: xls.chan @ch_inp {send_supported = false} : i32
88
chan ch_inp(bits[32], id=0, kind=streaming, ops=receive_only, metadata="")
99

10-
// CHECK-LABEL: xls.chan @ch_out {recv_supported = false} : i32
11-
chan ch_out(bits[32], id=1, kind=streaming, ops=send_only, metadata="")
10+
11+
// CHECK-LABEL: xls.chan @ch_out {
12+
// CHECK-SAME: fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>,
13+
// CHECK-SAME: input_flop_kind = #xls<flop_kind zero-latency>,
14+
// CHECK-SAME: output_flop_kind = #xls<flop_kind skid>
15+
// CHECK-SAME: recv_supported = false
16+
// CHECK-SAME: } : i32
17+
chan ch_out(bits[32], id=1, kind=streaming, ops=send_only, flow_control=ready_valid, strictness=proven_mutually_exclusive, fifo_depth=1, bypass=true, register_push_outputs=true, register_pop_outputs=false, input_flop_kind=zero_latency, output_flop_kind=skid, metadata="")
1218

1319
// CHECK-LABEL: xls.eproc @ident() zeroinitializer {
1420
// CHECK: xls.yield

xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#include "xls/common/file/get_runfile_path.h"
6969
#include "xls/contrib/mlir/IR/xls_ops.h"
7070
#include "xls/ir/bits.h"
71+
#include "xls/ir/channel.h"
7172
#include "xls/ir/foreign_function.h"
7273
#include "xls/ir/foreign_function_data.pb.h"
7374
#include "xls/ir/nodes.h"
@@ -1406,6 +1407,19 @@ absl::StatusOr<::xls::Function*> wrapDslxFunctionIfNeeded(
14061407
return xlsFunc;
14071408
}
14081409

1410+
::xls::FlopKind convertFlopKind(FlopKind kind) {
1411+
switch (kind) {
1412+
case FlopKind::kNone:
1413+
return ::xls::FlopKind::kNone;
1414+
case FlopKind::kFlop:
1415+
return ::xls::FlopKind::kFlop;
1416+
case FlopKind::kSkid:
1417+
return ::xls::FlopKind::kSkid;
1418+
case FlopKind::kZeroLatency:
1419+
return ::xls::FlopKind::kZeroLatency;
1420+
}
1421+
}
1422+
14091423
FailureOr<std::unique_ptr<Package>> mlirXlsToXls(
14101424
Operation* op, llvm::StringRef dslx_search_path,
14111425
DslxPackageCache& dslx_cache) {
@@ -1450,7 +1464,30 @@ FailureOr<std::unique_ptr<Package>> mlirXlsToXls(
14501464
} else if (!chan_op.getRecvSupported()) {
14511465
kind = ::xls::ChannelOps::kSendOnly; // NOLINT
14521466
}
1453-
auto channel = package->CreateStreamingChannel(name, kind, xls_type);
1467+
1468+
std::optional<::xls::FifoConfig> fifo_config = std::nullopt;
1469+
if (auto mlir_fifo_config = chan_op.getFifoConfig()) {
1470+
fifo_config = ::xls::FifoConfig(
1471+
mlir_fifo_config->getFifoDepth(), mlir_fifo_config->getBypass(),
1472+
mlir_fifo_config->getRegisterPushOutputs(),
1473+
mlir_fifo_config->getRegisterPopOutputs());
1474+
}
1475+
1476+
std::optional<::xls::FlopKind> input_flop = std::nullopt;
1477+
std::optional<::xls::FlopKind> output_flop = std::nullopt;
1478+
if (auto attr = chan_op.getInputFlopKind()) {
1479+
input_flop = convertFlopKind(*attr);
1480+
}
1481+
if (auto attr = chan_op.getOutputFlopKind()) {
1482+
output_flop = convertFlopKind(*attr);
1483+
}
1484+
1485+
auto channel_config =
1486+
::xls::ChannelConfig(fifo_config, input_flop, output_flop);
1487+
1488+
auto channel = package->CreateStreamingChannel(name, kind, xls_type, {},
1489+
channel_config);
1490+
14541491
if (!channel.ok()) {
14551492
chan_op.emitOpError("failed to create streaming channel: ")
14561493
<< channel.status().message();

xls/contrib/mlir/tools/xls_translate/xls_translate_to_mlir.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "xls/ir/bits.h"
4646
#include "xls/ir/channel.h"
4747
#include "xls/ir/fileno.h"
48+
#include "xls/ir/channel.h"
4849
#include "xls/ir/function.h"
4950
#include "xls/ir/function_base.h"
5051
#include "xls/ir/lsb_or_msb.h"
@@ -1633,15 +1634,50 @@ absl::StatusOr<Operation*> translateProc(::xls::Proc& xls_proc,
16331634
// Channel Translation
16341635
//===----------------------------------------------------------------------===//
16351636

1637+
FlopKind convertFlopKind(::xls::FlopKind kind) {
1638+
switch (kind) {
1639+
case ::xls::FlopKind::kNone:
1640+
return FlopKind::kNone;
1641+
case ::xls::FlopKind::kFlop:
1642+
return FlopKind::kFlop;
1643+
case ::xls::FlopKind::kSkid:
1644+
return FlopKind::kSkid;
1645+
case ::xls::FlopKind::kZeroLatency:
1646+
return FlopKind::kZeroLatency;
1647+
}
1648+
}
1649+
16361650
absl::Status translateChannel(::xls::Channel& xls_chn, OpBuilder& builder,
16371651
MLIRContext* ctx, TranslationState& state) {
16381652
auto chn = builder.create<xls::ChanOp>(
16391653
builder.getUnknownLoc(),
16401654
/*name=*/builder.getStringAttr(xls_chn.name()),
16411655
/*type=*/TypeAttr::get(translateType(xls_chn.type(), builder, ctx)),
1656+
/*fifo_config=*/nullptr,
1657+
/*input_flop_kind=*/nullptr,
1658+
/*output_flop_kind=*/nullptr,
16421659
/*send_supported=*/builder.getBoolAttr(xls_chn.CanSend()),
16431660
/*recv_supported=*/builder.getBoolAttr(xls_chn.CanReceive()));
16441661

1662+
if (auto xls_streaming_chn =
1663+
dynamic_cast<::xls::StreamingChannel*>(&xls_chn)) {
1664+
auto xls_ch_config = xls_streaming_chn->channel_config();
1665+
if (auto xls_fifo_config = xls_ch_config.fifo_config()) {
1666+
chn.setFifoConfigAttr(FifoConfig::get(
1667+
ctx, xls_fifo_config->depth(), xls_fifo_config->bypass(),
1668+
xls_fifo_config->register_push_outputs(),
1669+
xls_fifo_config->register_pop_outputs()));
1670+
}
1671+
1672+
if (auto xls_input_flop = xls_ch_config.input_flop_kind()) {
1673+
chn.setInputFlopKind(convertFlopKind(*xls_input_flop));
1674+
}
1675+
1676+
if (auto xls_output_flop = xls_ch_config.output_flop_kind()) {
1677+
chn.setOutputFlopKind(convertFlopKind(*xls_output_flop));
1678+
}
1679+
}
1680+
16451681
return state.setChannel(std::string(xls_chn.name()),
16461682
SymbolRefAttr::get(chn.getNameAttr()));
16471683
}

xls/contrib/mlir/transforms/array_to_bits.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ class LegalizeChanOpPattern : public OpConversionPattern<ChanOp> {
147147
ChanOp op, OpAdaptor adaptor,
148148
ConversionPatternRewriter& rewriter) const override {
149149
(void)adaptor;
150-
auto newOp = rewriter.replaceOpWithNewOp<ChanOp>(
151-
op, op.getSymName(), typeConverter->convertType(op.getType()));
152-
newOp.setSendSupported(op.getSendSupported());
153-
newOp.setRecvSupported(op.getRecvSupported());
150+
rewriter.replaceOpWithNewOp<ChanOp>(
151+
op, op.getSymName(), typeConverter->convertType(op.getType()),
152+
op.getFifoConfigAttr(), op.getInputFlopKindAttr(), op.getOutputFlopKindAttr(),
153+
op.getSendSupported(), op.getRecvSupported());
154154
return success();
155155
}
156156
};

0 commit comments

Comments
 (0)