编 者 按
之前在玩FPGA时,对于一个系统工程,当逻辑电路设计完成之后,一般会先拿给Vivado/Quartus先去跑一般综合,然后去获取所有的跨时钟路径,在ASIC里,基本也是拿EDA工具去分析获取。今儿个搞个小demo,看在SpinalHDL当设计做完后,如何一键提取整个工程里所有的跨时钟路径。
这个Demo会依赖spinal.lib.tools.DataAnalyzer,此次测试在1.9.3版本上进行。
获取跨时钟路径
得益于SpinalHDL对时钟域严格的划分,在SpinalHDL中,如果存在跨时钟域,那么必须显示的添加Tag进行标示,否则在生成电路时将会直接报错。以BufferCC为例:
class BufferCC[T <: Data](val dataType: T, init : => T, val bufferDepth: Option[Int], val randBoot : Boolean = false) extends Component {
def getInit() : T = init
val finalBufferDepth = BufferCC.defaultDepthOptioned(ClockDomain.current, bufferDepth)
assert(finalBufferDepth >= 1)
val io = newBundle {
val dataIn = in(cloneOf(dataType))
val dataOut = out(cloneOf(dataType))
}
val buffers= Vec(Reg(dataType, init),finalBufferDepth)
if(randBoot) buffers.foreach(_.randBoot())
buffers(0) := io.dataIn
buffers(0).addTag(crossClockDomain)
for(i <- 1until finalBufferDepth) {
buffers(i) := buffers(i - 1)
buffers(i).addTag(crossClockBuffer)
}
io.dataOut := buffers.last
}
因为是跨时钟域,所以buffers(0)必须添加Tag标签crossClockDomain,那么基于此,我们完全可以找出整个工程里的所有跨时钟路径的源节点,目的节点。
下面给出一个demo:
importspinal.core._
importspinal.lib._
importspinal.lib.tools.DataAnalyzer
importscala.collection.mutable.ArrayBuffer
object Test extendsApp {
def getCrossClockFanIn(signal: BaseType, clockDomain: ClockDomain): ArrayBuffer[BaseType] = {
val signalList = ArrayBuffer[BaseType]()
for(srcSignal <- DataAnalyzer.toAnalyzer(signal).getFanIn) {
if(srcSignal.isReg) {
if(srcSignal.clockDomain != clockDomain) {
signalList.append(srcSignal)
}
} else{
signalList ++= getCrossClockFanIn(srcSignal, clockDomain)
}
}
signalList
}
def reportCrossClockSignal(toplevel: Component) = {
toplevel.walkComponents { c=>
c.dslBody.walkDeclarations {
casesignal: BaseType=>{
if(signal.hasTag(crossClockDomain)) {
val fanInRegList = getCrossClockFanIn(signal, signal.clockDomain)
for(reg <- fanInRegList) {
println(s"src reg:${reg.getDisplayName()} hierarchy:${reg.component.getPath(".")} src clock:${reg.clockDomain.clock.getDisplayName()} dst reg:${signal.getDisplayName} hierarchy:${signal.component.getPath(".")} dst clock:${signal.clockDomain.clock.getDisplayName()}")
}
}
}
case_ =>
}
}
}
val report = SpinalSystemVerilog(newStreamFifoCC[UInt](UInt(8bits), 512, ClockDomain.external("clka"), ClockDomain.external("clkb")))
reportCrossClockSignal(report.toplevel)
val report1 = SpinalSystemVerilog(newStreamCCByToggle[Stream[UInt]](Stream(UInt(8bits)), ClockDomain.external("clka"), ClockDomain.external("clkb")))
reportCrossClockSignal(report1.toplevel)
}
在这个Demo中,采用了StreamFifoCC以及StreamCCByToggle来做演示。两个模块的跨时钟域路径分析结果如下:
StreamFifoCC
srcreg:popCC_ptrToPushhierarchy:toplevelsrcclock:clkb_clkdstreg:buffers_0hierarchy:toplevel.popToPushGray_bufferccdstclock:clka_clk
srcreg:pushCC_pushPtrGrayhierarchy:toplevelsrcclock:clka_clkdstreg:buffers_0hierarchy:toplevel.pushToPopGray_bufferccdstclock:clkb_clk
StreamCCByToggle
srcreg:pushArea_data_validhierarchy:toplevelsrcclock:clka_clkdstreg:popArea_stream_rData_validhierarchy:topleveldstclock:clkb_clk
srcreg:pushArea_data_readyhierarchy:toplevelsrcclock:clka_clkdstreg:popArea_stream_rData_readyhierarchy:topleveldstclock:clkb_clk
srcreg:pushArea_data_payloadhierarchy:toplevelsrcclock:clka_clkdstreg:popArea_stream_rData_payloadhierarchy:topleveldstclock:clkb_clk
srcreg:popArea_hithierarchy:toplevelsrcclock:clkb_clkdstreg:buffers_0hierarchy:toplevel.outHitSignal_bufferccdstclock:clka_clk
srcreg:pushArea_targethierarchy:toplevelsrcclock:clka_clkdstreg:buffers_0hierarchy:toplevel.pushArea_target_bufferccdstclock:clkb_clk
完全符合预期~
getCrossClockFanIn
该函数的作用用于针对指定信号其所有的扇入驱动中不在一个时钟域的寄存器。输入参数有两个:
-
signal:待搜索信号
-
clockDomain:signal信号对应的时钟域
这里面存在一个递归调用,通过调用DataAnalyzer中的getFanIn,获取signal信号的所有扇入,对于其扇入信号类型,存在以下三种情况:
-
扇入类型为寄存器,和signal不属于同一个时钟域,那么将信号添加到匹配列表中
-
扇入类型为寄存器,但和signal属于同一个时钟域,则不做任何处理
-
扇入类型为非寄存器,那么递归调用getCrossClockFanIn进一步搜索
reportCrossClockSignal
该函数的作用是对于传入的toplevel模块,会便利搜索其中所有带有crossClockDomain标签的信号,通过调用getCrossClockFanIn进一步得到其相应的跨时钟域路径。在得到跨时钟域路径后,这里仅做了信息打印,读者有需要可自行扩展,比如生成针对单bit信号的约束,对于多比特信号的约束等。
写在最后
这里仅能针对SpinalHDL代码中的电路进行分析。
-
FPGA
+关注
关注
1634文章
21830浏览量
607971 -
逻辑电路
+关注
关注
13文章
495浏览量
42824 -
时钟
+关注
关注
11文章
1756浏览量
132121 -
逻辑设计
+关注
关注
1文章
41浏览量
11655 -
Vivado
+关注
关注
19文章
819浏览量
67187
原文标题:一键获取逻辑设计中的所有跨时钟路径
文章出处:【微信号:Spinal FPGA,微信公众号:Spinal FPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论