之前有系列文章介紹了SpinalHDL中Pipeline的使用,最近在一個功能模塊中真實的使用了這個lib。雖然在使用上基于Flow/Stream的抽象已基本滿足大多數(shù)使用場景,但在FPGA端有時為了優(yōu)化時序往往不得不做一些邏輯打散,此時發(fā)現(xiàn)Pipeline中的標(biāo)準(zhǔn)化組件就有點難以滿足需求了。
》舉個例子
考慮下面的一個使用pipeline簡單的邏輯代碼:
這是一個很簡單的邏輯,port_in打兩拍輸出至port_out。邏輯里有這樣一個動作需求:
當(dāng)port_out.valid為高且port_out.data1為true時,checked為真
這里checked輸出為一個組合邏輯,如果外部在使用時還需要其他許多類似的條件那么就有可能會對時序收斂帶來困難了(這里僅用來舉個例子闡述這種類似的需求)。
那么也許想當(dāng)然的將checked的判斷條件聲明一個Stageable變量在stage1中完成判斷,stage2中直接使用,就像這么來做:
如此,我們將組合邏輯前移,checked輸出為時序邏輯。看似完美是吧~
然而,如果你在VCS仿真器里仿真你會發(fā)現(xiàn),checked可能剛一上電就是高電平導(dǎo)致后續(xù)邏輯異常。其原因就是cond_matched沒有賦初值。
在pipeline的架構(gòu)里,在Connection中實現(xiàn)了不同Stage之間的連接,其中也包含了時序協(xié)議的實現(xiàn)。以這里我們調(diào)用的M2S為例:
其將valid聲明為Reg并賦給初始值False,然而對于payload僅聲明為寄存器并未賦初值。
由于有valid信號指示,paylaod不賦初值無可厚非,奔著控制路徑添加復(fù)位,數(shù)據(jù)路徑不添加復(fù)位的原則,這里并沒有問題。然而我們在針對一些時序優(yōu)化的場景需要將部分paylaod賦初值,這里就不太符合我們的需求了。
》M2SExt
既然滿足不了需求,那就擴(kuò)展。這里的實現(xiàn)可能略顯丑陋,但能解決問題。Stageable類型在Pipeline中例化為對象時會以我們聲明的Stageable變量名作為結(jié)尾,我們只需在M2S的on實現(xiàn)基礎(chǔ)上添加匹配規(guī)則即可。由于M2S是Class不可繼承,這里重新定義了一個M2SExt來實現(xiàn):
caseclassM2SExt(collapse: Boolean= true, holdPayload: Boolean= false, flushPreserveInput: Boolean= false) extendsConnectionLogic { val initMap = LinkedHashMap[String, Data]() def addInitValue[T <: Data](target: Stageable[T], initValue: T) = { ????initMap.update(target.getName(), initValue) ??} ??def on(m: ConnectionPoint, ?????????s: ConnectionPoint, ?????????flush: Bool, flushNext: Bool, flushNextHit: Bool, ?????????throwHead: Bool, throwHeadHit: Bool) = new?Area { ????s.valid.setAsReg() init (False) ????s.payload.foreach(_.setAsReg()) ????m.ready match { ??????case?null?=> s.valid := m.valid (s.payload, m.payload).zipped.foreach(_ := _) caser=>{ if(flush != null&& flushPreserveInput) s.valid clearWhen (flush) if(throwHead != null) s.valid clearWhen (throwHead) when(r) { s.valid := m.valid } when(if(holdPayload) m.valid && r elser) { (s.payload, m.payload).zipped.foreach(_ := _) } } } if(flush != null&& !flushPreserveInput) s.valid clearWhen (flush) if(flushNext != null&& !flushPreserveInput) s.valid clearWhen (flushNext && s.ready) if(flushNextHit != null) flushNextHit := True // assert(!(flushNext != null && flushPreserveInput)) if(m.ready != null) { m.ready := s.ready if(collapse) m.ready setWhen (!s.valid) } Component.current.addPrePopTask(()=>{ s.payload.foreach(paylaod=>{ initMap.foreach { case(signalEndName, initValue) =>{ if(paylaod.getName().endsWith(signalEndName)) { paylaod.init(initValue) } } } }) }) }
這里為M2S定義了一個addInitValue方法,從而能使得我們能夠為某個ConnectionLogic中制定的Stageable映射電路對象添加復(fù)位值。在on實現(xiàn)函數(shù)最后通過添加PrePopTask來遍歷搜索當(dāng)前ConnectionLogic中對應(yīng)的payload并賦初始值。
最終我們可以在實現(xiàn)里如此:
stage1To2Connection通過調(diào)用addInitValue來為cond_matched添加復(fù)位值,以此滿足需求:
pipe_stage2_cond_matched添加復(fù)位控制。
審核編輯:劉清
-
FPGA
+關(guān)注
關(guān)注
1643文章
21963瀏覽量
614082 -
寄存器
+關(guān)注
關(guān)注
31文章
5421瀏覽量
123333 -
仿真器
+關(guān)注
關(guān)注
14文章
1033瀏覽量
84951 -
VCS
+關(guān)注
關(guān)注
0文章
80瀏覽量
9845 -
Pipeline
+關(guān)注
關(guān)注
0文章
29瀏覽量
9617
原文標(biāo)題:審視下Pipeline中的復(fù)位定制
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
在SpinalHDL中如何快速地實現(xiàn)總線連接
關(guān)于SpinalHDL中的驗證覆蓋率收集簡單說明
談?wù)?b class='flag-5'>SpinalHDL中StreamCCByToggle組件設(shè)計不足的地方
聊聊SpinalHDL中的FIFO
在SpinalHDL中關(guān)于casez的使用
SpinalHDL中仿真信號的驅(qū)動實現(xiàn)
定制板中的STMF446RE MCU復(fù)位問題求解
SpinalHDL里時鐘域中的定制與命名
SpinalHDL中的SpiMasterCtrl模塊做使用說明詳解
在SpinalHDL中的對應(yīng)關(guān)系及聲明形式
SpinalHDL中Bundle數(shù)據(jù)類型的轉(zhuǎn)換
SpinalHDL BlackBox時鐘與復(fù)位

SpinalHDL里pipeline的設(shè)計思路

評論