編 者 按
Scala里面的隱式轉(zhuǎn)換的好處是靈活,壞處就是太靈活。
StageableKey都是哪兒來的
在pipeline的實現(xiàn)中,有五大要素:pipeline、Connection、Stage、StageableKey、Stageable。我們來看下面的代碼:
這里我們所想要實現(xiàn)的是一個四輸入按照樹形加法器的形式經(jīng)過兩級求和。這是我在看完了pipeline源代碼后寫下的第一個練習代碼。在看了SpinalHDL里面給的pipeline的例子后給我的第一印象就是太靈活了。從最簡單的做起,在進行斷點調(diào)試分析執(zhí)行流程時,當我將斷點打在pip.build時一個問題困擾了我大半個小時。調(diào)試信息顯示stage0中internal.stageableToData中包含兩個元素,而stage1中internal.stageableToData中確顯示有四個元素。這讓我第一印象就是簡直離了個大譜,stage1里我明明也就只調(diào)了兩次insert函數(shù)啊!
老實講,我的Scala水平也就搞軟件的業(yè)余水平,如果我是當初初學,那么我就不糾結(jié)了,這里還是老是分析下。
insert
老實回到insert函數(shù)來仔細扒拉扒拉:
加上括號五行代碼我看了十幾遍,看了幾遍也沒毛病啊,這里面定義一個Stageable變量s,并把that賦值給this(s),隨后將s返回。調(diào)用this(s)會通過調(diào)用apply函數(shù)創(chuàng)建一個StageableKey。再怎么看是不是也只應(yīng)該將一個StageableKey壓入stageableToData不是~
這就是Scala里面的隱式轉(zhuǎn)換的隱入真的是太靈活了。我在看的時候一直忘記了思考一個問題:在上面的代碼中第三行":="左邊是Data類型,而右邊是Stageable變量類型,在Scala這種強類型語言里,操作符左右兩側(cè)變量類型不同能進行操作么?換句話說,就是Data所定義的:=方法所支持的參數(shù)列表里應(yīng)該沒有Stageable參數(shù)類型。
那么,這里的幺蛾子那就只能是存在隱式轉(zhuǎn)換了。在類Stage中存在下面這些隱式轉(zhuǎn)換:
implicit def stageablePiped[T <: Data](stageable: Stageable[T])(implicit key : StageableOffset = StageableOffsetNone) = Stage.this(stageable, key.value) implicit def stageablePiped2[T <: Data](stageable: Stageable[T]) = new { def of(key : Any) = Stage.this.apply(stageable, key) // def := (value : T)(implicit key : StageableOffset = StageableOffsetNone) = Stage.this(stageable, key.value) := value } implicit def stageablePiped3[T <: Data](key: Tuple2[Stageable[T], Any]) = Stage.this(key._1, key._2) implicit def stageablePipedVec[T <: Data](stageable: Stageable[Vec[T]])(implicit key : StageableOffset = StageableOffsetNone) : Vec[T] = Stage.this(stageable, key.value) implicit def stageablePipedVec2[T <: Data](stageable: Stageable[Vec[T]]) = new { def of(key : Any) = Stage.this.apply(stageable, key) } implicit def stageablePipedVec3[T <: Data](key: Tuple2[Stageable[Vec[T]], Any]) = Stage.this(key._1, key._2)
這里顯然符合條件的就是stageablePiped這個隱式轉(zhuǎn)換了。它將我們傳入的that這個Stageable參數(shù)調(diào)用Stage.this方法給注冊進了stageableToData中去。這也就意味著我們在Stage1中調(diào)用一次insert將會插入兩個StageableKey。而在Stage0中之所以不存在這個問題是因為我們所傳入的“that”本身就是一個UInt類型變量,無需再進行隱式轉(zhuǎn)換,其所調(diào)用的是這個insert函數(shù):
?再回到我們這個代碼里面的第18行。兩次insert均返回的是Stageable類型變量,而我們這里又做了一次加法。在Stageable里面明顯是不存在加法這個方法的。你在IDEA里面如果對加法進行代碼跳轉(zhuǎn),你會發(fā)現(xiàn)其調(diào)用的是UInt的加法操作。那么無疑這里有存在隱式轉(zhuǎn)換了。即將加法左右兩側(cè)的類型均隱式轉(zhuǎn)換成UInt類型。這里還是會調(diào)用stageablePiped這個隱式轉(zhuǎn)換,只不過在Stage.this所對應(yīng)的apply方法里:
由于stageableToData中在調(diào)用insert時已經(jīng)將數(shù)據(jù)壓入,此時不會再生成新的StageableKey,將原有的直接返回即可。
因此,在Stage1中的stageableToData中,一共壓入了四個StageableKey。
理解了這些,對于stage1,我們可以換個寫法:
這時只會針對stage0.tmp和stage0.tmp1分別調(diào)用一次隱式轉(zhuǎn)換得到兩個UInt進行相加,故在stage1中的stageableToData中僅包含兩個元素。
寫在最后
SpinalHDL作者Dolu真的是一個大神,軟硬件都玩的真溜~
審核編輯:湯梓紅
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4361瀏覽量
63630 -
代碼
+關(guān)注
關(guān)注
30文章
4871瀏覽量
69906 -
變量
+關(guān)注
關(guān)注
0文章
614瀏覽量
28719 -
scala
+關(guān)注
關(guān)注
0文章
42瀏覽量
6570
原文標題:pipeline高端玩法(四)—Stage里的隱式轉(zhuǎn)換
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
得到警告373“隱式簽名到無符號轉(zhuǎn)換”
XC8怎么將float隱式轉(zhuǎn)換為整數(shù)
隱式有符號到無符號轉(zhuǎn)換
Pipeline ADCs Come of Age

基于顯式與隱式反饋信息的矩陣分解
軟件使用SMMUv3的stage1還是stage2地址轉(zhuǎn)換

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

pipeline高端玩法—優(yōu)先級介紹

評論