Skip to content

Commit f78fff6

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 49cff5c commit f78fff6

File tree

13 files changed

+184
-29
lines changed

13 files changed

+184
-29
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>]> {
@@ -1763,7 +1792,10 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17631792
}];
17641793
let arguments = (ins
17651794
StrAttr:$name,
1766-
TypeAttr:$type
1795+
TypeAttr:$type,
1796+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1797+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1798+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind
17671799
);
17681800
let results = (outs
17691801
Xls_SchanType:$out,
@@ -1774,7 +1806,7 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17741806
OpBuilder<(ins "::mlir::StringRef":$name, "::mlir::Type":$element_type), [{
17751807
auto inChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/true);
17761808
auto outChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/false);
1777-
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type);
1809+
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type, /*fifo_config=*/nullptr, /*input_flop_kind=*/nullptr, /*output_flop_kind=*/nullptr);
17781810
}]>
17791811
];
17801812
}

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: 3 additions & 3 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
2-
// CHECK-LABEL: xls.chan @req : i32
3-
// CHECK-NEXT: xls.chan @resp : i32
2+
// CHECK-LABEL: xls.chan @req : 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: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ 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)
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)
10+
// CHECK-LABEL: xls.chan @ch_out {
11+
// CHECK-SAME: fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>,
12+
// CHECK-SAME: input_flop_kind = #xls<flop_kind zero-latency>,
13+
// CHECK-SAME: output_flop_kind = #xls<flop_kind skid>
14+
// CHECK-SAME: recv_supported = false
15+
// CHECK-SAME: } : i32
16+
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)
1217

1318
// CHECK-LABEL: xls.eproc @ident() zeroinitializer {
1419
// 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"
@@ -1408,6 +1409,19 @@ absl::StatusOr<::xls::Function*> wrapDslxFunctionIfNeeded(
14081409
return xlsFunc;
14091410
}
14101411

1412+
::xls::FlopKind convertFlopKind(FlopKind kind) {
1413+
switch (kind) {
1414+
case FlopKind::kNone:
1415+
return ::xls::FlopKind::kNone;
1416+
case FlopKind::kFlop:
1417+
return ::xls::FlopKind::kFlop;
1418+
case FlopKind::kSkid:
1419+
return ::xls::FlopKind::kSkid;
1420+
case FlopKind::kZeroLatency:
1421+
return ::xls::FlopKind::kZeroLatency;
1422+
}
1423+
}
1424+
14111425
FailureOr<std::unique_ptr<Package>> mlirXlsToXls(
14121426
Operation* op, llvm::StringRef dslx_search_path,
14131427
DslxPackageCache& dslx_cache) {
@@ -1452,7 +1466,30 @@ FailureOr<std::unique_ptr<Package>> mlirXlsToXls(
14521466
} else if (!chan_op.getRecvSupported()) {
14531467
kind = ::xls::ChannelOps::kSendOnly; // NOLINT
14541468
}
1455-
auto channel = package->CreateStreamingChannel(name, kind, xls_type);
1469+
1470+
std::optional<::xls::FifoConfig> fifo_config = std::nullopt;
1471+
if (auto mlir_fifo_config = chan_op.getFifoConfig()) {
1472+
fifo_config = ::xls::FifoConfig(
1473+
mlir_fifo_config->getFifoDepth(), mlir_fifo_config->getBypass(),
1474+
mlir_fifo_config->getRegisterPushOutputs(),
1475+
mlir_fifo_config->getRegisterPopOutputs());
1476+
}
1477+
1478+
std::optional<::xls::FlopKind> input_flop = std::nullopt;
1479+
std::optional<::xls::FlopKind> output_flop = std::nullopt;
1480+
if (auto attr = chan_op.getInputFlopKind()) {
1481+
input_flop = convertFlopKind(*attr);
1482+
}
1483+
if (auto attr = chan_op.getOutputFlopKind()) {
1484+
output_flop = convertFlopKind(*attr);
1485+
}
1486+
1487+
auto channel_config =
1488+
::xls::ChannelConfig(fifo_config, input_flop, output_flop);
1489+
1490+
auto channel = package->CreateStreamingChannel(name, kind, xls_type, {},
1491+
channel_config);
1492+
14561493
if (!channel.ok()) {
14571494
chan_op.emitOpError("failed to create streaming channel: ")
14581495
<< 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"
@@ -1600,15 +1601,50 @@ absl::StatusOr<Operation*> translateProc(::xls::Proc& xls_proc,
16001601
// Channel Translation
16011602
//===----------------------------------------------------------------------===//
16021603

1604+
FlopKind convertFlopKind(::xls::FlopKind kind) {
1605+
switch (kind) {
1606+
case ::xls::FlopKind::kNone:
1607+
return FlopKind::kNone;
1608+
case ::xls::FlopKind::kFlop:
1609+
return FlopKind::kFlop;
1610+
case ::xls::FlopKind::kSkid:
1611+
return FlopKind::kSkid;
1612+
case ::xls::FlopKind::kZeroLatency:
1613+
return FlopKind::kZeroLatency;
1614+
}
1615+
}
1616+
16031617
absl::Status translateChannel(::xls::Channel& xls_chn, OpBuilder& builder,
16041618
MLIRContext* ctx, TranslationState& state) {
16051619
auto chn = builder.create<xls::ChanOp>(
16061620
builder.getUnknownLoc(),
16071621
/*name=*/builder.getStringAttr(xls_chn.name()),
16081622
/*type=*/TypeAttr::get(translateType(xls_chn.type(), builder, ctx)),
1623+
/*fifo_config=*/nullptr,
1624+
/*input_flop_kind=*/nullptr,
1625+
/*output_flop_kind=*/nullptr,
16091626
/*send_supported=*/builder.getBoolAttr(xls_chn.CanSend()),
16101627
/*recv_supported=*/builder.getBoolAttr(xls_chn.CanReceive()));
16111628

1629+
if (auto xls_streaming_chn =
1630+
dynamic_cast<::xls::StreamingChannel*>(&xls_chn)) {
1631+
auto xls_ch_config = xls_streaming_chn->channel_config();
1632+
if (auto xls_fifo_config = xls_ch_config.fifo_config()) {
1633+
chn.setFifoConfigAttr(FifoConfig::get(
1634+
ctx, xls_fifo_config->depth(), xls_fifo_config->bypass(),
1635+
xls_fifo_config->register_push_outputs(),
1636+
xls_fifo_config->register_pop_outputs()));
1637+
}
1638+
1639+
if (auto xls_input_flop = xls_ch_config.input_flop_kind()) {
1640+
chn.setInputFlopKind(convertFlopKind(*xls_input_flop));
1641+
}
1642+
1643+
if (auto xls_output_flop = xls_ch_config.output_flop_kind()) {
1644+
chn.setOutputFlopKind(convertFlopKind(*xls_output_flop));
1645+
}
1646+
}
1647+
16121648
return state.setChannel(std::string(xls_chn.name()),
16131649
SymbolRefAttr::get(chn.getNameAttr()));
16141650
}

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)