0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一個(gè)簡(jiǎn)單的pipeline是如何構(gòu)建起來(lái)的?

Spinal FPGA ? 來(lái)源:Spinal FPGA ? 2023-08-12 11:18 ? 次閱讀

續(xù)接上文,這一次我們來(lái)詳細(xì)了解下一個(gè)簡(jiǎn)單的pipeline是如何構(gòu)建起來(lái)的

》最簡(jiǎn)單的流水線

書接上文,一個(gè)最簡(jiǎn)單的流水線例子,這里對(duì)data_in打兩拍做輸出:

b5c6ab92-38b3-11ee-9e74-dac502259ad0.png

我們逐行分析pipeline里每一行代碼都干了什么。

》Stage分析

在第八行我們聲明了一個(gè)Stageable變量,如前文所述,Stageable變量并不會(huì)立即產(chǎn)生電路對(duì)象。

代碼第9行,我們創(chuàng)建一個(gè)Stage,Stage中的下面的代碼會(huì)通過(guò)調(diào)用Pipeline中的addStage函數(shù)向Pipeline中的StageSet添加當(dāng)前Stage:

if(_pip != null) {
_pip.addStage(this)
}

在stage0中,第11行用io.data_in.valid驅(qū)動(dòng)stage0中的internals.input.valid。而在第12行,從左向右看,this(payload)函數(shù)會(huì)調(diào)用Stage的apply函數(shù):

def apply[T <: Data](key : Stageable[T]) : T = {
????apply(StageableKey(key.asInstanceOf[Stageable[Data]], null)).asInstanceOf[T]
}

其進(jìn)一步調(diào)用:

defapply(key : StageableKey):Data = {
internals.stageableToData.getOrElseUpdate(key, ContextSwapper.outsideCondScope{
key.stageable()//.setCompositeName(this, s"${key}")
})
}

可以看到,這里的主要作用是一StageableKey作為Key查詢internals.stageableToData中是否包含該key,如果有則返回其value,否則創(chuàng)建該key-value,并將value返回。

最終這里會(huì)返回一個(gè)UInt(8 bits)電路對(duì)象。并將io.data_in.payload賦值給該電路對(duì)象。此時(shí),stage0中的internals.stageableToData中包含一個(gè)元素。

在第14行,我們創(chuàng)建了stage1,其例化時(shí)傳入了Connection,其會(huì)調(diào)用:

 if(_pip != null) {
_pip.addStage(this)
}

def chainConnect(connection: ConnectionLogic): Unit ={
_pip.connect(_pip.stagesSet.takeWhile(_ != this).last, this)(connection)
}

def this(connection: ConnectionLogic)(implicit_pip: Pipeline) {
this()
chainConnect(connection)
}

這里的的調(diào)用關(guān)系是:

當(dāng)前Pipeline的StageSet添加當(dāng)前Stage元素

通過(guò)調(diào)用pipeline的connect函數(shù)和StageSet中的最后一個(gè)元素建立連接關(guān)系:

defconnect(m : Stage, s : Stage)(logics : ConnectionLogic*) = {
val c = new ConnectionModel
connections += c
c.m = m
c.s = s
c.logics ++= logics
c
}

在connection里,創(chuàng)建了一個(gè)連接關(guān)系ConnectionModel,用于連接stage0中的output接口和stage1的input接口,采用M2S()方式進(jìn)行連接。

同樣,15行同樣stage2的創(chuàng)建亦如此。

代碼第16行則是用stage2的output.valid驅(qū)動(dòng)data_out的valid輸出。而代碼第17行通過(guò)同樣的方式創(chuàng)建了一個(gè)UInt(8 bits)電路對(duì)象,用來(lái)驅(qū)動(dòng)data_out.payload。此時(shí)stage2中的internals.stageableToData中包含一個(gè)元素。

最后調(diào)用pipeline的build函數(shù)進(jìn)行流水線的搭建。

》build分析

我們按片段來(lái)分析build中的代碼:

b6048a66-38b3-11ee-9e74-dac502259ad0.png

首先,上面第一行代碼將connection中的stage添加到stageSet。在執(zhí)行該行之前,stageSet中包含了stage0、stage1、stage2三個(gè)元素,而connection按照描述進(jìn)行map后得到兩個(gè)元素:(stage0,stage1),(stage1,stage2)。由于stageSet為L(zhǎng)inkedHashSet,故執(zhí)行完后依然是(stage0,stage1,stage2)。

第二行代碼則是獲取帶有slave驅(qū)動(dòng)的stage,這里即stage0(驅(qū)動(dòng)stage1)、stage1(驅(qū)動(dòng)stage2)。

第三行則是獲取沒(méi)有slave驅(qū)動(dòng)的stage,這里只有stage2。

第7~8行則是分別建立每個(gè)stage都是由誰(shuí)驅(qū)動(dòng)的映射存儲(chǔ)至stageMaster、而stage input的驅(qū)動(dòng)邏輯則存儲(chǔ)至stageDriver。同時(shí)這里也限制了每個(gè)stage,最多只能由一個(gè)驅(qū)動(dòng)邏輯。處理完后,stageMaster、stageDriver中存儲(chǔ)的元素分別為:

stageMaster:
stage0->ArrayBuffer()
stage1->ArrayBuffer(stage0)
stage2->ArrayBuffer(stage2)
stageDriver:
stage1->Connection(m=stage0,s=stage1,logic=M2S)
stage2->Connection(m=stage1,s=stage2,logic=M2S)

代碼13~16行由于我們并沒(méi)有使用到stageableResultingToData,這里可以暫時(shí)忽略,等后續(xù)章節(jié)再進(jìn)行討論。

val clFlush = mutable.LinkedHashMap[ConnectionLogic, Bool]()
val clFlushNext = mutable.LinkedHashMap[ConnectionLogic, Bool]()
val clFlushNextHit = mutable.LinkedHashMap[ConnectionLogic, Bool]()
val clThrowOne = mutable.LinkedHashMap[ConnectionLogic, Bool]()
val clThrowOneHit = mutable.LinkedHashMap[ConnectionLogic, Bool]()

這里聲明的變量我們這里都是用不上,可以暫時(shí)先不進(jìn)行關(guān)注。

def propagateData(key : StageableKey, stage : Stage): Boolean ={
if(stage.internals.stageableTerminal.contains(key)) returnfalse
stage.stageableToData.get(key) match {
caseNone => {
val hits = ArrayBuffer[Stage]()
for(m <- stageMasters(stage)){
????????if(propagateData(key, m)){
??????????stage.apply(key) //Force creation
??????????hits += m
????????}
??????}
??????hits.size match {
????????case?0?=> false
case1=> true
case2=> PendingError(s"$key at $stage has multiple drivers : ${hits.mkString(",")}"); false
}
}
caseSome(x) => true
}
}

for(stage <- stagesSet){
??for(key <- stage.stageableToData.keys){
????for(m <- stageMasters(stage)) {
??????propagateData(key, m);
????}
??}
}

這里就有點(diǎn)兒意思了對(duì)于StageSet中的每個(gè)stage中stageableToData中的每個(gè)元素,都會(huì)調(diào)用propgateData函數(shù)進(jìn)行處理。我們不妨先來(lái)看看此時(shí)各stage中的stageableToData中的元素:

stage0:
StageableKey(payload,null)->UInt(8)
stage1:
null
stage2:
StageableKey(payload,null)->UInt(8)

由于stage0沒(méi)有master,無(wú)需考慮,stage1中stageableToData為空,也可以跳過(guò)。那么來(lái)看stage2,此時(shí)調(diào)用propagateData傳入的參數(shù)為:

key=StageableKey(payload,null)->UInt(8)
m=stage1

進(jìn)入propagateData函數(shù),由于stageableTerminal我們并未使用,繼續(xù)往下看,由于stage1中的stageableToData為空,故這里match匹配為None,此時(shí)會(huì)看stage1的master端口,此時(shí)嵌套調(diào)用propagateData,傳入?yún)?shù)為:

key=StageableKey(payload,null)->UInt(8)
m=stage0

由于stage0中的stageableToData包含該key,那么此時(shí)返回true退出,再次回到頭次調(diào)用的處理上。

由于嵌套返回true,那么此時(shí)會(huì)在stage1上調(diào)用apply函數(shù),為stage1插入一個(gè)stageableKey。最終,各stage中stageableToData的結(jié)果為:

stage0:
StageableKey(payload,null)->UInt(8)
stage1:
StageableKey(payload,null)->UInt(8)
stage2:
StageableKey(payload,null)->UInt(8)

看到這里,是不是明白了一些門道了呢?pipeline自動(dòng)幫我們補(bǔ)齊了stage1中所依賴的元素,完成了payload從stage0到stage2中的傳輸元素補(bǔ)齊。

對(duì)于propagateRequirements函數(shù),這里我們并用不上,這里我們先無(wú)需關(guān)注。

接下來(lái)看時(shí)internal connections:

b6457df0-38b3-11ee-9e74-dac502259ad0.png

這里我們近會(huì)用到s.output.valid:=s.input.valid,即將每個(gè)stage中的internal.output.valid由internal.input.valid進(jìn)行驅(qū)動(dòng)。

剩下的就是stage之間的連接了:

for(c<- connections){
??val stageables = (c.m.stageableToData.keys).filter(key => c.s.stageableToData.contains(key) && !c.m.stageableTerminal.contains(key))
var m= ConnectionPoint(c.m.output.valid, c.m.output.ready, stageables.map(c.m.outputOf(_)).toList)
for((l, id) <- c.logics.zipWithIndex){
????val s = if(l?== c.logics.last)
??????ConnectionPoint(c.s.input.valid, c.s.input.ready, stageables.map(c.s.stageableToData(_)).toList)
????else?{
??????ConnectionPoint(Bool(), (m.ready != null) generate Bool(), stageables.map(_.stageable.craft()).toList)
????}
????val area = l.on(m, s, clFlush(l), clFlushNext(l), clFlushNextHit(l), clThrowOne(l), clThrowOneHit(l))
????if(c.logics.size != 1)
??????area.setCompositeName(c, s"level_$id", true)
????else
??????area.setCompositeName(c, true)
????m?= s
??}
}

對(duì)于每個(gè)connection,首先是將master端和slave端stage共有的stageableToData給篩選到stageables中去,這里對(duì)應(yīng)的為:

Connection(m=stage0,s=stage1,logic=M2S):
StageableKey(payload,null)
Connection(m=stage1,s=stage2,logic=M2S):
StageableKey(payload,null)

接著創(chuàng)建ConnectionPoint,對(duì)應(yīng)的paylaod即為StageabelKey所對(duì)應(yīng)的電路對(duì)象,也就意味著:

Connection(m=stage0,s=stage1,logic=M2S): 
m=ConenctionPoint(stage0.out.valid,stage0.out.ready,stage0.stageableToData(StageableKey(payload,null)))
s=ConenctionPoint(stage1.in.valid,stage1.in.ready,stage1.stageableToData(StageableKey(payload,null)))
Connection(m=stage1,s=stage2,logic=M2S):
m=ConenctionPoint(stage1.out.valid,stage1.out.ready,stage1.stageableToData(StageableKey(payload,null)))
s=ConenctionPoint(stage2.in.valid,stage2.in.ready,stage2.stageableToData(StageableKey(payload,null)))

最終,調(diào)用M2S.on創(chuàng)建stage之間的連接關(guān)系:

b6a44b0a-38b3-11ee-9e74-dac502259ad0.png

這里我們只用到6~7行,建立起各stage之間的連接關(guān)系。

至此!完成整個(gè)流水線的創(chuàng)建。

》寫在最后

通過(guò)本篇,分析了一個(gè)簡(jiǎn)單的流水線在Pipeline中的創(chuàng)建實(shí)現(xiàn),后續(xù)將陸續(xù)進(jìn)行更加復(fù)雜流水線的Demo及其背后自動(dòng)實(shí)現(xiàn)原理。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19286

    瀏覽量

    229852
  • 驅(qū)動(dòng)器
    +關(guān)注

    關(guān)注

    52

    文章

    8236

    瀏覽量

    146369
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7492

    瀏覽量

    163842
  • 連接器
    +關(guān)注

    關(guān)注

    98

    文章

    14520

    瀏覽量

    136547
  • Pipeline
    +關(guān)注

    關(guān)注

    0

    文章

    28

    瀏覽量

    9367

原文標(biāo)題:pipeline高端玩法(三)——一個(gè)pipeline是如何建立起來(lái)的

文章出處:【微信號(hào):Spinal FPGA,微信公眾號(hào):Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何構(gòu)建個(gè)簡(jiǎn)單的對(duì)講電路

    在這個(gè)電路中,我們將構(gòu)建個(gè)非常簡(jiǎn)單的對(duì)講電路,您可以使用該電路在房屋或?qū)W校內(nèi)以兩種方式進(jìn)行本地通信。這個(gè)項(xiàng)目帶來(lái)了童年的記憶,即使用火柴盒和線來(lái)制作
    的頭像 發(fā)表于 11-21 17:26 ?1646次閱讀
    如何<b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的對(duì)講電路

    如何構(gòu)建個(gè)簡(jiǎn)單而強(qiáng)大的MP3播放器

    在本教程中,我們將學(xué)習(xí)如何構(gòu)建個(gè)簡(jiǎn)單而強(qiáng)大的 MP3 播放器,可以播放任何 MP3 歌曲,音量和曲目也可以借助按鈕進(jìn)行調(diào)整。通過(guò)些額外的
    的頭像 發(fā)表于 01-25 17:32 ?5176次閱讀
    如何<b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>而強(qiáng)大的MP3播放器

    分享個(gè)51上寫的個(gè)簡(jiǎn)單的操作系統(tǒng),包含完整全部程序

    外圍電路和程序都寫得很熟練了,要想成為單片機(jī)真正應(yīng)用,必須懂時(shí)間片輪度法,狀態(tài)機(jī),最后達(dá)到單片機(jī)系統(tǒng)的境界,網(wǎng)上有很多RTOS,uc/os2,等系統(tǒng),但那些都太專業(yè),需要本書專門學(xué),這里分享個(gè)圈圈寫的小系統(tǒng),大家可以在里面專
    發(fā)表于 07-15 13:30

    電子時(shí)鐘

    `在knewmaker上看見(jiàn)這么篇文章,感覺(jué)還行,轉(zhuǎn)了數(shù)字電子時(shí)鐘可是電子DIY入門第課,對(duì)于了解電路知識(shí)和提高動(dòng)手能力有著很大的幫助。今天小編帶來(lái)的是個(gè)通過(guò)純數(shù)字模塊搭
    發(fā)表于 05-31 10:22

    針對(duì)ARM產(chǎn)品系列的Linux

    Linux是個(gè)類似Unix的電腦操作系統(tǒng),利用免費(fèi)和開(kāi)源的軟件開(kāi)發(fā)以及分銷模式構(gòu)建起來(lái)。專有嵌入式操作系統(tǒng)的優(yōu)勢(shì)包括,擁有不受單軟件公司限制的員工作支持基礎(chǔ),能夠修改和重新發(fā)布源代
    發(fā)表于 02-09 14:32

    微波濾波器應(yīng)用選擇需要注意哪些事項(xiàng)?

    微波濾波器搭建起來(lái)簡(jiǎn)單,但理解起來(lái)比較復(fù)雜。它們?cè)谙到y(tǒng)中完成個(gè)基本的功能:阻止某些信號(hào),通過(guò)其它信號(hào)。但可以用許多不同的方式實(shí)現(xiàn)這種功能
    發(fā)表于 08-19 06:35

    如何構(gòu)建個(gè)簡(jiǎn)單的傳感器?

    您可以自己構(gòu)建個(gè)簡(jiǎn)單的傳感器。 我的博客上有個(gè) PNP 和
    發(fā)表于 04-28 08:23

    元宇宙概念是什么意思

    元宇宙般指通過(guò)多種科技所構(gòu)建起來(lái)種虛擬的宇宙形式,平行于現(xiàn)實(shí)世界的虛擬世界,旨在元宇宙中實(shí)現(xiàn)在現(xiàn)實(shí)中人們可以做到的事。
    的頭像 發(fā)表于 11-01 09:47 ?1.4w次閱讀

    如何構(gòu)建個(gè)簡(jiǎn)單的基于紅外的車門遙控器

    在這篇文章中,我們將學(xué)習(xí)如何構(gòu)建個(gè)簡(jiǎn)單但萬(wàn)無(wú)失的基于紅外的遙控器,該遙控器可用于通過(guò)個(gè)人遙控手機(jī)鎖定和解鎖任何車門。
    的頭像 發(fā)表于 04-02 10:37 ?1313次閱讀
    如何<b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的基于紅外的車門遙控器

    文解析新型電力系統(tǒng)與智能裝備技術(shù)

    新型電力系統(tǒng)是指基于智能電網(wǎng)、清潔能源、能源互聯(lián)網(wǎng)等技術(shù)和理念,構(gòu)建起來(lái)的高效、安全、可靠、可持續(xù)的電力系統(tǒng)。
    發(fā)表于 04-24 11:50 ?3498次閱讀
    <b class='flag-5'>一</b>文解析新型電力系統(tǒng)與智能裝備技術(shù)

    構(gòu)建個(gè)簡(jiǎn)單的機(jī)械臂

    電子發(fā)燒友網(wǎng)站提供《構(gòu)建個(gè)簡(jiǎn)單的機(jī)械臂.zip》資料免費(fèi)下載
    發(fā)表于 06-14 14:55 ?0次下載
    <b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的機(jī)械臂

    構(gòu)建個(gè)簡(jiǎn)單的提醒報(bào)警電路

    一個(gè)工作狂可能聽(tīng)起來(lái)有點(diǎn)酷。但研究表明,傾向于長(zhǎng)時(shí)間坐在電腦前工作的人患糖尿病、心臟病等疾病的風(fēng)險(xiǎn)很高。所以我想設(shè)計(jì)個(gè)簡(jiǎn)單的電路,可以幫
    的頭像 發(fā)表于 06-18 10:14 ?829次閱讀
    <b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的提醒報(bào)警電路

    如何構(gòu)建個(gè)簡(jiǎn)單的家庭自動(dòng)化

    電子發(fā)燒友網(wǎng)站提供《如何構(gòu)建個(gè)簡(jiǎn)單的家庭自動(dòng)化.zip》資料免費(fèi)下載
    發(fā)表于 07-05 11:41 ?0次下載
    如何<b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的家庭自動(dòng)化

    什么是pipeline?Go中構(gòu)建流數(shù)據(jù)pipeline的技術(shù)

    本文介紹了在 Go 中構(gòu)建流數(shù)據(jù)pipeline的技術(shù)。 處理此類pipeline中的故障很棘手,因?yàn)?b class='flag-5'>pipeline中的每個(gè)階段可能會(huì)阻止嘗試向下游發(fā)送值,并且下游階段可能不再關(guān)心傳
    的頭像 發(fā)表于 03-11 10:16 ?613次閱讀

    為THS3001構(gòu)建個(gè)簡(jiǎn)單的SPICE模型

    電子發(fā)燒友網(wǎng)站提供《為THS3001構(gòu)建個(gè)簡(jiǎn)單的SPICE模型.pdf》資料免費(fèi)下載
    發(fā)表于 10-29 10:11 ?0次下載
    為THS3001<b class='flag-5'>構(gòu)建</b><b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>簡(jiǎn)單</b>的SPICE模型