英文:
Exposing Simulation-only behavior in Chisel3
问题
I want to expose certain signals only during simulation (for performance monitoring purposes, etc...) that can be used during the debug process for various purposes. I could use the dontTouch
annotation to ensure that the counter, which is necessarily eliminated by DCE, is preserved in simulation and visible in the final waveform, but this would mean that the component would also be preserved during synthesis.
Chisel3 generates #ifndef SYNTHESIS
verilog macros for cases of VerificationStatement
(e.g. $printf
, $stop
, ...). Is there a way for a user to more generally use the #ifndef SYNTHESIS
macro within their designs or would I need to write my own FIRRTL/CIRCT annotations/passes to provide this functionality?
英文:
I want to expose certain signals only during simulation (for performance monitoring purposes, etc...) that can be used during the debug process for various purposes. I could use the dontTouch
annotation to ensure that the counter, which is necessarily eliminated by DCE, is preserved in simulation and visible in the final waveform, but this would mean that the component would also be preserved during synthesis.
Chisel3 generates 'ifndef SYNTHESIS
verilog macros for cases of VerificationStatement
(e.g. $printf
, $stop
, ...). Is there a way for a user to more generally use the 'ifndef SYNTHESIS
macro within their designs or would I need to write my own FIRRTL/CIRCT annotations/passes to provide this functionality?
答案1
得分: 3
An alternative approach would be to probe the internals of the design from the testbench. This uses a new feature of Chisel 6 (BoringUtils.tapAndRead
) to create cross-module references.
Here's a small example:
//> using scala "2.13.10"
//> using repository "https://s01.oss.sonatype.org/content/repositories/snapshots"
//> using lib "org.chipsalliance::chisel::6.0.0-M1+3-35860474-SNAPSHOT"
//> using plugin "org.chipsalliance:::chisel-plugin::6.0.0-M1+3-35860474-SNAPSHOT"
//> using options "-unchecked", "-deprecation", "-language:reflectiveCalls", "-feature", "-Xcheckinit", "-Ywarn-dead-code", "-Ywarn-unused", "-Ymacro-annotations"
import chisel3._
import chisel3.util.experimental.BoringUtils
import circt.stage.ChiselStage
class Bar extends RawModule {
val b = WireInit(Bool(), DontCare)
dontTouch(b)
}
class Foo extends RawModule {
val bar = Module(new Bar)
val a = WireInit(Bool(), BoringUtils.tapAndRead(bar.b))
dontTouch(a)
}
object Main extends App {
println(ChiselStage.emitSystemVerilog(new Foo))
}
Running this (scala-cli Foo.scala
) produces the following Verilog:
module Bar();
wire b = 1'h0;
endmodule
module Foo();
wire a = Foo.bar.b;
Bar bar ();
endmodule
You could also do this by creating a "debug module" inside Bar
with all the signals you want. This module can then be excluded from synthesis. There is no great mechanism to exclude a module from synthesis (either via emitting it as a Verilog bind
to a specific bind file or with ifdef
s). Support for instantiating a module via a bind
is expected soon-ish.
英文:
An alternative approach would be to probe the internals of the design from the testbench. This uses a new feature of Chisel 6 (BoringUtils.tapAndRead
) to create cross-module references.
Here's a small example:
//> using scala "2.13.10"
//> using repository "https://s01.oss.sonatype.org/content/repositories/snapshots"
//> using lib "org.chipsalliance::chisel::6.0.0-M1+3-35860474-SNAPSHOT"
//> using plugin "org.chipsalliance:::chisel-plugin::6.0.0-M1+3-35860474-SNAPSHOT"
//> using options "-unchecked", "-deprecation", "-language:reflectiveCalls", "-feature", "-Xcheckinit", "-Ywarn-dead-code", "-Ywarn-unused", "-Ymacro-annotations"
import chisel3._
import chisel3.util.experimental.BoringUtils
import circt.stage.ChiselStage
class Bar extends RawModule {
val b = WireInit(Bool(), DontCare)
dontTouch(b)
}
class Foo extends RawModule {
val bar = Module(new Bar)
val a = WireInit(Bool(), BoringUtils.tapAndRead(bar.b))
dontTouch(a)
}
object Main extends App {
println(ChiselStage.emitSystemVerilog(new Foo))
}
Running this (scala-cli Foo.scala
) produces the following Verilog:
module Bar();
wire b = 1'h0;
endmodule
module Foo();
wire a = Foo.bar.b;
Bar bar ();
endmodule
You could also do this by creating a "debug module" inside Bar
with all the signals you want. This module can then be excluded from synthesis. There is no great mechanism to exclude a module from synthesis (either via emitting it as a Verilog bind
to a specific bind file or with ifdef
s). Support for instantiating a module via a bind
is expected soon-ish.
答案2
得分: 1
在chiseltest中,我们提供了一个简单的expose
功能,允许您将设计中的任意信号作为输出在顶层中使用。如果您只想在模拟中使用它,技巧是创建一个模拟顶层模块,它只是包装了您的待测设计并添加了所有必要的expose
语句。请参考这个小例子。
英文:
In chiseltest we provide a simple expose
feature that allows you to make arbitrary signals from your design available as outputs in your toplevel. If you want to use this only for simulation, the trick is to make a simulation toplevel module that just wraps your design under test and adds all necessary expose
statements. Have a look at this small example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论