2017-09-01 132 views
1

我從下面的鑿子代碼中生成的Verilog有問題,我想這可能與我編寫我的鑿子代碼的方式有關。低於Scala版本和我的代碼的鑿子版本以及生成的Verilog輸出。chisel k最近鄰居verilog輸出

這裏是我的代碼的斯卡拉版本:

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

在您嘗試使硬件正常工作之前,您應該編寫一個scala測試或主文件來證明您的軟件實現能夠正常工作。例如,keySize的計算總是返回一個,因爲.take(1).length。關於文件中的數據意味着什麼的一些描述將非常有用 –

+0

有什麼具體的東西你希望通過將預測作爲具有apply函數的對象聲明來實現?它看起來像是一種相當複雜的方式來聲明一個名爲predict的普通方法。 –

回答

1

的關鍵問題是在HardwareNearestNeighbours

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

這裏的sortBy是軟件實現的那種。您需要編寫自己的代碼來創建必要的硬件,以收集頂部的值k。對寄存器進行排序可能最簡單,但最佳策略將取決於電路的設計目標。