-
Notifications
You must be signed in to change notification settings - Fork 597
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for generic intrinsic expressions and statements. (#3986)
- Loading branch information
Showing
8 changed files
with
272 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chisel3 | ||
|
||
import chisel3._ | ||
import chisel3.experimental.{requireIsChiselType, Param, SourceInfo} | ||
import chisel3.internal.firrtl.ir._ | ||
import chisel3.internal.{Builder, OpBinding} | ||
import chisel3.internal.Builder.pushCommand | ||
|
||
object Intrinsic { | ||
|
||
/** Create an intrinsic statement. | ||
* | ||
* @param intrinsic name of the intrinsic | ||
* @param params parameter name/value pairs, if any. Parameter names must be unique. | ||
* @param data inputs | ||
* | ||
* @example {{{ | ||
* Intrinsic("test", "Foo" -> 5)(f, g) | ||
* }}} | ||
*/ | ||
def apply(intrinsic: String, params: (String, Param)*)(data: Data*)(implicit sourceInfo: SourceInfo): Unit = { | ||
require(params.map(_._1).distinct.size == params.size, "parameter names must be unique") | ||
pushCommand(DefIntrinsic(sourceInfo, intrinsic, data.map(_.ref), params)) | ||
} | ||
} | ||
|
||
object IntrinsicExpr { | ||
|
||
/** Create an intrinsic expression. | ||
* | ||
* @param intrinsic name of the intrinsic | ||
* @param ret return type of the expression | ||
* @param params parameter name/value pairs, if any. Parameter names must be unique. | ||
* @param data inputs | ||
* @return intrinsic expression that returns the specified return type | ||
* | ||
* @example {{{ | ||
* val test = IntrinsicExpr("test", UInt(32.W), "Foo" -> 5)(f, g) + 3.U | ||
* }}} | ||
*/ | ||
def apply[T <: Data]( | ||
intrinsic: String, | ||
ret: => T, | ||
params: (String, Param)* | ||
)(data: Data* | ||
)( | ||
implicit sourceInfo: SourceInfo | ||
): T = { | ||
val prevId = Builder.idGen.value | ||
val t = ret // evaluate once (passed by name) | ||
requireIsChiselType(t, "intrinsic type") | ||
val int = if (!t.mustClone(prevId)) t else t.cloneTypeFull | ||
|
||
int.bind(OpBinding(Builder.forcedUserModule, Builder.currentWhen)) | ||
require(params.map(_._1).distinct.size == params.size, "parameter names must be unique") | ||
pushCommand(DefIntrinsicExpr(sourceInfo, intrinsic, int, data.map(_.ref), params)) | ||
int | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chiselTests | ||
|
||
import chiselTests.{ChiselFlatSpec, MatchesAndOmits} | ||
import circt.stage.ChiselStage | ||
|
||
import chisel3._ | ||
|
||
class IntrinsicSpec extends ChiselFlatSpec with MatchesAndOmits { | ||
behavior.of("Intrinsics") | ||
|
||
it should "support a simple intrinsic statement" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
Intrinsic("test")() | ||
}) | ||
|
||
matchesAndOmits(chirrtl)("intrinsic(test)")() | ||
} | ||
|
||
it should "support intrinsic statements with arguments" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
val f = IO(UInt(3.W)) | ||
val g = IO(UInt(5.W)) | ||
Intrinsic("test")(f, g) | ||
}) | ||
|
||
matchesAndOmits(chirrtl)("intrinsic(test, f, g)")() | ||
} | ||
it should "support intrinsic statements with parameters and arguments" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
val f = IO(UInt(3.W)) | ||
val g = IO(UInt(5.W)) | ||
Intrinsic("test", "Foo" -> 5)(f, g) | ||
}) | ||
|
||
matchesAndOmits(chirrtl)("intrinsic(test<Foo = 5>, f, g)")() | ||
} | ||
|
||
it should "support intrinsic expressions" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
val f = IO(UInt(3.W)) | ||
val g = IO(UInt(5.W)) | ||
val test = IntrinsicExpr("test", UInt(32.W))(f, g) + 3.U | ||
}) | ||
|
||
matchesAndOmits(chirrtl)(" = intrinsic(test : UInt<32>, f, g)")() | ||
} | ||
|
||
it should "support intrinsic expressions with parameters and arguments" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
val f = IO(UInt(3.W)) | ||
val g = IO(UInt(5.W)) | ||
val test = IntrinsicExpr("test", UInt(32.W), "foo" -> "bar", "x" -> 5)(f, g) + 3.U | ||
}) | ||
|
||
matchesAndOmits(chirrtl)(" = intrinsic(test<foo = \"bar\", x = 5> : UInt<32>, f, g)")() | ||
} | ||
|
||
it should "preserve parameter order" in { | ||
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { | ||
val test = IntrinsicExpr("test", UInt(32.W), "x" -> 5, "foo" -> 3)() | ||
}) | ||
|
||
matchesAndOmits(chirrtl)(" = intrinsic(test<x = 5, foo = 3> : UInt<32>)")() | ||
} | ||
|
||
it should "requite unique parameter names" in { | ||
intercept[IllegalArgumentException] { | ||
ChiselStage.emitCHIRRTL(new RawModule { | ||
val test = IntrinsicExpr("test", UInt(32.W), "foo" -> 5, "foo" -> 3)() | ||
}) | ||
}.getMessage() should include( | ||
"parameter names must be unique" | ||
) | ||
} | ||
} |