2017-07-19 47 views
1

以下代碼實現了一個n位固定優先級仲裁器。Chisel3:固定優先級仲裁器中的虛擬組合環

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

此代碼報告不存在組合循環。鑿子源鏡像下面的電路的Verilog實現,當在Synopsys Synplify中合成時,該電路不報告任何組合循環。 enter image description here

以下編譯錯誤是由FIRRTL在Eclipse IDE報道在Windows不受FIRRTL產生任何Verilog源 enter image description here

回答

2

FIRRTL不使用UINT這裏,你所創造的東西似乎支持子字分析,以便成爲一個組合循環,即使它實際上不是。爲了解決這個問題,你可以使用像Vecs這樣的聚集類型來明確地表明Firrtl正在處理單個位。下面是使用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

jkoenig的解決方案產生功能正確的Verilog。 – plenn08

+0

可惜的是,鑿子不能提供一些高級的API來允許在相同向量的不同位域上進行按位操作,而不需要編譯器將其錯誤地標記爲組合循環,但如果是這種情況,那麼我們只需要必須保持意識。 jkoenig採取的方法當然是一種有效的解決方法。也許這個例子在鑿子的文檔中是有價值的? – plenn08