最近做些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文章
5328浏览量
120116 -
驱动
+关注
关注
12文章
1829浏览量
85213 -
代码
+关注
关注
30文章
4762浏览量
68408
原文标题:连线对不对,仿真靠边站,让代码自己做
文章出处:【微信号:Spinal FPGA,微信公众号:Spinal FPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论