Skip to content

Commit 38b7d51

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 a45f782 commit 38b7d51

File tree

13 files changed

+192
-29
lines changed

13 files changed

+192
-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: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,36 @@ 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 = "FIFO Configuration Attribute";
151+
let description = [{
152+
Definies the properties of the physical FIFO to be instantiated from
153+
an (internal) channel.
154+
}];
155+
156+
let parameters = (ins
157+
"int64_t":$fifo_depth,
158+
"bool":$bypass,
159+
"bool":$register_push_outputs,
160+
"bool":$register_pop_outputs
161+
);
162+
163+
let mnemonic = "fifo_config";
164+
165+
let assemblyFormat = "`<` struct(params) `>`";
166+
}
167+
138168
class GetShapeSplat<string name> :
139169
StrFunc<"getShapeSplat($" # name # ".getType())">;
140170

@@ -1626,6 +1656,9 @@ def Xls_ChanOp : Xls_Op<"chan", [
16261656
let arguments = (ins
16271657
SymbolNameAttr:$sym_name,
16281658
TypeAttr:$type,
1659+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1660+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1661+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind,
16291662
DefaultValuedAttr<BoolAttr, "true">:$send_supported,
16301663
DefaultValuedAttr<BoolAttr, "true">:$recv_supported
16311664
);
@@ -1653,7 +1686,6 @@ def Xls_ChanOp : Xls_Op<"chan", [
16531686
void setArgAttrsAttr(ArrayAttr) { return; }
16541687
void setResAttrsAttr(ArrayAttr) { return; }
16551688
}];
1656-
16571689
}
16581690

16591691
def Xls_InstantiateEprocOp : Xls_Op<"instantiate_eproc", [DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
@@ -1763,7 +1795,10 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17631795
}];
17641796
let arguments = (ins
17651797
StrAttr:$name,
1766-
TypeAttr:$type
1798+
TypeAttr:$type,
1799+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1800+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1801+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind
17671802
);
17681803
let results = (outs
17691804
Xls_SchanType:$out,
@@ -1774,7 +1809,8 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17741809
OpBuilder<(ins "::mlir::StringRef":$name, "::mlir::Type":$element_type), [{
17751810
auto inChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/true);
17761811
auto outChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/false);
1777-
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type);
1812+
// TODO(jpienaar): Remove unecessary default args once they are generated automatically.
1813+
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type, /*fifo_config=*/nullptr, /*input_flop_kind=*/nullptr, /*output_flop_kind=*/nullptr);
17781814
}]>
17791815
];
17801816
}

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"
@@ -1409,6 +1410,19 @@ absl::StatusOr<::xls::Function*> wrapDslxFunctionIfNeeded(
14091410
return xlsFunc;
14101411
}
14111412

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