今天來(lái)看下SpinalHDL Pipeline組件里的resulting及overloaded的使用
》resulting
在Stage中的數(shù)據(jù)結(jié)構(gòu)中,有四種類(lèi)型:
val stageableToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableOverloadedToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableResultingToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableTerminal = mutable.LinkedHashSet[StageableKey]()
關(guān)于stageableToData,在之前的文章中已有介紹,今天來(lái)看下stageableOverloadedToData以及stageableResultingToData的作用。在提供的API中,相關(guān)的注冊(cè)函數(shù)有:
stageableOverloadedToData注冊(cè):
defoverloaded(key : StageableKey):Data = {
internals.stageableOverloadedToData.getOrElseUpdate(key, ContextSwapper.outsideCondScope{
key.stageable()//.setCompositeName(this, s"${key}_overloaded")
})
}
stageableResultingToData注冊(cè):
def resulting(key : StageableKey) : Data = {
internals.stageableResultingToData.getOrElseUpdate(key, ContextSwapper.outsideCondScope{
key.stageable()//.setCompositeName(this, s"${key}_overloaded")
})
}
def resulting[T <: Data](key : Stageable[T]) : T = {
????resulting(StageableKey(key.asInstanceOf[Stageable[Data]], null)).asInstanceOf[T]
??}
def resulting[T <: Data](key : Stageable[T], key2 : Any) : T = {
????resulting(StageableKey(key.asInstanceOf[Stageable[Data]], key2)).asInstanceOf[T]
}
字如其名,resulting可以理解為獲取Stageable的最終結(jié)果,而overload則是對(duì)數(shù)據(jù)的重載。不妨先來(lái)看看在pipeline中這兩種類(lèi)型所起的作用:
在pipeline的build函數(shù)里,對(duì)于stageableResultingToData,其首先的處理方式代碼如下:
for(s <- stagesSet){
???for(key <- s.internals.stageableResultingToData.keys){
?????s.apply(key)
???}
}
這里對(duì)于每個(gè)stage中stageableResultingToData里所注冊(cè)的每種類(lèi)型StageableKey,其都會(huì)調(diào)用Stage的apply函數(shù)將其注冊(cè)到StageableToData中,也就意味著如果前級(jí)也有該對(duì)應(yīng)的StageableKey,那么在連接階段兩者是可以建立連接關(guān)系的。
隨后,在internal conntection階段,對(duì)于stageableResultingToData中的變量,采用的賦值邏輯為:
for((key, value) <-?s.internals.stageableResultingToData){
???value := s.internals.outputOf(key)
}
而outputOf的賦值邏輯為:
def outputOf(key : StageableKey) = stageableOverloadedToData.get(key) match {
caseSome(x) => x
caseNone => stageableToData(key)
}
可以看出,這里的處理方式為,如果該變量在stageableOverloadedToData中存在,那么會(huì)將stageableOverloadedToData中的值賦值驅(qū)動(dòng)stageableResultingToData中對(duì)應(yīng)的變量,否則將會(huì)從stageableToData中尋找對(duì)應(yīng)的變量進(jìn)行驅(qū)動(dòng)(上一步已經(jīng)將對(duì)應(yīng)的StageableKey注冊(cè)進(jìn)stageableToData中)。
》Show Me The Code
分析完了源代碼,上一個(gè)簡(jiǎn)單的example:
caseclassTest3() extendsComponent{
val io=newBundle{
val data_in=slave(Flow(Vec(UInt(8bits),4)))
val data_out=master(Flow(UInt(8bits)))
}
noIoPrefix()
val A,B=Stageable(UInt(8bits))
val pip=newPipeline{
val stage0=newStage{
this.internals.input.valid:=io.data_in.valid
A:=io.data_in.payload(0)+io.data_in.payload(1)
B:=io.data_in.payload(2)+io.data_in.payload(3)
}
val stage1=newStage(Connection.M2S()){
io.data_out.payload:=resulting(A)+resulting(B)
io.data_out.valid:=this.internals.output.valid
}
}
pip.build()
}
在這個(gè)例子里,在stage1中僅用到了resulting語(yǔ)句。按前面所述,stage1中最終stageableResultingToData中會(huì)包含兩個(gè)變量,build階段也會(huì)向其stageableToData階段注冊(cè)兩個(gè)變量A、B:

在這里,由于stage0中也包含A、B,故這里最終的驅(qū)動(dòng)關(guān)系為:

再來(lái)看一個(gè)resulting和overlaoded共用的代碼:
caseclass Test4() extends Component{
val io=newBundle{
val data_in=slave(Flow(Vec(UInt(8bits),4)))
val data_out=master(Flow(UInt(8bits)))
}
noIoPrefix()
val A,B=Stageable(UInt(8bits))
val pip=newPipeline{
val stage0=newStage{
this.internals.input.valid:=io.data_in.valid
A:=io.data_in.payload(0)+io.data_in.payload(1)
B:=io.data_in.payload(2)+io.data_in.payload(3)
}
val stage1=newStage(Connection.M2S()){
io.data_out.payload:=resulting(A)+B
io.data_out.valid:=this.internals.output.valid
overloaded(A):=A+1
}
}
pip.build()
}
這里在stage1中對(duì)A調(diào)用了overloaded重載,結(jié)合上面的賦值順序,最終的驅(qū)動(dòng)關(guān)系為:

看到這里,可能會(huì)有一個(gè)疑問(wèn):為什么不能直接寫(xiě)成A:=A+1的形式呢?主要在于A本身處于StageableToData,在進(jìn)行Stage之間的連接時(shí)已經(jīng)對(duì)齊進(jìn)行賦值驅(qū)動(dòng),這里如果直接寫(xiě)成A:=A+1相當(dāng)于對(duì)電路進(jìn)行重復(fù)驅(qū)動(dòng),從而導(dǎo)致報(bào)錯(cuò)。
》總結(jié)
resulting&overloaded主要用于在某個(gè)Stage階段對(duì)電路在結(jié)合上一Stage基礎(chǔ)上需做一些額外判斷對(duì)該階段的相應(yīng)電路做新的賦值驅(qū)動(dòng)時(shí)進(jìn)行處理。如在NaxRsicV中Cache里的一些電路處理:
overloaded(BANK_BUSY)(bankId) := BANK_BUSY(bankId) || bank.write.valid && REDO_ON_DATA_HAZARD
在流水線(xiàn)的某一階段在保持Stageable語(yǔ)義而不必新增Stageable情況下通過(guò)overlaoded、resulting來(lái)進(jìn)行Stage內(nèi)的電路對(duì)象驅(qū)動(dòng)。
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
20154瀏覽量
247506 -
驅(qū)動(dòng)器
+關(guān)注
關(guān)注
54文章
9026瀏覽量
153475 -
Pipeline
+關(guān)注
關(guān)注
0文章
29瀏覽量
9915 -
HDL語(yǔ)言
+關(guān)注
關(guān)注
0文章
48瀏覽量
9315 -
cache技術(shù)
+關(guān)注
關(guān)注
0文章
41瀏覽量
1329
原文標(biāo)題:pipeline高端玩法(六)—resulting&overloaded
文章出處:【微信號(hào):Spinal FPGA,微信公眾號(hào):Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
SpinalHDL里pipeline的設(shè)計(jì)思路
在SpinalHDL里switch方法有何用處呢
在SpinalHDL里實(shí)現(xiàn)優(yōu)雅的添加待跟蹤波形信號(hào)
談?wù)?b class='flag-5'>SpinalHDL中StreamCCByToggle組件設(shè)計(jì)不足的地方
在SpinalHDL中關(guān)于casez的使用
分享一個(gè)在SpinalHDL里apply的有趣用法
SpinalHDL是如何讓仿真跑起來(lái)的
如何在SpinalHDL里啟動(dòng)一個(gè)仿真
SpinalHDL里時(shí)鐘域中的定制與命名
SpinalHDL里用于跨時(shí)鐘域處理的一些手段方法
SpinalHDL運(yùn)行VCS+Vivado相關(guān)仿真
SpinalHDL里如何實(shí)現(xiàn)Sobel邊緣檢測(cè)
SpinalHDL里pipeline的設(shè)計(jì)思路

怎樣使用SpinalHDL Pipeline組件里的resulting及overloaded?
評(píng)論