Chisel: получение имени сигнала в окончательном Verilog

#chisel

#chisel

Вопрос:

Я хотел бы максимально автоматизировать создание экземпляра ILA непосредственно из кода Chisel. Это означает создание экземпляра модуля, который выглядит следующим образом:

 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 в коде (и которое, кроме того, я не знаю, как получить автоматически без необходимости повторного ввода именипеременной в виде строки где-нибудь). Как я могу их получить?

Ответ №1:

Я хотел бы привести более полный пример, но я хотел убедиться, что хотя бы что-то написал. Это также необходимо конкретизировать в качестве правильного примера / руководства на веб-сайте.

FIRRTL имеет надежную поддержку для отслеживания имен сигналов во встроенных и пользовательских преобразованиях. Это тот случай, когда вся инфраструктура есть, но это очень опытный пользовательский API. Короче говоря, вы можете создавать аннотации FIRRTL, которые будут отслеживать цели. Затем вы можете создавать пользовательские файлы метаданных или использовать обычный файл аннотаций 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 методы определяют, как сериализовать мой пользовательский файл метаданных. Как упоминалось в комментарии, как реализовано в этом примере, у нас может быть только 1 экземпляр этого MyMetadataAnno , или они попытаются записать тот же файл, что и ошибка. Это можно обработать, настроив имя файла на основе 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
  }
  

Теперь все, что нам нужно сделать, это использовать этот простой API в нашем Chisel

 // 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