2017-08-07 131 views
2

所以,我有一个关于凿子代码转换的理论问题。我已经知道凿子代码被编译为Java字节码,然后运行在JVM中,它发出等效的Verilog和C++源代码(用于旧版本的凿子)。凿子代码翻译成Verilog/C++

但是我在理解这个过程中遇到了很多麻烦。 例如,在凿子源代码中,我可以看到有一个Reg类,例如,创建一个寄存器的定义。然后我可以在硬件设计中导入和使用这个类。但我无法理解Reg类本身的描述与它的实际用法之间的区别在哪里。这很混乱。

例如,假设我正在开发一个使用Reg对象的项目,其中有一个名为whatever.scala的源代码,并且在此源代码中有Reg对象。据我了解,寄存器本身(Reg.scala)和使用它的源代码(whatever.scala)的描述都是同时编译的,这正是a不能得到的。

为了简短起见,在我看来,描述一个库和实际在构建它之后使用这个库是分开的。您必须先编译库,然后将其导入到项目中并使用它。但在凿子中,这两个步骤似乎同时发生。

在JVM代码发射和创建凿子AST之间是否存在任何中间过程?

回答

2

凿子是用于生成硬件设计的高级别高参数化嵌入式DSL。 甲凿程序通常包括几个步骤:

  • 甲chisel3 程序第一构造的理想化电路的内部表示作为abstact语法树(AST)。在世代结束时,AST被序列化为FIRRTL(中间表示)表示。参见:chisel3
  • firrtl转换引擎处理用某些转换通道生成的高级别FIRRTL。这些通道可以优化代码,进行宽度推理,并最终发出verilog或low firrt。见:firrtl
  • 通常在开发过程中,电路然后单元测试。有两种简单的方法可以做到这一点。
    • 发出的verilog可以通过verilator和C++编译器转换为可执行模拟。仿真可以使用验证电路的测试线束来执行。参见:chisel-testers
    • 或者,可以使用firrtl解释器模拟一个轻量级的scala程序,能够运行与凿子测试仪一样的单元测试。参见:firrtl-interpreter

这些步骤可以一起运行,使用凿子测试仪能自动地执行所有上述步骤。或者单独完成,每一步都可以生成输出文件,供用户添加定制集成或针对FPGA或芯片封装的Verilog。

JVM只是用于运行scala程序的执行环境,不需要理解或与之交互以便使用凿子构建电路。

+0

我明白你的观点。但是还是有一些让我困惑的东西,我给你举一个例子:假设在使用凿子的硬件描述中,有一个注册对象的声明,比方说,output_register = Reg(...)。作为后端,将会有一个C++或Verilog寄存器,其变量名称大致相同。所以,就像凿子在从凿子变成另一种语言时,它可以检查自己的变量名称,这似乎是反思。 Chisel在变换时如何知道它是自己的变量名称? – Rafael

+0

凿子确实使用反射。在创建模块时,在运行时检查变量以及引用凿子类型实例的变量。名称来自变量名称,由模块层次结构决定。 –

2

为了解决凿子对你的项目的问题:

凿是编译成JVM字节一个Scala库。 使用的项目凿子是连接凿子的Scala程序。该项目也编译为JVM字节码,但包括对单独编译的凿子库*的调用。然后使用Chisel执行该项目,并在JVM上运行。该程序的执行构建了一个最终以Verilog形式发布的硬件AST。

*许多项目(如rocket-chip)都将凿子源代码作为子项目。凿子通常先编制然后与之相连。但是,如果它一次编译完全没有区别 - 它只是其他Scala代码调用的Scala代码。