2017-09-01 8 views
1

Ich habe ein Problem mit dem generierten Verilog von meinem Meißel-Code unten und ich denke, dass dies mit der Art und Weise in Zusammenhang stehen könnte, wie ich meinen Meißel-Code geschrieben habe. Fein unter der Scala-Version und den Meißel-Versionen meines Codes mit der generierten Verilog-Ausgabe.Meißel k Nächste Nachbarn Verilog-Ausgabe

Hier ist die Scala Version meines Code:

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        

     }                         
    }                          
} 

Hier ist der Meißel Version. Kann jemand in meinen Code schauen, um zu sehen, wo ich falsch gelaufen bin?

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) 
} 

Dies ist, wie ich meinen Code mit Werten aus einer Datei ausführen:

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)) 
} 

I zeigen die Datendatei im selben Ordner vorgenommen haben ist. Der Code lief, aber ich mache mir Sorgen mit dem erzeugten 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 

Ich hätte auch gerne einen Ratschlag, wie man die Richtigkeit meiner erstellten Verilog überprüfen kann. Ich bin völlig neu in Hardware-Sprachen. Danke! Ich freue mich auf Ihre Antworten.

+0

Ihr generierter Verilog tut nicht viel, initialisiert aber einen Ausgang auf einen konstanten Wert. Ich denke, Ihr Code hat nur das Ergebnis berechnet und generiert. Was hast du erwartet? Wie beim Testen müssen Sie das Verilog-Modul simulieren, Eingaben bereitstellen und Ausgaben überwachen, um sicherzustellen, dass es korrekt funktioniert. In Ihrem Fall gibt es jedoch nichts zu überprüfen. – Serge

+0

Bevor Sie versuchen, die Hardware zum Laufen zu bringen, sollten Sie einen Scala-Test oder einen Master schreiben, der zeigt, dass Ihre Software-Implementierung funktioniert. Ihre Berechnung der keySize zum Beispiel gibt immer eine zurück, weil .take (1) .length. Eine Beschreibung dessen, was die Daten in der Datei bedeuten, wäre sehr hilfreich. –

+0

Gibt es etwas Bestimmtes, das Sie erreichen wollten, indem Sie vorhergesagt als ein Objekt mit einer Anwendungsfunktion deklarieren? Es sieht wie eine ziemlich komplizierte Weise aus, eine gewöhnliche Methode zu benennen, die vorhergesagt wird. –

Antwort

1

Das Schlüsselproblem ist in HardwareNearestNeighbours:

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

Die sortBy hier ist eine Software-Implementierung von Art. Sie müssen Ihre eigenen schreiben, um die erforderliche Hardware zu erstellen, um die oberen k Werte zu sammeln. Es wäre wahrscheinlich am einfachsten, einen Satz von Registern zu sortieren, aber Ihre beste Strategie würde von Ihren Konstruktionszielen für die Schaltung abhängen.

Verwandte Themen