Skip to content

Commit 0f4e000

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 0f4e000

File tree

13 files changed

+187
-29
lines changed

13 files changed

+187
-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: 38 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,7 @@ 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+
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type, /*fifo_config=*/nullptr, /*input_flop_kind=*/nullptr, /*output_flop_kind=*/nullptr);
17781813
}]>
17791814
];
17801815
}

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)