2017-09-01 10 views
1

私は下のチゼルコードから生成されたVerilogに問題があり、これは私がチゼルコードを書いた方法に関連していると思います。生成されたVerilog出力でScalaバージョンと私のコードのchiselバージョンを下回っています。ここでチゼルk最近隣のVerilog出力

は、私のコードのScalaのバージョンである:ここで

class NearestNeighbours(k: Int, dataX: Array[Array[Double]], dataY: Seq[String]){      
    object predict{                     
     def apply(X: Array[Double]): String = {              
      val distances = dataX.indices.map{y=>              
       val Rsum=X.zip(dataX(y)).foldLeft(0.0){case (acc, (i,j))=>        
       acc + ((i-j)*(i-j))                  
       }                      
       sqrt(Rsum)                    
      }                       
     val topKClasses = distances.zipWithIndex.sortBy(_._1).take(k).map{case (dist, idx)=>dataY(idx)} 
      topKClasses.groupBy(identity).mapValues(_.size).maxBy(_._2)._1        

     }                         
    }                          
} 

はチゼルバージョンです。誰かが私のコードを調べて、どこが間違っているのか確認できますか?

class HardwareNearestNeighbours(val fixedType: FixedPoint, 
         val k: Int, 
         val keySize: Int, 
         val dataY: Seq[String], 
         val dataX: Array[Array[Double]]) extends Module { 
    val io = IO(new Bundle { 
    val x = Input(Vec(keySize, fixedType)) 
    val out = Output(fixedType) 
    }) 
     private val tabHash0 = dataX.map(_.map(_.F(fixedType.getWidth.W, fixedType.binaryPoint)))          
     private val distances = tabHash0.indices.map { ind1 => 
      val dist: FixedPoint = io.x.zip(tabHash0(ind1)).foldLeft(0.F(fixedType.binaryPoint)) { case (accum, (x, t)) => 
       accum + ((x-t) *(x-t)) 
      } 
      } 
     val topKClasses = distances.zipWithIndex.sortBy(_._1).take(k).map{case (dist, idx)=>dataY(idx)} 
     val label = topKClasses.groupBy(identity).mapValues(_.size).maxBy(_._2)._1 
io.out := label(0).toByte.toDouble.F(fixedType.getWidth.W, fixedType.binaryPoint) 
} 

これは、私は、ファイルからの値を使用して自分のコードを実行する方法である:私が作った

object HardwareNearestNeighboursDriver extends App { 

    def line2Data(line: String): (List[Double],String)= 
    val elts=line.split(",") 
    val y= elts.last 
    val x= elts.dropRight(1).map(_.toDouble).toList 
    (x,y) 
    } 

    val data = Source.fromFile("ionosphere.data.txt").getLines().map(x=>line2Data(x)).toList 
    val outputs =data.map(_._2).toSeq 
    val inputs =data.map(_._1).toArray 
println("The output size is" + outputs.size) 
val keySize = inputs.take(1).length 
    val dataX = inputs.map(_.toArray).take(300) 
    val dataY = outputs.take(300) 

    val fixedWidth = 64 
    val binaryPoint = 32 
    val k = 5 


    chisel3.Driver.execute(args,() => new HardwareNearestNeighbours(FixedPoint(fixedWidth.W, binaryPoint.BP), k, keySize, dataY, dataX)) 
} 

をデータファイルが同じフォルダ内であることを示しています。コードは実行されましたが、生成されたVerilogが心配です。

`ifdef RANDOMIZE_GARBAGE_ASSIGN 
    `define RANDOMIZE 
    `endif 
    `ifdef RANDOMIZE_INVALID_ASSIGN 
    `define RANDOMIZE 
    `endif 
    `ifdef RANDOMIZE_REG_INIT 
    `define RANDOMIZE 
    `endif 
    `ifdef RANDOMIZE_MEM_INIT 
    `define RANDOMIZE 
    `endif 

    module HardwareNearestNeighbours(
     input   clock, 
     input   reset, 
     input [63:0] io_x_0, 
     output [63:0] io_out 
    ); 
     assign io_out = 64'sh6700000000; 
    endmodule 

私は、生成されたVerilogの正しさをチェックする方法について助言したいと思います。私はハードウェア言語で全く新しいです。 ありがとう!あなたの応答を楽しみにしています。

+0

あなたの生成されたVerilogはあまり効果がありませんが、出力を一定の値に初期化します。私はあなたのコードが結果を計算し、それを生成したと思います。あなたは何を期待しましたか?テストに関しては、Verilogモジュールをシミュレートし、入力を提供し、出力を監視して正しく動作することを確認する必要があります。あなたのケースでチェックするものは何もありません。 – Serge

+0

ハードウェアを動作させる前に、ソフトウェア実装が機能することを示すスカラーテストまたはメインを作成する必要があります。たとえば、keySizeの計算は常に.take(1).lengthのため1を返します。ファイル内のデータが何を意味するかの説明は本当に役に立ちます –

+0

apply関数を使用してオブジェクトとしてpredictを宣言することで、何か具体的なものがありますか?これは、predictという名前の通常のメソッドを宣言する方法のように見えます。 –

答えて

1

重要な問題は、HardwareNearestNeighboursである:

val topKClasses = distances.zipWithIndex.sortBy(_._1).take(k).map{case (dist, idx)=>dataY(idx)} 

ここsortByは、ソートのソフトウェアの実装です。あなたはトップkの値を収集するために必要なハードウェアを作成するために独自に作成する必要があります。レジスタのセットに分類するのが最も簡単かもしれませんが、回路の設計目標によって最適な戦略が決まります。

関連する問題