Chisel编译器非常慢

时间:2013-10-17 06:16:55

标签: scala matrix hdl chisel

我正在研究矩阵求和式设计。编译器需要4 +小时才能生成1百万行代码。每一行都是“赋值.....”我不知道这是编译器的低效率还是我的编码风格不好。如果有人可以建议一些非常好的选择!

以下是代码的说明 输入将使用随机矩阵逐元素并使用.reduce求和,因此结果矩阵应该是140X6 vec,cat它们一起给我一个840位输出

(rndvec,它应该是一个140x840x6位的随机矩阵。因为我不知道如何生成随机值所以我开始用一个固定的140x6代表一行并一次又一次地输入它)< / p>

以下是我的代码

import Chisel._
import scala.collection.mutable.HashMap
import util.Random

class LBio(n: Int) extends Bundle {
   var myinput = UInt(INPUT,840)
   var myoutput = UInt (OUTPUT,840)

}


class Lbi(q: Int,n:Int,m :Int ) extends Module{
   def mask(orig: Vec[UInt],maska:UInt,mi:Int)={
   val result = Vec.fill(840){UInt(width =6)}
    for (i<-0 until 840 ){
         result(i) := orig(i)&Fill(6,maska(i))  //every bits of input AND with random vector 
      }


     result
   }

  val io= new LBio(840)

   val rndvec =  Vec.fill(840){UInt("h13",6)}       //random vector, for now its just replication of 0x13....
   val resultvec = Vec.fill(140){UInt(width = 6)}

  for (i<-0 until 140){

       resultvec(i) := mask(rndvec,io.myinput,m).reduce(_+_)  //add the entire row of 6 bits element together with reduce

  }

 io.myoutput := resultvec.toBits


}

终端报告:

started inference
finished inference (4)
start width checking
finished width checking
started flattenning
finished flattening (941783)
resolving nodes to the components
finished resolving
started transforms
finished transforms
checking for combinational loops
NO COMBINATIONAL LOOP FOUND
COMPILING class TutorialExamples.Lbi 0 CHILDREN (0,0)
[success] Total time: 33453 s, completed Oct 16, 2013 10:32:10 PM

1 个答案:

答案 0 :(得分:2)

你的Chisel代码没有明显的错误,但是我应该指出,如果rndvec是140x840x6位,那就是~689kB的状态!你的减速操作是在5kB的状态。

Chisel使用“assign”语句,因为你的代码是完全组合的,Chisel生成了一种非常结构化的Verilog形式。

我怀疑杀死编译时间的部分(除了大量的状态)是你使用mask()函数生成和操作140 Vecs。

我尝试重写代码并将其从941,783个节点下载到202,723(编译大约需要10-15分钟,但生成11MB的Verilog代码)。我很确定这会影响您的代码:

class Hello(q: Int, dim_n:Int) extends Module
{
    val io = new LBio(dim_n)

    val rndvec = Vec.fill(dim_n){UInt("h13",6)}
    val resultvec = Vec.fill(dim_n/6){UInt(width=6)}

    // lift this work outside of the for loop
    val padded_input = Vec.fill(dim_n){UInt(width=6)}
    for (i <- 0 until dim_n)
    {
       padded_input(i) := Fill(6,io.myinput)
    }  

    for (i <- 0 until dim_n/6)
    {
       val result = Bits(width=dim_n*6)
       result := rndvec.toBits & padded_input.toBits

       var sum = UInt(0) //advanced Chisel - be careful with the use of var!
       for (j <- 0 until dim_n by 6)
       {
          sum = sum + result(j+6,j)
       }  
       resultvec(i) := sum
    }  

    io.myoutput := resultvec.toBits
}  

我所做的是避免一遍又一遍地做同样的工作 - 比如在for循环的mask()函数中填充myinput Vec。我还把所有东西都保存在Bits()而不是Vecs中。可悲的是,这意味着我失去了令人敬畏的.reduce()函数。

我想也许答案是“认识到你创造了多少状态”和“Vecs很棒,但要小心使用”。

你有一个简洁明了的Verilog版本吗?看看Chisel是否存在效率明显下降的领域会很有趣。