編 者 按
之前在玩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
+關注
關注
1630文章
21796瀏覽量
606012 -
邏輯電路
+關注
關注
13文章
494瀏覽量
42709 -
時鐘
+關注
關注
11文章
1746瀏覽量
131801 -
邏輯設計
+關注
關注
1文章
41瀏覽量
11609 -
Vivado
+關注
關注
19文章
815瀏覽量
66889
原文標題:一鍵獲取邏輯設計中的所有跨時鐘路徑
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論