Skip to content

Commit d409ccd

Browse files
author
MoritzScherer
authored
[Moore] Add builtin for $urandom (llvm#8968)
1 parent 15c0a0d commit d409ccd

File tree

5 files changed

+80
-7
lines changed

5 files changed

+80
-7
lines changed

include/circt/Dialect/Moore/MooreOps.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,26 @@ def FormatRealOp : MooreOp<"fmt.real", [Pure]> {
17411741
class Builtin<string mnemonic, list<Trait> traits = []> :
17421742
MooreOp<"builtin." # mnemonic, traits>;
17431743

1744+
//===----------------------------------------------------------------------===//
1745+
// Pseudo-Random Generators
1746+
//===----------------------------------------------------------------------===//
1747+
1748+
def UrandomBIOp : Builtin<"urandom"> {
1749+
let summary = "Generate a pseudo-random unsigned integer (optionally seeded)";
1750+
let description = [{
1751+
Corresponds to the `$urandom` system function. Returns a 32-bit
1752+
pseudo-random integer. The seed is optional; when provided, it initializes
1753+
the generator. If not provided, treat it as 0 in semantics/lowering.
1754+
1755+
See IEEE 1800-2023 § 18.13 "Random number system functions and methods".
1756+
}];
1757+
1758+
// Optional positional attribute for the seed
1759+
let arguments = (ins Optional<TwoValuedI32>:$seed);
1760+
let results = (outs TwoValuedI32:$result);
1761+
let assemblyFormat = "($seed^)? attr-dict";
1762+
}
1763+
17441764
//===----------------------------------------------------------------------===//
17451765
// Simulation Control Builtins
17461766
//===----------------------------------------------------------------------===//

include/circt/Dialect/Moore/MooreTypes.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,13 @@ def FourValuedI64 : MooreType<CPred<[{
483483
let builderCall = "IntType::getLogic($_builder.getContext(), 64)";
484484
}
485485

486+
// A 32-bit two-valued integer.
487+
def TwoValuedI32 : MooreType<CPred<[{
488+
moore::isIntType($_self, 32, moore::Domain::TwoValued)
489+
}]>, "32-bit two-valued integer type", "moore::IntType"> {
490+
let builderCall = "IntType::getInt($_builder.getContext(), 32)";
491+
}
492+
486493
/// A packed or unpacked array type with a fixed size.
487494
def AnyStaticArrayType : MooreType<
488495
Or<[ArrayType.predicate, UnpackedArrayType.predicate]>,

lib/Conversion/ImportVerilog/Expressions.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -984,17 +984,29 @@ struct RvalueExprVisitor : public ExprVisitor {
984984
const auto &subroutine = *info.subroutine;
985985
auto args = expr.arguments();
986986

987-
if (args.size() == 1) {
988-
auto value = context.convertRvalueExpression(*args[0]);
987+
FailureOr<Value> result;
988+
Value value;
989+
990+
switch (args.size()) {
991+
case (0):
992+
result = context.convertSystemCallArity0(subroutine, loc);
993+
break;
994+
995+
case (1):
996+
value = context.convertRvalueExpression(*args[0]);
989997
if (!value)
990998
return {};
991-
auto result = context.convertSystemCallArity1(subroutine, loc, value);
992-
if (failed(result))
993-
return {};
994-
if (*result)
995-
return *result;
999+
result = context.convertSystemCallArity1(subroutine, loc, value);
1000+
break;
1001+
1002+
default:
1003+
break;
9961004
}
9971005

1006+
if (failed(result))
1007+
return {};
1008+
if (*result)
1009+
return *result;
9981010
mlir::emitError(loc) << "unsupported system call `" << subroutine.name
9991011
<< "`";
10001012
return {};
@@ -1572,6 +1584,20 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
15721584
return value;
15731585
}
15741586

1587+
FailureOr<Value>
1588+
Context::convertSystemCallArity0(const slang::ast::SystemSubroutine &subroutine,
1589+
Location loc) {
1590+
1591+
auto systemCallRes =
1592+
llvm::StringSwitch<std::function<FailureOr<Value>()>>(subroutine.name)
1593+
.Case("$urandom",
1594+
[&]() -> Value {
1595+
return moore::UrandomBIOp::create(builder, loc, nullptr);
1596+
})
1597+
.Default([&]() -> Value { return {}; });
1598+
return systemCallRes();
1599+
}
1600+
15751601
FailureOr<Value>
15761602
Context::convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
15771603
Location loc, Value value) {
@@ -1661,6 +1687,10 @@ Context::convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
16611687
[&]() -> Value {
16621688
return moore::AtanhBIOp::create(builder, loc, value);
16631689
})
1690+
.Case("$urandom",
1691+
[&]() -> Value {
1692+
return moore::UrandomBIOp::create(builder, loc, value);
1693+
})
16641694
.Default([&]() -> Value { return {}; });
16651695
return systemCallRes();
16661696
}

lib/Conversion/ImportVerilog/ImportVerilogInternals.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ struct Context {
181181
moore::IntFormat defaultFormat = moore::IntFormat::Decimal,
182182
bool appendNewline = false);
183183

184+
/// Convert system function calls only have arity-0.
185+
FailureOr<Value>
186+
convertSystemCallArity0(const slang::ast::SystemSubroutine &subroutine,
187+
Location loc);
188+
184189
/// Convert system function calls only have arity-1.
185190
FailureOr<Value>
186191
convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,

test/Conversion/ImportVerilog/builtins.sv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,14 @@ function void MathBuiltins(int x, logic [41:0] y, real r);
263263
// CHECK: moore.builtin.atanh [[R]] : real
264264
dummyB($atanh(r));
265265
endfunction
266+
267+
// CHECK-LABEL: func.func private @RandomBuiltins(
268+
// CHECK-SAME: [[X:%.+]]: !moore.i32
269+
function RandomBuiltins(int x);
270+
// CHECK: [[RAND0:%.+]] = moore.builtin.urandom
271+
// CHECK-NEXT: call @dummyA([[RAND0]]) : (!moore.i32) -> ()
272+
dummyA($urandom());
273+
// CHECK: [[RAND1:%.+]] = moore.builtin.urandom [[X]]
274+
// CHECK-NEXT: call @dummyA([[RAND1]]) : (!moore.i32) -> ()
275+
dummyA($urandom(x));
276+
endfunction

0 commit comments

Comments
 (0)