From 025d0398f898742f6838b1dd258eb687ef6750cd Mon Sep 17 00:00:00 2001 From: XLS Team Date: Mon, 22 Jun 2026 19:41:31 -0700 Subject: [PATCH] Port delay_ps field in TranslationLinkage to MLIR Additionally, replace the hardcoded string "xls.name" and "xls.linkage" with constant declaration. PiperOrigin-RevId: 936381313 --- xls/contrib/mlir/IR/xls_ops.cc | 8 +++----- xls/contrib/mlir/IR/xls_ops.h | 3 +++ xls/contrib/mlir/IR/xls_ops.td | 10 +++++++--- .../mlir/testdata/translate_foreign.mlir | 4 +++- .../xls_translate/xls_translate_from_mlir.cc | 17 +++++++++++------ xls/contrib/mlir/transforms/arith_to_xls.cc | 9 ++++++--- .../mlir/transforms/normalize_xls_calls.cc | 9 +++++---- 7 files changed, 38 insertions(+), 22 deletions(-) diff --git a/xls/contrib/mlir/IR/xls_ops.cc b/xls/contrib/mlir/IR/xls_ops.cc index 1fc2b0c4c1..659055a78d 100644 --- a/xls/contrib/mlir/IR/xls_ops.cc +++ b/xls/contrib/mlir/IR/xls_ops.cc @@ -157,8 +157,7 @@ LogicalResult verifyImportedVerilogFunctionArgumentsAndResults( << "for Verilog imported function all arguments should " "be named (use xls.name attribute)"; } - StringRef attrName = "xls.name"; - if (!dictAttr.contains(attrName)) { + if (!dictAttr.contains(kNameAttr)) { func->emitError() << "for Verilog imported function all arguments" " should be named (use xls.name attribute)"; return failure(); @@ -174,8 +173,7 @@ LogicalResult verifyImportedVerilogFunctionArgumentsAndResults( << "for Verilog imported function all results should " "be named (use xls.name attribute)"; } - StringRef attrName = "xls.name"; - if (!dictAttr.contains(attrName)) { + if (!dictAttr.contains(kNameAttr)) { func->emitError() << "for Verilog imported function all results should " "be named (use xls.name attribute)"; return failure(); @@ -371,7 +369,7 @@ LogicalResult ImportVerilogFileOp::verifySymbolUses( if (!func) { continue; } - auto linkage = func->getAttrOfType("xls.linkage"); + auto linkage = func->getAttrOfType(kLinkageAttr); if (!linkage) { continue; } diff --git a/xls/contrib/mlir/IR/xls_ops.h b/xls/contrib/mlir/IR/xls_ops.h index f15a1c3e37..6db41b94c9 100644 --- a/xls/contrib/mlir/IR/xls_ops.h +++ b/xls/contrib/mlir/IR/xls_ops.h @@ -42,6 +42,9 @@ namespace mlir::xls { +constexpr llvm::StringLiteral kNameAttr = "xls.name"; +constexpr llvm::StringLiteral kLinkageAttr = "xls.linkage"; + class XlsDialect : public Dialect { public: explicit XlsDialect(mlir::MLIRContext* ctx); diff --git a/xls/contrib/mlir/IR/xls_ops.td b/xls/contrib/mlir/IR/xls_ops.td index 9cb2c2b6a1..a1f1115e9e 100644 --- a/xls/contrib/mlir/IR/xls_ops.td +++ b/xls/contrib/mlir/IR/xls_ops.td @@ -125,14 +125,18 @@ def Xls_LinkageKindAttr : EnumAttr def Xls_TranslationLinkage : Xls_Attr<"TranslationLinkage"> { let summary = "Translation linkage attribute"; let description = [{ - Refers to a DSLX package and symbol to resolve too at translation time. + Refers to a DSLX package and symbol to resolve at translation time. + If specified, `delay_ps` overrides the global default delay for a foreign function. }]; let parameters = (ins "::mlir::SymbolRefAttr":$package, "::mlir::StringAttr":$function, - DefaultValuedParameter<"mlir::xls::LinkageKind", "LinkageKind::kImport">:$kind); + DefaultValuedParameter<"mlir::xls::LinkageKind", "LinkageKind::kImport">:$kind, + OptionalParameter<"std::optional">:$delay_ps + ); let mnemonic = "translation_linkage"; - let assemblyFormat = "`<` $package `:` $function (`,` $kind^)? `>`"; + let assemblyFormat = + "`<` $package `:` $function (`,` $kind^)? (`,` `delay` `=` $delay_ps^)? `>`"; let attrName = "xls.translation_linkage"; } diff --git a/xls/contrib/mlir/testdata/translate_foreign.mlir b/xls/contrib/mlir/testdata/translate_foreign.mlir index d68fdec77b..d14f998ea8 100644 --- a/xls/contrib/mlir/testdata/translate_foreign.mlir +++ b/xls/contrib/mlir/testdata/translate_foreign.mlir @@ -2,6 +2,8 @@ // RUN: xls_translate --mlir-xls-to-verilog %s -- --ffi_fallback_delay_ps=100 --generator=combinational 2>&1 | FileCheck %s --dump-input-filter=all --check-prefix=VERILOG // XLS: #[ffi_proto("""code_template: "int_to_float {fn}(.x({x}), .out({return}))" +// XLS-NEXT: delay_ps: 1500 +// XLS-NEXT: """)] // XLS: fn __struct_type__int_to_float // XLS-SAME: x @@ -9,7 +11,7 @@ xls.import_dslx_file_package "xls/contrib/mlir/testdata/struct_type.x" as @struct_type func.func private @int_to_float(%a: i32) -> f32 attributes - {xls.linkage = #xls.translation_linkage<@struct_type:"int_to_float", foreign>} + {xls.linkage = #xls.translation_linkage<@struct_type:"int_to_float", foreign, delay = 1500>} func.func private @float_to_int(%a: f32) -> i32 attributes {xls.linkage = #xls.translation_linkage<@struct_type:"float_to_int", foreign>} diff --git a/xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc b/xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc index 82970f1ce1..63ee3f59ba 100644 --- a/xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc +++ b/xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc @@ -1468,7 +1468,7 @@ bool isVerilogImport(Operation* op, const ModuleOp& module, XlsRegionOpInterface& xlsRegion) { bool isImportedVerilog = false; if (auto func = dyn_cast(op)) { - auto linkage = func->getAttrOfType("xls.linkage"); + auto linkage = func->getAttrOfType(kLinkageAttr); if (linkage) { Operation* importOp = translationState.getSymbolTable().lookupSymbolIn( module, linkage.getPackage()); @@ -1495,11 +1495,10 @@ LogicalResult getArgumentNamesForVerilogImport( ::std::optional argAttrs = func.getArgAttrs(); const Region::BlockArgListType& argValues = xls_region.getBodyRegion().getArguments(); - StringRef attrName = "xls.name"; ArrayRef attrArgs = argAttrs->getValue(); for (auto [argValue, attr] : zip(argValues, attrArgs)) { auto dictAttr = dyn_cast(attr); - auto nameAttr = dictAttr.getNamed(attrName); + auto nameAttr = dictAttr.getNamed(kNameAttr); ::xls::Type* xls_type = translation_state.getType(argValue.getType()); if (!xls_type) { return failure(); @@ -1546,7 +1545,7 @@ LogicalResult annotateForeignFunction(FuncOp func, ::xls::Function& xlsFunc) { return func->emitError() << "there should be one result when importing" " a verilog function"; } - auto linkage = func->getAttrOfType("xls.linkage"); + auto linkage = func->getAttrOfType(kLinkageAttr); if (!linkage || linkage.getKind() != LinkageKind::kForeign) { return func->emitError() << "expected foreign xls.linkage attribute"; } @@ -1560,7 +1559,7 @@ LogicalResult annotateForeignFunction(FuncOp func, ::xls::Function& xlsFunc) { if (!dictAttr) { continue; } - std::optional namedAttr = dictAttr.getNamed("xls.name"); + std::optional namedAttr = dictAttr.getNamed(kNameAttr); if (namedAttr != std::nullopt) { auto nameAttr = cast(namedAttr->getValue()); resultName = nameAttr.getValue(); @@ -1583,6 +1582,9 @@ LogicalResult annotateForeignFunction(FuncOp func, ::xls::Function& xlsFunc) { return failure(); } + if (linkage.getDelayPs().has_value()) { + ffd->set_delay_ps(linkage.getDelayPs().value()); + } xlsFunc.SetForeignFunctionData(ffd.value()); return success(); } @@ -1942,7 +1944,7 @@ FailureOr> mlirXlsToXls(Operation* op, isVerilogImport(&op, module, translation_state, xls_region); // Skip function declarations for now. if (auto func = dyn_cast(op); func && func.isDeclaration()) { - auto linkage = func->getAttrOfType("xls.linkage"); + auto linkage = func->getAttrOfType(kLinkageAttr); if (!linkage) { continue; } @@ -1981,6 +1983,9 @@ FailureOr> mlirXlsToXls(Operation* op, << ffd.status().message(); return failure(); } + if (linkage.getDelayPs().has_value()) { + ffd->set_delay_ps(linkage.getDelayPs().value()); + } xlsFunc.value()->SetForeignFunctionData(ffd.value()); } continue; diff --git a/xls/contrib/mlir/transforms/arith_to_xls.cc b/xls/contrib/mlir/transforms/arith_to_xls.cc index 8987c56530..d6af393d28 100644 --- a/xls/contrib/mlir/transforms/arith_to_xls.cc +++ b/xls/contrib/mlir/transforms/arith_to_xls.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include #include #include @@ -54,7 +56,8 @@ FuncOp maybeDeclareDslxFn(SymbolTable& symtab, OpBuilder builder, const std::string& symbolName, const std::string& dslxName, xls::ImportDslxFilePackageOp importOp, - TypeRange results, TypeRange operands) { + TypeRange results, TypeRange operands, + std::optional delayPs = {}) { if (auto fn = symtab.lookup(symbolName)) { return fn; } @@ -62,10 +65,10 @@ FuncOp maybeDeclareDslxFn(SymbolTable& symtab, OpBuilder builder, FuncOp fn = FuncOp::create(builder, importOp->getLoc(), symbolName, builder.getFunctionType(operands, results), {}); fn.setVisibility(SymbolTable::Visibility::Private); - fn->setAttr("xls.linkage", + fn->setAttr(kLinkageAttr, xls::TranslationLinkage::get( builder.getContext(), SymbolRefAttr::get(importOp), - builder.getStringAttr(dslxName), /*kind=*/{})); + builder.getStringAttr(dslxName), /*kind=*/{}, delayPs)); return fn; } diff --git a/xls/contrib/mlir/transforms/normalize_xls_calls.cc b/xls/contrib/mlir/transforms/normalize_xls_calls.cc index 841da422d8..8abb02ae19 100644 --- a/xls/contrib/mlir/transforms/normalize_xls_calls.cc +++ b/xls/contrib/mlir/transforms/normalize_xls_calls.cc @@ -97,10 +97,11 @@ void NormalizeXlsCallsPass::runOnOperation() { llvm::formatv("{0}_{1}", path.stem(), call.getFunction()).str(), newType); func.setVisibility(SymbolTable::Visibility::Private); - func->setAttr("xls.linkage", xls::TranslationLinkage::get( - builder.getContext(), - SymbolRefAttr::get(it->second.front()), - call.getFunctionAttr(), /*kind=*/{})); + func->setAttr(kLinkageAttr, xls::TranslationLinkage::get( + builder.getContext(), + SymbolRefAttr::get(it->second.front()), + call.getFunctionAttr(), /*kind=*/{}, + /*delay_ps=*/{})); // Ensure unique symbol name. symbolTable.insert(func); fIt->second.push_back(func);