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