暴露在Chisel3中仅限于模拟的行为

huangapple go评论59阅读模式
英文:

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 ifdefs). 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 ifdefs). 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.

huangapple
  • 本文由 发表于 2023年5月11日 02:35:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定