-
Notifications
You must be signed in to change notification settings - Fork 615
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More Circt intrinsic wrappers (IsX, PlusArgsTest, PlusArgsValue) (#2958)
This extends the set of circt intrinsics with Chisel wrappers. These have no impact on code not using them.
- Loading branch information
Showing
8 changed files
with
266 additions
and
67 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,32 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chisel3.util.circt | ||
|
||
import chisel3._ | ||
import chisel3.experimental.IntrinsicModule | ||
import chisel3.internal.Builder | ||
|
||
import circt.Intrinsic | ||
|
||
/** Create a module with a parameterized type which returns whether the input | ||
* is a verilog 'x'. | ||
*/ | ||
private class IsXIntrinsic[T <: Data](gen: T) extends IntrinsicModule("circt_isX") { | ||
val i = IO(Input(gen)) | ||
val found = IO(Output(Bool())) | ||
} | ||
|
||
object IsX { | ||
|
||
/** Creates an intrinsic which returns whether the input is a verilog 'x'. | ||
* | ||
* @example {{{ | ||
* b := IsX(a) | ||
* }}} | ||
*/ | ||
def apply[T <: Data](gen: T): Bool = { | ||
val inst = Module(new IsXIntrinsic(chiselTypeOf(gen))) | ||
inst.i := gen | ||
inst.found | ||
} | ||
} |
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,35 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chisel3.util.circt | ||
|
||
import chisel3._ | ||
import chisel3.experimental.IntrinsicModule | ||
import chisel3.internal.Builder | ||
|
||
import circt.Intrinsic | ||
|
||
/** Create a module with a parameterized type which calls the verilog function | ||
* \$test\$plusargs to test for the existence of the string str in the | ||
* simulator command line. | ||
*/ | ||
private class PlusArgsTestIntrinsic[T <: Data](gen: T, str: String) | ||
extends IntrinsicModule("circt_plusargs_test", Map("FORMAT" -> str)) { | ||
val found = IO(Output(Bool())) | ||
} | ||
|
||
object PlusArgsTest { | ||
|
||
/** Creates an intrinsic which calls \$test\$plusargs. | ||
* | ||
* @example {{{ | ||
* b := PlusArgsTest(UInt<32.W>, "FOO") | ||
* }}} | ||
*/ | ||
def apply[T <: Data](gen: T, str: String): Bool = { | ||
Module(if (gen.isSynthesizable) { | ||
new PlusArgsTestIntrinsic(chiselTypeOf(gen), str) | ||
} else { | ||
new PlusArgsTestIntrinsic(gen, str) | ||
}).found | ||
} | ||
} |
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,54 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chisel3.util.circt | ||
|
||
import scala.language.reflectiveCalls | ||
|
||
import chisel3._ | ||
import chisel3.experimental.{FlatIO, IntrinsicModule} | ||
import chisel3.internal.Builder | ||
|
||
import circt.Intrinsic | ||
|
||
/** Create a module which generates a verilog \$value\$plusargs. This returns a | ||
* value as indicated by the format string and a flag for whether the value | ||
* was found. | ||
*/ | ||
private class PlusArgsValueIntrinsic[T <: Data](gen: T, str: String) | ||
extends IntrinsicModule("circt_plusargs_value", Map("FORMAT" -> str)) { | ||
val io = FlatIO(new Bundle { | ||
val found = Output(Bool()) | ||
val result = Output(gen) | ||
}) | ||
} | ||
|
||
object PlusArgsValue { | ||
|
||
/** Creates an intrinsic which calls \$value\$plusargs. | ||
* | ||
* @example {{{ | ||
* b := PlusArgsValue(UInt(32.W), "FOO=%d") | ||
* b.found | ||
* b.value | ||
* }}} | ||
*/ | ||
def apply[T <: Data](gen: T, str: String) = { | ||
Module(if (gen.isSynthesizable) { | ||
new PlusArgsValueIntrinsic(chiselTypeOf(gen), str) | ||
} else { | ||
new PlusArgsValueIntrinsic(gen, str) | ||
}).io | ||
} | ||
|
||
/** Creates an intrinsic which calls \$value\$plusargs and returns a default | ||
* value if the specified pattern is not found. | ||
* | ||
* @example {{{ | ||
* v := PlusArgsValue(UInt(32.W), "FOO=%d", 42.U) | ||
* }}} | ||
*/ | ||
def apply[T <: Data](gen: T, str: String, default: T): T = { | ||
val result = apply(gen, str) | ||
Mux(result.found, result.result, default) | ||
} | ||
} |
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,47 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chiselTests.util | ||
|
||
import chisel3._ | ||
import chisel3.stage.ChiselGeneratorAnnotation | ||
import chisel3.testers.BasicTester | ||
import chisel3.util.circt.IsX | ||
import circt.stage.ChiselStage | ||
|
||
import org.scalatest.flatspec.AnyFlatSpec | ||
import org.scalatest.matchers.should.Matchers | ||
|
||
import scala.io.Source | ||
|
||
private class IsXBundle extends Bundle { | ||
val a = UInt() | ||
val b = SInt() | ||
} | ||
|
||
private class IsXTop extends Module { | ||
val w = IO(Input(UInt(65.W))) | ||
val x = IO(Input(new IsXBundle)) | ||
val y = IO(Input(UInt(65.W))) | ||
val outw = IO(Output(UInt(1.W))) | ||
val outx = IO(Output(UInt(1.W))) | ||
val outy = IO(Output(UInt(1.W))) | ||
outw := IsX(w) | ||
outx := IsX(x) | ||
outy := IsX(y) | ||
} | ||
|
||
class IsXSpec extends AnyFlatSpec with Matchers { | ||
it should "Should work for types" in { | ||
val fir = ChiselStage.emitCHIRRTL(new IsXTop) | ||
println(fir) | ||
( | ||
(fir.split('\n').map(_.trim) should contain).allOf( | ||
"intmodule IsXIntrinsic :", | ||
"input i : UInt<65>", | ||
"output found : UInt<1>", | ||
"intrinsic = circt_isX", | ||
"input i : { a : UInt, b : SInt}" | ||
) | ||
) | ||
} | ||
} |
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,35 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chiselTests.util | ||
|
||
import chisel3._ | ||
import chisel3.testers.BasicTester | ||
import chisel3.util.circt.PlusArgsTest | ||
import circt.stage.ChiselStage | ||
|
||
import org.scalatest.flatspec.AnyFlatSpec | ||
import org.scalatest.matchers.should.Matchers | ||
|
||
import scala.io.Source | ||
|
||
private class PlusArgsTestTop extends Module { | ||
val w = IO(Output(UInt(1.W))) | ||
val x = IO(Output(UInt(1.W))) | ||
val z = IO(Input(UInt(32.W))) | ||
w := PlusArgsTest(UInt(32.W), "FOO") | ||
x := PlusArgsTest(z, "BAR") | ||
} | ||
|
||
class PlusArgsTestSpec extends AnyFlatSpec with Matchers { | ||
it should "Should work for types" in { | ||
val fir = ChiselStage.emitCHIRRTL(new PlusArgsTestTop) | ||
println(fir) | ||
(fir.split('\n').map(_.trim) should contain).allOf( | ||
"intmodule PlusArgsTestIntrinsic :", | ||
"output found : UInt<1>", | ||
"intrinsic = circt_plusargs_test", | ||
"parameter FORMAT = \"FOO\"", | ||
"parameter FORMAT = \"BAR\"" | ||
) | ||
} | ||
} |
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,44 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chiselTests.util | ||
|
||
import chisel3._ | ||
import chisel3.testers.BasicTester | ||
import chisel3.util.circt.PlusArgsValue | ||
import circt.stage.ChiselStage | ||
|
||
import org.scalatest.flatspec.AnyFlatSpec | ||
import org.scalatest.matchers.should.Matchers | ||
|
||
import scala.io.Source | ||
|
||
private class PlusArgsValueTop extends Module { | ||
val wf = IO(Output(UInt(1.W))) | ||
val wv = IO(Output(UInt(32.W))) | ||
val xf = IO(Output(UInt(1.W))) | ||
val xv = IO(Output(UInt(32.W))) | ||
val zv = IO(Output(UInt(32.W))) | ||
val tmpw = PlusArgsValue(UInt(32.W), "FOO=%d") | ||
val tmpx = PlusArgsValue(xv, "BAR=%d") | ||
zv := PlusArgsValue(xv, "BAR=%d", 42.U) | ||
wf := tmpw.found | ||
wv := tmpw.result | ||
xf := tmpx.found | ||
xv := tmpx.result | ||
} | ||
|
||
class PlusArgsValueSpec extends AnyFlatSpec with Matchers { | ||
it should "Should work for types" in { | ||
val fir = ChiselStage.emitCHIRRTL(new PlusArgsValueTop) | ||
println(fir) | ||
(fir.split('\n').map(_.trim.takeWhile(_ != '@')) should contain).inOrder( | ||
"intmodule PlusArgsValueIntrinsic :", | ||
"output found : UInt<1>", | ||
"output result : UInt<32>", | ||
"intrinsic = circt_plusargs_value", | ||
"parameter FORMAT = \"FOO=%d\"", | ||
"parameter FORMAT = \"BAR=%d\"", | ||
"node _zv_T = mux(PlusArgsValueIntrinsic_2.found, PlusArgsValueIntrinsic_2.result, UInt<6>(\"h2a\")) " | ||
) | ||
} | ||
} |
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 |
---|---|---|
@@ -1,64 +1,36 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package chiselTests.util | ||
|
||
import chisel3._ | ||
import chisel3.stage.ChiselGeneratorAnnotation | ||
import chisel3.testers.BasicTester | ||
import chisel3.util.circt.SizeOf | ||
|
||
import circt.stage.ChiselStage | ||
|
||
import firrtl.stage.FirrtlCircuitAnnotation | ||
|
||
import org.scalatest.flatspec.AnyFlatSpec | ||
import org.scalatest.matchers.should.Matchers | ||
|
||
import scala.io.Source | ||
|
||
class MyBundle extends Bundle { | ||
private class SizeOfBundle extends Bundle { | ||
val a = UInt() | ||
val b = SInt() | ||
} | ||
|
||
class SizeOfTop extends Module { | ||
val io = IO(new Bundle { | ||
val w = Input(UInt(65.W)) | ||
val x = Input(new MyBundle) | ||
val outw = UInt(32.W) | ||
val outx = UInt(32.W) | ||
}) | ||
io.outw := SizeOf(io.w) | ||
io.outx := SizeOf(io.x) | ||
private class SizeOfTop extends Module { | ||
val w = IO(Input(UInt(65.W))) | ||
val x = IO(Input(new SizeOfBundle)) | ||
val outw = IO(Output(UInt(32.W))) | ||
val outx = IO(Output(UInt(32.W))) | ||
outw := SizeOf(w) | ||
outx := SizeOf(x) | ||
} | ||
|
||
/** A test for intrinsics. Since chisel is producing intrinsics as tagged | ||
* extmodules (for now), we explicitly test the chirrtl and annotations rather | ||
* than the processed firrtl or verilog. It is worth noting that annotations | ||
* are implemented (for now) in a way which makes the output valid for all | ||
* firrtl compilers, hence we write a localized, not end-to-end test | ||
*/ | ||
class SizeOfSpec extends AnyFlatSpec with Matchers { | ||
it should "Should work for types" in { | ||
val fir = ChiselStage.emitCHIRRTL(new SizeOfTop) | ||
val a1 = """extmodule SizeOf_0""".r | ||
(fir should include).regex(a1) | ||
val b1 = """defname = SizeOf_0""".r | ||
(fir should include).regex(b1) | ||
val a2 = """extmodule SizeOf_1""".r | ||
(fir should include).regex(a2) | ||
val b2 = """defname = SizeOf_1""".r | ||
(fir should include).regex(b2) | ||
|
||
// The second elaboration uses a unique name since the Builder is reused (?) | ||
val c = """Intrinsic\(~SizeOfTop\|SizeOf.*,circt.sizeof\)""" | ||
((new ChiselStage) | ||
.execute( | ||
args = Array("--target", "chirrtl"), | ||
annotations = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => new SizeOfTop)) | ||
) | ||
.flatMap { | ||
case FirrtlCircuitAnnotation(circuit) => circuit.annotations | ||
case _ => None | ||
} | ||
.mkString("\n") should include).regex(c) | ||
println(fir) | ||
(fir.split('\n').map(_.trim) should contain) | ||
.allOf("intmodule SizeOfIntrinsic :", "input i : UInt<65>", "output size : UInt<32>", "intrinsic = circt_sizeof") | ||
} | ||
} |