2017-06-14 70 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,就像嵌入了一個工具鏈。但我不知道如何。希望任何人講述更多。