2017-07-19 2 views
1

Le code suivant implémente un arbitre de priorité fixe N-bit.Chisel3: Fausse boucle combinatoire dans l'arbitre à priorité fixe

import chisel3._ 
import chisel3.util._ 

class fixedPriorityArbiter(val n_reqs:Int = 4) extends Module { 
    val NO_OF_REQS = n_reqs 
    val io = IO(new Bundle { 
     val req  = Input(UInt(NO_OF_REQS.W)) 
     val grant = Output(UInt(NO_OF_REQS.W)) 
    }) 
    val higherPriReq = Wire(UInt(NO_OF_REQS.W)) 

    higherPriReq := Cat((higherPriReq(NO_OF_REQS-2, 0) | io.req(NO_OF_REQS-2, 0)), UInt(0,1.W)) 
    io.grant := io.req & ~higherPriReq 
} 


object main_obj extends App { 
    val DUT =() => new fixedPriorityArbiter() 
    val margs = Array("--compiler", "verilog") 

    chisel3.Driver.execute(args= margs, dut= DUT) 
} 

Des boucles combinatoires inexistantes sont indiquées pour ce code. La source de ciseau reflète une implémentation Verilog du circuit ci-dessous qui ne signale aucune boucle combinatoire lorsqu'elle est synthétisée dans Synopsys Synplify. enter image description here

L'erreur de compilation suivante est rapporté par FIRRTL dans Eclipse IDE sur Windows sans aucune source Verilog générée par FIRRTL enter image description here

Répondre

2

FIRRTL ne prend pas en charge l'analyse sous-mot donc en utilisant un UInt ici, vous créez ce qui apparaît être une boucle combinatoire, même si elle ne l'est pas réellement. Pour contourner cela, vous pouvez utiliser des types d'agrégats comme Vecs pour rendre explicite à Firrtl que vous travaillez sur les bits individuels. Voici une implémentation équivalente utilisant un Vec:

class FixedPriorityArbiter(val n_reqs: Int = 4) extends Module { 
    val NO_OF_REQS = n_reqs 
    val io = IO(new Bundle { 
     val req  = Input(UInt(NO_OF_REQS.W)) 
     val grant = Output(UInt(NO_OF_REQS.W)) 
    }) 
    val higherPriReq = Wire(Vec(NO_OF_REQS, Bool())) 

    // Vec implements scala.collection.Seq so you can use such operations as slice and map 
    val upperOr = higherPriReq.slice(0, NO_OF_REQS-1).zip(io.req(NO_OF_REQS-2, 0).toBools) 
                .map { case (l, r) => l | r } 
    higherPriReq := false.B +: upperOr 
    io.grant := io.req & ~higherPriReq.asUInt 
} 
+0

La solution de jkoenig produit des Verilog fonctionnellement corrects. – plenn08

+0

Il est dommage que Chisel ne puisse pas fournir une API de haut niveau pour permettre des opérations au niveau du bit sur des champs binaires distincts du même vecteur sans que le compilateur ne l'indique incorrectement comme une boucle combinatoire, mais si c'est le cas, nous devoir en rester conscient. L'approche adoptée par jkoenig est certainement une solution de contournement valable pour le moment. Cet exemple serait peut-être utile dans la documentation de Chisel? – plenn08