2017-06-14 57 views
3

所以,我有一个关于凿码转换的理论问题。凿码转换

我知道凿子实际上是一组Scala的定义,所以它被编译成Java字节码,它依次运行在JVM中,就像魔法一样,它吐出了Verilog的等价描述,甚至是旧版本的C++描述的凿子。

问题是我无法弄清楚这个“魔法”是如何工作的。我的猜测是,从Chisel到Verilog/C++的代码转换全部基于Scala反射。但我不确定,因为我找不到与此主题相关的任何内容。

那么,这是关于反思吗?如果是这样,它是编译时间我们的运行时反射? 有人可以给我一个线索吗?

非常感谢。

回答

2

从根本上说,写凿是写一个Scala程序到生成一个电路。你所描述的内容听起来有点像高级合成,这与凿子完全不同。 Chisel不是将Scala(或Java)原语映射到硬件,而是执行Scala代码来构造一个hardware AST,然后将其编译为Verilog。

我会试着用一个带注释的例子更清楚一点。

// The body of a Scala class is the default constructor 
// MyModule's default constructor has a single Int argument 
// Superclass Module is a chisel3 Class that begins construction of a hardware module 
// Implicit clock and reset inputs are added by the Module constructor 
class MyModule(width: Int) extends Module { 
    // io is a required field for subclasses of Module 
    // new Bundle creates an instance of an anonymous subclass of Chisel's Bundle (like a struct) 
    // When executing the function IO(...), Chisel adds ports to the Module based on the Bundle object 
    val io = IO(new Bundle { 
    val in = Input(UInt(width.W)) // Input port with width defined by parameter 
    val out = Output(UInt()) // Output port with width inferred by Chisel 
    }) 

    // A Scala println that will print at elaboration time each time this Module is instantiated 
    // This does NOT create a node in the Module AST 
    println(s"Constructing MyModule with width $width") 

    // Adds a register declaration node to the Module AST 
    // This counter register resets to the value of input port io.in 
    // The implicit clock and reset inputs feed into this node 
    val counter = RegInit(io.in) 

    // Adds an addition node to the hardware AST with operands counter and 1 
    val inc = counter + 1.U // + is overloaded, this is actually a Chisel function call 

    // Connects the output of the addition node to the "next" value of counter 
    counter := inc 

    // Adds a printf node to the Module AST that will print at simulation time 
    // The value of counter feeds into this node 
    printf("counter = %d\n", counter) 
} 
+1

但是凿子检查自己以便生成FIRRTL?当你编译并运行你给出的例子时,Chisel中的硬件描述如何解释并导出firrtl?我只能认为它适用于反思。 – Rafael

+0

我会尽量做得更具体。当你用凿子写的时候,Scala的描述本身就是输出firrtl吗?还是有另一个外部工具可以扫描凿子的源代码并将其转换为firrtl?无论如何,谢谢你的回答。 – Rafael

+1

这是斯卡拉描述本身,出口Firrtl。这不是真的*反思;凿子函数调用像'UInt'和':='实际上是在一个给定的模块内部改变由Chisel构造的AST。凿子从顶层模块开始走这个AST,以发射Firrtl。我们*实际使用反射,但仅用于命名连线和寄存器,而不是用于构建AST。 – jkoenig

0

这也是我感兴趣的问题。我认为“构建硬件AST”是编程和编译为* .class。生成类时,如firrtl。在执行这些类之后,生成rtl,就像嵌入了一个工具链。但我不知道如何。希望任何人讲述更多。