最近做些RTL代碼連線正確性檢查的一些事情,在對于Verilog代碼進行連接性檢查,只能依賴仿真的形式,過程深感不便。且在一個大型工程里,比如檢測一個fifo的overflow是否都連接到了debug接口上通過仿真就是一個很耗時的事情。作為SpinalHDL的堅定支持者,這種類型的工作交給代碼自己做,在SpinalHDL里so easy。
》連接性檢查所謂的連接性檢查,無非就是A、B兩個信號,判斷下兩者之間有沒有驅動關系。比如說我們認為A應該驅動B,在仿真里Force A為一個值,然后delay一段時間看B是否有變更為對應的值。如果針對某一類連線規則,在Verilog里通過這種仿真的形式一根根進行檢查是一個很耗時的事情。然而在SpinalHDL里,采用LatencyAnalysis,搞什么仿真,輕輕松幾行代碼定義下規則就可以搞定了。如上面的判斷A是否有驅動B,僅需通過下面的一行代碼即可:
LatencyAnalysis(A,B)
其會自動分析A到B之間的路徑并返回其寄存器級數。即使跨時鐘域也能輕松搞定。
》Example通過在代碼里制定連接性檢查規則,根本不需要仿真,生成RTL代碼的時候就可以直接順便把這件事給做了。以下面的例子為例:
importspinal.core._
importspinal.lib._
object connectCheck{
def fifoPortCheck(componecnt:Component,portBoolean={
for(elem <- componecnt.children) {
??????elem match {
????????casefifo: StreamFifo[BaseType]=> {
println(s"Start Check ${componecnt.getName()} ${fifo.getName()} ${fifo.io.pop.valid.getName} to ${port.getName()} connection")
LatencyAnalysis(fifo.io.pop.valid,port)>=0
}
case_=>true
}
fifoPortCheck(elem,port)
}
true
}
}
caseclasstest1() extendsComponent{
val io=newBundle{
val data0=out Bool()
}
noIoPrefix()
val fifoInst=Array.fill(10)(StreamFifo(UInt(8bits),16))
fifoInst.foreach(fifo=>{
fifo.io.push.valid.clear()
fifo.io.push.payload.clearAll()
fifo.io.pop.ready.clear()
})
val test2Inst=test2()
io.data0:=fifoInst.map(_.io.pop.valid).reduce(_|_)|test2Inst.io.data0
connectCheck.fifoPortCheck(this,io.data0)
}
caseclasstest2() extendsComponent{
val io=newBundle{
val data0=out Bool()
}
noIoPrefix()
val fifoInst=Array.fill(10)(StreamFifo(UInt(8bits),16))
fifoInst.foreach(fifo=>{
fifo.io.push.valid.clear()
fifo.io.push.payload.clearAll()
fifo.io.pop.ready.clear()
})
io.data0:=fifoInst.map(_.io.pop.valid).reduce(_|_)
}
這里test2里面定義了10個StreamFifo,所有fifo的pop.valid通過或的形式連接到io.data0上。然后在test1里例化了test2和10個StreamFifo,將10個StreamFifo的pop.valid和test2的data0通過或的形式驅動io.data0。
假定我們在設計里定義如下規則:
-
test1下面的所有模塊的Stream Fifo的pop.valid都需要連接到test1的輸出端口io.data0上。
這里我們定義了一個fifoPortCheck函數用于做這件事,它會遍歷指定component下面的所有StreamFifo,通過LatencyAnalysis判斷其pop.valid是否與指定port之間是否存在連接關系。
如此,在生成代碼時便會有下面的檢查信息顯示:
這不比仿真來的快的多么,也無需發現錯誤自己挨個去找各模塊的負責人,只需統一制定好規則,每個人自己就能檢查,喝口水的功夫~。
現在我們把test1里面的test2Inst的data0拿掉不讓他驅動test1的io.data0:
caseclasstest1() extendsComponent{
val io=newBundle{
val data0=out Bool()
}
noIoPrefix()
val fifoInst=Array.fill(10)(StreamFifo(UInt(8bits),16))
fifoInst.foreach(fifo=>{
fifo.io.push.valid.clear()
fifo.io.push.payload.clearAll()
fifo.io.pop.ready.clear()
})
val test2Inst=test2()
io.data0:=fifoInst.map(_.io.pop.valid).reduce(_|_)
connectCheck.fifoPortCheck(this,io.data0)
}
生成RTL代碼時就會報錯:
告知test2Inst中的StreamFifo并沒有驅動test1中的io.data0,規則不過,根本不讓你生成Verilog代碼,仿真靠邊站~
效率就是這么提升的~
-
寄存器
+關注
關注
31文章
5363瀏覽量
121172 -
驅動
+關注
關注
12文章
1851瀏覽量
85645 -
代碼
+關注
關注
30文章
4827瀏覽量
69054
原文標題:連線對不對,仿真靠邊站,讓代碼自己做
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論