最近做些RTL代碼連線正確性檢查的一些事情,在對于Verilog代碼進(jìn)行連接性檢查,只能依賴仿真的形式,過程深感不便。且在一個大型工程里,比如檢測一個fifo的overflow是否都連接到了debug接口上通過仿真就是一個很耗時的事情。作為SpinalHDL的堅定支持者,這種類型的工作交給代碼自己做,在SpinalHDL里so easy。
》連接性檢查所謂的連接性檢查,無非就是A、B兩個信號,判斷下兩者之間有沒有驅(qū)動關(guān)系。比如說我們認(rèn)為A應(yīng)該驅(qū)動B,在仿真里Force A為一個值,然后delay一段時間看B是否有變更為對應(yīng)的值。如果針對某一類連線規(guī)則,在Verilog里通過這種仿真的形式一根根進(jìn)行檢查是一個很耗時的事情。然而在SpinalHDL里,采用LatencyAnalysis,搞什么仿真,輕輕松幾行代碼定義下規(guī)則就可以搞定了。如上面的判斷A是否有驅(qū)動B,僅需通過下面的一行代碼即可:
LatencyAnalysis(A,B)
其會自動分析A到B之間的路徑并返回其寄存器級數(shù)。即使跨時鐘域也能輕松搞定。
》Example通過在代碼里制定連接性檢查規(guī)則,根本不需要仿真,生成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通過或的形式驅(qū)動io.data0。
假定我們在設(shè)計里定義如下規(guī)則:
-
test1下面的所有模塊的Stream Fifo的pop.valid都需要連接到test1的輸出端口io.data0上。
這里我們定義了一個fifoPortCheck函數(shù)用于做這件事,它會遍歷指定component下面的所有StreamFifo,通過LatencyAnalysis判斷其pop.valid是否與指定port之間是否存在連接關(guān)系。
如此,在生成代碼時便會有下面的檢查信息顯示:
這不比仿真來的快的多么,也無需發(fā)現(xiàn)錯誤自己挨個去找各模塊的負(fù)責(zé)人,只需統(tǒng)一制定好規(guī)則,每個人自己就能檢查,喝口水的功夫~。
現(xiàn)在我們把test1里面的test2Inst的data0拿掉不讓他驅(qū)動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并沒有驅(qū)動test1中的io.data0,規(guī)則不過,根本不讓你生成Verilog代碼,仿真靠邊站~
效率就是這么提升的~
-
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120375 -
驅(qū)動
+關(guān)注
關(guān)注
12文章
1840瀏覽量
85293 -
代碼
+關(guān)注
關(guān)注
30文章
4788瀏覽量
68616
原文標(biāo)題:連線對不對,仿真靠邊站,讓代碼自己做
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論