From 36eaec3fa1177552693f123968883c6e18fe3cb8 Mon Sep 17 00:00:00 2001 From: Nandor Licker Date: Mon, 8 Jan 2024 07:26:41 -0800 Subject: [PATCH] [FIRRTL] Move intrinsics into their own tablegen file --- include/circt/Dialect/FIRRTL/FIRRTL.td | 1 + .../circt/Dialect/FIRRTL/FIRRTLExpressions.td | 73 +---------------- .../circt/Dialect/FIRRTL/FIRRTLIntrinsics.td | 82 +++++++++++++++++++ 3 files changed, 84 insertions(+), 72 deletions(-) create mode 100644 include/circt/Dialect/FIRRTL/FIRRTLIntrinsics.td diff --git a/include/circt/Dialect/FIRRTL/FIRRTL.td b/include/circt/Dialect/FIRRTL/FIRRTL.td index 4b80721b4c..860926c46d 100644 --- a/include/circt/Dialect/FIRRTL/FIRRTL.td +++ b/include/circt/Dialect/FIRRTL/FIRRTL.td @@ -21,6 +21,7 @@ include "FIRRTLStructure.td" include "FIRRTLDeclarations.td" include "FIRRTLStatements.td" include "FIRRTLExpressions.td" +include "FIRRTLIntrinsics.td" // Types include "FIRRTLTypes.td" diff --git a/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td b/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td index 64a43a9059..062c453fa5 100644 --- a/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td +++ b/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td @@ -865,77 +865,6 @@ def Mux4CellIntrinsicOp : PrimOp<"int.mux4cell"> { "`(` operands `)` attr-dict `:` functional-type(operands, $result)"; } -//===----------------------------------------------------------------------===// -// Verif and SV specific -//===----------------------------------------------------------------------===// - -def IsXIntrinsicOp : FIRRTLOp<"int.isX", - [HasCustomSSAName, Pure]> { - let summary = "Test for 'x"; - let description = [{ - The `int.isX` expression checks that the operand is not a verilog literal - 'x. FIRRTL doesn't have a notion of 'x per-se, but x can come in to the - system from external modules and from SV constructs. Verification - constructs need to explicitly test for 'x. - }]; - - let arguments = (ins FIRRTLBaseType:$arg); - let results = (outs NonConstUInt1Type:$result); - let hasFolder = 1; - let assemblyFormat = "$arg attr-dict `:` type($arg)"; -} - -def PlusArgsTestIntrinsicOp : FIRRTLOp<"int.plusargs.test", - [HasCustomSSAName, Pure]> { - let summary = "SystemVerilog `$test$plusargs` call"; - - let arguments = (ins StrAttr:$formatString); - let results = (outs NonConstUInt1Type:$found); - let assemblyFormat = "$formatString attr-dict"; -} - -def PlusArgsValueIntrinsicOp : FIRRTLOp<"int.plusargs.value", - [HasCustomSSAName, Pure]> { - let summary = "SystemVerilog `$value$plusargs` call"; - - let arguments = (ins StrAttr:$formatString); - let results = (outs NonConstUInt1Type:$found, AnyType:$result); - let assemblyFormat = "$formatString attr-dict `:` type($result)"; -} - -def HasBeenResetIntrinsicOp : FIRRTLOp<"int.has_been_reset", [Pure]> { - let summary = "Check that a proper reset has been seen."; - let description = [{ - The result of `firrtl.int.has_been_reset` reads as 0 immediately after simulation - startup and after each power-cycle in a power-aware simulation. The result - remains 0 before and during reset and only switches to 1 after the reset is - deasserted again. - - See the corresponding `verif.has_been_reset` operation. - }]; - let arguments = (ins NonConstClockType:$clock, AnyResetType:$reset); - let results = (outs NonConstUInt1Type:$result); - let hasFolder = 1; - let assemblyFormat = "$clock `,` $reset attr-dict `:` type($reset)"; -} - -def FPGAProbeIntrinsicOp : FIRRTLOp<"int.fpga_probe", []> { - let summary = "Mark a value to be observed through FPGA debugging facilities"; - - let description = [{ - The `firrtl.int.fpga_probe` intrinsic marks a value in - the IR to be made observable through FPGA debugging facilities. Most FPGAs - offer a form of signal observation or logic analyzer to debug a design. This - operation allows the IR to indicate which signals should be made observable - for debugging. Later FPGA-specific passes may then pick this information up - and materialize the necessary logic analyzers or tool scripts. - }]; - - let arguments = (ins AnyType:$input, NonConstClockType:$clock); - let results = (outs); - let assemblyFormat = "$clock `,` $input attr-dict `:` type($input)"; -} - //===----------------------------------------------------------------------===// // Verbatim //===----------------------------------------------------------------------===// @@ -1012,7 +941,7 @@ def VerbatimWireOp : FIRRTLOp<"verbatim.wire", //===----------------------------------------------------------------------===// // This assumes operands are ground types without explicitly checking -class SameGroundTypeOperandConstness +class SameGroundTypeOperandConstness : PredOpTrait< "operand constness must match", CPred<"isConst($" # a # ".getType()) == isConst($" # b # ".getType())">>; diff --git a/include/circt/Dialect/FIRRTL/FIRRTLIntrinsics.td b/include/circt/Dialect/FIRRTL/FIRRTLIntrinsics.td new file mode 100644 index 0000000000..2d8f1d6a81 --- /dev/null +++ b/include/circt/Dialect/FIRRTL/FIRRTLIntrinsics.td @@ -0,0 +1,82 @@ +//===- FIRRTLIntrinsics.td - FIRRTL intrinsic ops ----------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This describes the MLIR ops for FIRRTL intrinsics. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_DIALECT_FIRRTL_FIRRTLINTRINSICS_TD +#define CIRCT_DIALECT_FIRRTL_FIRRTLINTRINSICS_TD + +def IsXIntrinsicOp : FIRRTLOp<"int.isX", + [HasCustomSSAName, Pure]> { + let summary = "Test for 'x"; + let description = [{ + The `int.isX` expression checks that the operand is not a verilog literal + 'x. FIRRTL doesn't have a notion of 'x per-se, but x can come in to the + system from external modules and from SV constructs. Verification + constructs need to explicitly test for 'x. + }]; + + let arguments = (ins FIRRTLBaseType:$arg); + let results = (outs NonConstUInt1Type:$result); + let hasFolder = 1; + let assemblyFormat = "$arg attr-dict `:` type($arg)"; +} + +def PlusArgsTestIntrinsicOp : FIRRTLOp<"int.plusargs.test", + [HasCustomSSAName, Pure]> { + let summary = "SystemVerilog `$test$plusargs` call"; + + let arguments = (ins StrAttr:$formatString); + let results = (outs NonConstUInt1Type:$found); + let assemblyFormat = "$formatString attr-dict"; +} + +def PlusArgsValueIntrinsicOp : FIRRTLOp<"int.plusargs.value", + [HasCustomSSAName, Pure]> { + let summary = "SystemVerilog `$value$plusargs` call"; + + let arguments = (ins StrAttr:$formatString); + let results = (outs NonConstUInt1Type:$found, AnyType:$result); + let assemblyFormat = "$formatString attr-dict `:` type($result)"; +} + +def HasBeenResetIntrinsicOp : FIRRTLOp<"int.has_been_reset", [Pure]> { + let summary = "Check that a proper reset has been seen."; + let description = [{ + The result of `firrtl.int.has_been_reset` reads as 0 immediately after simulation + startup and after each power-cycle in a power-aware simulation. The result + remains 0 before and during reset and only switches to 1 after the reset is + deasserted again. + + See the corresponding `verif.has_been_reset` operation. + }]; + let arguments = (ins NonConstClockType:$clock, AnyResetType:$reset); + let results = (outs NonConstUInt1Type:$result); + let hasFolder = 1; + let assemblyFormat = "$clock `,` $reset attr-dict `:` type($reset)"; +} + +def FPGAProbeIntrinsicOp : FIRRTLOp<"int.fpga_probe", []> { + let summary = "Mark a value to be observed through FPGA debugging facilities"; + + let description = [{ + The `firrtl.int.fpga_probe` intrinsic marks a value in + the IR to be made observable through FPGA debugging facilities. Most FPGAs + offer a form of signal observation or logic analyzer to debug a design. This + operation allows the IR to indicate which signals should be made observable + for debugging. Later FPGA-specific passes may then pick this information up + and materialize the necessary logic analyzers or tool scripts. + }]; + + let arguments = (ins AnyType:$input, NonConstClockType:$clock); + let results = (outs); + let assemblyFormat = "$clock `,` $input attr-dict `:` type($input)"; +} +#endif // CIRCT_DIALECT_FIRRTL_FIRRTLINTRINSICS_TD