Skip to content

Commit 28639f9

Browse files
Merge pull request #1916 from schilkp:schilkp/mlir_fifo_props
PiperOrigin-RevId: 734211535
2 parents 7ac5098 + 7cf46ef commit 28639f9

File tree

13 files changed

+232
-30
lines changed

13 files changed

+232
-30
lines changed

xls/contrib/mlir/IR/xls_ops.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,9 @@ 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-
return success();
623+
624+
return failure(
625+
parser.parseOptionalAttrDictWithKeyword(result.attributes).failed());
624626
}
625627

626628
void SchanOp::print(OpAsmPrinter& printer) {
@@ -630,6 +632,9 @@ void SchanOp::print(OpAsmPrinter& printer) {
630632
printer << '(';
631633
printer.printString(getName());
632634
printer << ')';
635+
printer << ") ";
636+
printer.printOptionalAttrDictWithKeyword(getOperation()->getAttrs(),
637+
{"type", "name"});
633638
}
634639

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

xls/contrib/mlir/IR/xls_ops.td

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

138+
def Xls_FlopKindNone : I32EnumAttrCase<"kNone", 0, "none"> {
139+
let summary = "No flop.";
140+
let description = [{
141+
Adds no buffer to the input/output.
142+
143+
See https://google.github.io/xls/codegen_options/#io-behavior for more information.
144+
}];
145+
}
146+
def Xls_FlopKindFlop : I32EnumAttrCase<"kFlop", 1, "flop"> {
147+
let summary = "Basic flop.";
148+
let description = [{
149+
Adds a pipeline stage to the input/output. This is essentially a single-element FIFO
150+
151+
See https://google.github.io/xls/codegen_options/#io-behavior for more information.
152+
}];
153+
}
154+
def Xls_FlopKindSkid : I32EnumAttrCase<"kSkid", 2, "skid"> {
155+
let summary = "Skip flop.";
156+
let description = [{
157+
Adds a skid buffer to the input/output. The skid buffer can hold 2 entries.
158+
159+
See https://google.github.io/xls/codegen_options/#io-behavior for more information.
160+
}];
161+
}
162+
def Xls_FlopKindZeroLatency : I32EnumAttrCase<"kZeroLatency", 3, "zero-latency"> {
163+
let summary = "Zero-latency flop.";
164+
let description = [{
165+
Adds a zero-latency buffer to the input/output. This is essentially a
166+
single-element FIFO with bypass.
167+
168+
See https://google.github.io/xls/codegen_options/#io-behavior for more information.
169+
}];
170+
}
171+
def Xls_FlopKind : I32EnumAttr<"FlopKind", "XLS flop kind",
172+
[Xls_FlopKindNone, Xls_FlopKindFlop, Xls_FlopKindSkid, Xls_FlopKindZeroLatency]> {
173+
let genSpecializedAttr = 0;
174+
let cppNamespace = "::mlir::xls";
175+
}
176+
def Xls_FlopKindAttr : EnumAttr<Xls_Dialect, Xls_FlopKind, "flop_kind"> {
177+
let summary = "Channel flop/buffer kind.";
178+
let description = [{
179+
The inputs/outputs of procs/blocks can optionally be fitted with one of a
180+
number of buffer types. This is specified on the channel connected to this
181+
proc input/output, using the `input_flop_kind` and `output_flop_kind`
182+
property.
183+
184+
See https://google.github.io/xls/codegen_options/#io-behavior for more information.
185+
}];
186+
}
187+
188+
def Xls_FifoConfig : Xls_Attr<"FifoConfig"> {
189+
let summary = "FIFO Configuration Attribute";
190+
let description = [{
191+
Definies the properties of the physical FIFO to be instantiated from
192+
an (internal) channel.
193+
}];
194+
195+
let parameters = (ins
196+
"int64_t":$fifo_depth,
197+
"bool":$bypass,
198+
"bool":$register_push_outputs,
199+
"bool":$register_pop_outputs
200+
);
201+
202+
let mnemonic = "fifo_config";
203+
204+
let assemblyFormat = "`<` struct(params) `>`";
205+
}
206+
138207
class GetShapeSplat<string name> :
139208
StrFunc<"getShapeSplat($" # name # ".getType())">;
140209

@@ -1626,6 +1695,9 @@ def Xls_ChanOp : Xls_Op<"chan", [
16261695
let arguments = (ins
16271696
SymbolNameAttr:$sym_name,
16281697
TypeAttr:$type,
1698+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1699+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1700+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind,
16291701
DefaultValuedAttr<BoolAttr, "true">:$send_supported,
16301702
DefaultValuedAttr<BoolAttr, "true">:$recv_supported
16311703
);
@@ -1653,7 +1725,6 @@ def Xls_ChanOp : Xls_Op<"chan", [
16531725
void setArgAttrsAttr(ArrayAttr) { return; }
16541726
void setResAttrsAttr(ArrayAttr) { return; }
16551727
}];
1656-
16571728
}
16581729

16591730
def Xls_InstantiateEprocOp : Xls_Op<"instantiate_eproc", [DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
@@ -1763,7 +1834,10 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17631834
}];
17641835
let arguments = (ins
17651836
StrAttr:$name,
1766-
TypeAttr:$type
1837+
TypeAttr:$type,
1838+
OptionalAttr<Xls_FifoConfig>: $fifo_config,
1839+
OptionalAttr<Xls_FlopKindAttr>: $input_flop_kind,
1840+
OptionalAttr<Xls_FlopKindAttr>: $output_flop_kind
17671841
);
17681842
let results = (outs
17691843
Xls_SchanType:$out,
@@ -1774,7 +1848,10 @@ def Xls_SchanOp : Xls_Op<"schan", [Pure, HasParent<"SprocOp">]> {
17741848
OpBuilder<(ins "::mlir::StringRef":$name, "::mlir::Type":$element_type), [{
17751849
auto inChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/true);
17761850
auto outChanTy = SchanType::get($_builder.getContext(), element_type, /*isInput=*/false);
1777-
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name, element_type);
1851+
// TODO(jpienaar): Remove unecessary default args once they are generated automatically.
1852+
build($_builder, $_state, ::mlir::TypeRange{outChanTy, inChanTy}, name,
1853+
element_type, /*fifo_config=*/nullptr, /*input_flop_kind=*/nullptr,
1854+
/*output_flop_kind=*/nullptr);
17781855
}]>
17791856
];
17801857
}

xls/contrib/mlir/testdata/array_to_bits.mlir

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

226-
// CHECK-LABEL: xls.chan @mychan : i24
227-
xls.chan @mychan : !xls.array<3 x i8>
226+
// CHECK-LABEL: xls.chan @mychan {fifo_config = #xls.fifo_config<fifo_depth = 1, bypass = true, register_push_outputs = true, register_pop_outputs = false>} : i24
227+
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>
228228

229229
// CHECK-LABEL: xls.eproc @eproc(
230230
// 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) {
@@ -1454,7 +1468,30 @@ FailureOr<std::unique_ptr<Package>> mlirXlsToXls(
14541468
} else if (!chan_op.getRecvSupported()) {
14551469
kind = ::xls::ChannelOps::kSendOnly; // NOLINT
14561470
}
1457-
auto channel = package->CreateStreamingChannel(name, kind, xls_type);
1471+
1472+
std::optional<::xls::FifoConfig> fifo_config = std::nullopt;
1473+
if (auto mlir_fifo_config = chan_op.getFifoConfig()) {
1474+
fifo_config = ::xls::FifoConfig(
1475+
mlir_fifo_config->getFifoDepth(), mlir_fifo_config->getBypass(),
1476+
mlir_fifo_config->getRegisterPushOutputs(),
1477+
mlir_fifo_config->getRegisterPopOutputs());
1478+
}
1479+
1480+
std::optional<::xls::FlopKind> input_flop = std::nullopt;
1481+
std::optional<::xls::FlopKind> output_flop = std::nullopt;
1482+
if (auto attr = chan_op.getInputFlopKind()) {
1483+
input_flop = convertFlopKind(*attr);
1484+
}
1485+
if (auto attr = chan_op.getOutputFlopKind()) {
1486+
output_flop = convertFlopKind(*attr);
1487+
}
1488+
1489+
auto channel_config =
1490+
::xls::ChannelConfig(fifo_config, input_flop, output_flop);
1491+
1492+
auto channel = package->CreateStreamingChannel(name, kind, xls_type, {},
1493+
channel_config);
1494+
14581495
if (!channel.ok()) {
14591496
chan_op.emitOpError("failed to create streaming channel: ")
14601497
<< channel.status().message();

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,15 +1600,50 @@ absl::StatusOr<Operation*> translateProc(::xls::Proc& xls_proc,
16001600
// Channel Translation
16011601
//===----------------------------------------------------------------------===//
16021602

1603+
FlopKind convertFlopKind(::xls::FlopKind kind) {
1604+
switch (kind) {
1605+
case ::xls::FlopKind::kNone:
1606+
return FlopKind::kNone;
1607+
case ::xls::FlopKind::kFlop:
1608+
return FlopKind::kFlop;
1609+
case ::xls::FlopKind::kSkid:
1610+
return FlopKind::kSkid;
1611+
case ::xls::FlopKind::kZeroLatency:
1612+
return FlopKind::kZeroLatency;
1613+
}
1614+
}
1615+
16031616
absl::Status translateChannel(::xls::Channel& xls_chn, OpBuilder& builder,
16041617
MLIRContext* ctx, TranslationState& state) {
16051618
auto chn = builder.create<xls::ChanOp>(
16061619
builder.getUnknownLoc(),
16071620
/*name=*/builder.getStringAttr(xls_chn.name()),
16081621
/*type=*/TypeAttr::get(translateType(xls_chn.type(), builder, ctx)),
1622+
/*fifo_config=*/nullptr,
1623+
/*input_flop_kind=*/nullptr,
1624+
/*output_flop_kind=*/nullptr,
16091625
/*send_supported=*/builder.getBoolAttr(xls_chn.CanSend()),
16101626
/*recv_supported=*/builder.getBoolAttr(xls_chn.CanReceive()));
16111627

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

xls/contrib/mlir/transforms/array_to_bits.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,11 @@ 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(),
153+
op.getOutputFlopKindAttr(), op.getSendSupported(),
154+
op.getRecvSupported());
154155
return success();
155156
}
156157
};

0 commit comments

Comments
 (0)