Stream、Flow是在電路描述里經(jīng)常用到的對象。較早時間有小伙伴問關(guān)于Stream里Fragment嵌套的問題,當(dāng)時沒有去深入的研究,最近重新review下這個問題,特來做個總結(jié)。
》開篇立問
先來看看下面的這個場景:
我們定義如下接口:
這里定義了一個Stream接口,如果我們想引用這里面的data,那么下面兩種方法是等價的:
b.data
b.payload.data
估計大多數(shù)人不深究的話基本上就采用第一種寫法了,簡單快捷(我也是)。
》深入一步
顯而易見,這里b的定義是一個Stream接口。按照Stream接口的定義,其所包含的信號只有三個:
從直觀上來看,那么采用b.data這種形式顯然是沒有直接的方法或調(diào)用關(guān)系的。
那么剩下的一種可能就是隱式轉(zhuǎn)換了~
Stream類在定義時其繼承關(guān)系如下:
這里的隱式轉(zhuǎn)換存在于trait DataCarrier中:
這里為DataCarrier定義了兩個隱式轉(zhuǎn)換函數(shù)toImplicit和toImplicit2。根據(jù)DataCarrier的數(shù)據(jù)類型,分別返回不同的對象:
如果數(shù)據(jù)類型是普通類型,則直接返回dataCarrier.payload
如果數(shù)據(jù)類型是Fragment類型,則會返回dataCarrier.fragment(同樣,會調(diào)用到toImplicit函數(shù))。
如果你在toImplicit函數(shù)上打斷點,執(zhí)行上面的接口定義相關(guān)的代碼,你就會發(fā)現(xiàn)會在toImplicit函數(shù)上暫停。也就意味著當(dāng)我們調(diào)用b.data時會調(diào)用隱式轉(zhuǎn)換函數(shù)toImplicit返回b.payload后再執(zhí)行b.payload.data~
》亂花漸欲迷人眼
理解了上面的代碼,接下來的場景可能讓你眼花繚亂了。
先來看下面的這段代碼:
上面這段代碼是不是覺得fire0和fire1是表達相同的功能?然而,生成的RTL代碼會讓你懷疑自己:
再來看看一個Fragment嵌套的場景:
一眼看去是不是覺得fire0和fire1的作用是一樣的?
然而,生成的RTL代碼卻是這樣的:
給你一分鐘,你先品著。等品完之后再來看一個三層Fragment嵌套的代碼:
對應(yīng)的RTL代碼:
看看對應(yīng)的RTL代碼是不是和你想的又不一樣了?
我們調(diào)用函數(shù)實現(xiàn)和我們自己實現(xiàn)大相徑庭!
先暈一會兒~
》撥云見霧
是否又到了懷疑TM這SpinalHDL有Bug吧……
我也思索了兩三天~
回歸正題。接下來的內(nèi)容好好品。這一切的一切均還是在于隱式轉(zhuǎn)換。
審核編輯:劉清
-
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59901 -
HDL語言
+關(guān)注
關(guān)注
0文章
47瀏覽量
8942
原文標(biāo)題:Stream里的隱式轉(zhuǎn)換
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論