凿子:在最终的Verilog中获取信号名称

问题描述

我想直接从Chisel代码自动执行ILA的实例化。这意味着实例化如下所示的模块:

i_ila my_ila(
.clk(clock),.probe0(a_signal_to_monitor),.probe1(another_signal_to_monitor),// and so on
);

我打算将要监视的信号存储在UInt的列表中,以便在模块详细说明的末尾可以生成上面的实例化代码,并将其复制/粘贴到最终代码中。 Verilog代码(或编写自动执行此操作的Python脚本)。

首先,是否有更好的方法可以做到这一点,也许是在FIRRTL级别?

即使我采用这种半手动方法,我也需要知道最终Verilog中信号的名称是什么,这不一定是代码UInt val的名称(并且此外,我不知道如何在不必将变量名重新输入为字符串的情况下自动获取)。我怎样才能得到它们?

解决方法

我想提供一个更完整的示例,但我想确保至少写点东西。这也需要充实,作为网站上的适当示例/教程。

FIRRTL具有对内置和自定义转换中的信号名称进行跟踪的强大支持。在这种情况下,基础结构就已经存在,但是它是高级用户API。简而言之,您可以创建将跟踪Annotations的FIRRTL Targets。然后,您可以发出自定义元数据文件或使用普通的FIRRTL注释文件(尝试使用CLI选项-foaf / --output-annotation-file)。

示例FIRRTL注释将在编译结束时发出自定义元数据文件:

// Example FIRRTL annotation with Custom serialization
// FIRRTL will track the name of this signal through compilation
case class MyMetadataAnno(target: ReferenceTarget)
    extends SingleTargetAnnotation[ReferenceTarget]
    with CustomFileEmission {
  def duplicate(n: ReferenceTarget) = this.copy(n)

  // API for serializing a custom metadata file
  // Note that multiple of this annotation will collide which is an error,not handled in this example
  protected def baseFileName(annotations: AnnotationSeq): String = "my_metadata"
  protected def suffix: Option[String] = Some(".txt")
  def getBytes: Iterable[Byte] =
    s"Annotated signal: ${target.serialize}".getBytes
}

case class声明和duplicate方法足以通过编译跟踪单个信号。 CustomFileEmission和相关的baseFileNamesuffixgetBytes方法定义了如何序列化我的自定义元数据文件。如注释中所述,在本示例中实现的情况下,我们只能有1个该MyMetadataAnno的实例,否则他们将尝试写入同一文件,这是一个错误。可以通过基于Target自定义文件名或编写FIRRTL转换以将此注释的多个集合为一个注释来处理。

然后我们需要一种在凿子中创建此注释的方法:

  def markSignal[T <: Data](x: T): T = {
    annotate(new ChiselAnnotation {
      // We can't call .toTarget until end of Chisel elaboration
      // .toFirrtl is called by Chisel at the end of elaboration
      def toFirrtl = MyMetadataAnno(x.toTarget)
    })
    x
  }

现在我们要做的就是在我们的凿子中使用这个简单的API

// Simple example with a marked signal
class Foo extends MultiIOModule {
  val in = IO(Flipped(Decoupled(UInt(8.W))))
  val out = IO(Decoupled(UInt(8.W)))

  markSignal(out.valid)

  out <> in
}

这将导致将文件my_metadata.txt写入内容如下的目标目录:

Annotated signal: ~Foo|Foo>out_valid

请注意,这是特殊的FIRRTL目标语法,它表示out_valid是存在于模块Foo中的带注释的信号。

在可执行示例中的完整代码: https://scastie.scala-lang.org/moEiIqZPTRCR5mLQNrV3zA