Chisel:在最终 Verilog 中获取信号名称
Chisel: getting signal name in final Verilog
我想尽可能多地自动从 Chisel 代码中直接对 ILA 进行实例化。这意味着实例化一个看起来像这样的模块:
i_ila my_ila(
.clk(clock),
.probe0(a_signal_to_monitor),
.probe1(another_signal_to_monitor),
// and so on
);
我打算将我想要监视的信号存储在 UInt
的列表中,以便在模块详细说明结束时我可以生成上面的实例化代码,我将 copy/paste 在最终的 Verilog 代码中(或编写一个自动执行此操作的 Python 脚本)。
首先,是否有更好的方法来执行此操作,也许是在 FIRRTL 级别?
即使我采用这种半手动方法,我也需要知道最终 Verilog 中的信号名称是什么,这不一定是代码中 UInt
值的名称(此外,我不知道如何自动获取而不必在某处将变量名称重新键入为字符串)。我怎样才能得到它们?
我想提供一个更完整的例子,但我想确保至少写点东西。这也需要在网站上充实为适当的 example/tutorial。
FIRRTL 对跨 built-in 和自定义转换跟踪信号名称提供了强大的支持。在这种情况下,基础架构就在那里,但它是一个超级用户 API。简而言之,您可以创建 FIRRTL Annotations that will track 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
和相关的 baseFileName
、suffix
和 getBytes
方法定义了如何序列化我的自定义元数据文件。正如评论中提到的,如本示例中所实现的,我们只能拥有此 MyMetadataAnno
的 1 个实例,否则他们将尝试写入相同的文件,这是一个错误。这可以通过根据 Target
自定义文件名或编写 FIRRTL 转换以将多个此注释聚合为单个注释来处理。
然后我们需要一种在 Chisel 中创建此注释的方法:
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
}
现在我们需要做的就是在我们的 Chisel
中使用这个简单的 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
我想尽可能多地自动从 Chisel 代码中直接对 ILA 进行实例化。这意味着实例化一个看起来像这样的模块:
i_ila my_ila(
.clk(clock),
.probe0(a_signal_to_monitor),
.probe1(another_signal_to_monitor),
// and so on
);
我打算将我想要监视的信号存储在 UInt
的列表中,以便在模块详细说明结束时我可以生成上面的实例化代码,我将 copy/paste 在最终的 Verilog 代码中(或编写一个自动执行此操作的 Python 脚本)。
首先,是否有更好的方法来执行此操作,也许是在 FIRRTL 级别?
即使我采用这种半手动方法,我也需要知道最终 Verilog 中的信号名称是什么,这不一定是代码中 UInt
值的名称(此外,我不知道如何自动获取而不必在某处将变量名称重新键入为字符串)。我怎样才能得到它们?
我想提供一个更完整的例子,但我想确保至少写点东西。这也需要在网站上充实为适当的 example/tutorial。
FIRRTL 对跨 built-in 和自定义转换跟踪信号名称提供了强大的支持。在这种情况下,基础架构就在那里,但它是一个超级用户 API。简而言之,您可以创建 FIRRTL Annotations that will track 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
和相关的 baseFileName
、suffix
和 getBytes
方法定义了如何序列化我的自定义元数据文件。正如评论中提到的,如本示例中所实现的,我们只能拥有此 MyMetadataAnno
的 1 个实例,否则他们将尝试写入相同的文件,这是一个错误。这可以通过根据 Target
自定义文件名或编写 FIRRTL 转换以将多个此注释聚合为单个注释来处理。
然后我们需要一种在 Chisel 中创建此注释的方法:
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
}
现在我们需要做的就是在我们的 Chisel
中使用这个简单的 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