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