单独编译模块和链接

Compiling Modules Separately and Linking

我正在用 chisel3 编译一些非常大的项目,有很多电线和连接。现在,顶级对象及其所有子模块都在同一个 Scala 包中,我 运行 sbt "runMain top.Instantiator --verilog"。但是,它在 FIRRTL 中崩溃:

[info] Done packaging.
[info] Running top.Instantiator --verilog --testArgs vcs
[info] [0.005] Elaborating design...
[info] [68.146] Done elaborating.
[error] (run-main-0) java.lang.NegativeArraySizeException
[error] java.lang.NegativeArraySizeException
[error]     at java.util.Arrays.copyOf(Arrays.java:3332)
[error]     at org.antlr.v4.runtime.ANTLRInputStream.load(ANTLRInputStream.java:101)
[error]     at org.antlr.v4.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:64)
[error]     at org.antlr.v4.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:60)
[error]     at org.antlr.v4.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:68)
[error]     at firrtl.Parser$$anonfun.apply(Parser.scala:35)
[error]     at firrtl.Parser$$anonfun.apply(Parser.scala:29)
[error]     at firrtl.Utils$.time(Utils.scala:135)
[error]     at firrtl.Parser$.parse(Parser.scala:29)
[error]     at firrtl.Driver$$anonfun$execute.apply(Driver.scala:171)
[error]     at firrtl.Driver$$anonfun$execute.apply(Driver.scala:140)
[error]     at logger.Logger$$anonfun$makeScope.apply(Logger.scala:129)
[error]     at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
[error]     at logger.Logger$.makeScope(Logger.scala:127)
[error]     at firrtl.Driver$.execute(Driver.scala:140)
[error]     at chisel3.Driver$.execute(Driver.scala:180)
[error]     at chisel3.Driver$.execute(Driver.scala:200)
[error]     at fringe.CommonMain$class.main(CommonMain.scala:64)
[error]     at top.Instantiator$.main(Instantiator.scala:17)
[error]     at top.Instantiator.main(Instantiator.scala)
[error]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]     at java.lang.reflect.Method.invoke(Method.java:498)
[error] Nonzero exit code: 1
[error] (Compile / runMain) Nonzero exit code: 1

我的猜测是项目中大量的电线和连接导致了一些溢出。有没有人有过这种错误的经验以及如何调试它的建议?现在,我的想法是 1)重构凿子代码,使其更容易编译 2) 找出一种方法分别为每个模块生成 verilog,然后 link 最后将它们一起生成。有没有一种非递归编译的方法,这样我在编译 top.Instantiator 时就不会 运行 陷入同样的​​错误? 3) 以某种方式将 packages/projects 分开,以便 sbt 分别处理每个

谢谢

增加想法4)在chisel和firrtl之间使用protobuf序列化。

我可以看到 firrtl 在解析器中爆炸了。 protobuf 支持是相当新的,但我相信它比基于 antlr 的解析器占用更少的内存。 这是从 chisel3

生成 firrtl protobuf 序列化的示例
import chisel3._

class XX extends Module {
  val io = IO(new Bundle {
    val i = Input(UInt(1.W))
    val o = Output(UInt(1.W))
  })

  io.o := io.i
}
object PB {
  def main(args: Array[String]): Unit = {
    val c = Driver.elaborate(() => new XX)
    Driver.dumpProto(c, None)
  }
}

然后您可以使用 firrtl 编译器生成 verilog

firrtl -i XX.pb -X verilog -o XX.v

或者构建您自己的编译器,例如

import firrtl._

object PB {
  def main(args: Array[String]): Unit = {
    Driver.execute(Array("-i", "XX.pb", "-X", "verilog", "-o", "XX.v"))
  }
}

您的其他选择可能值得追求,但这可能是一个更简单的快速解决方案。