》Stageable、StageableKey stageable、StageableKey是最整個(gè)pipeline中的基本數(shù)據(jù)類(lèi)型元素:
object Stageable{ def apply[T <: Data](gen : => T) = new Stageable(gen) def apply[T <: Data](gen : HardType[T]) = new Stageable(gen.craft()) } class Stageable[T <: Data](gen : => T) extends HardType(gen) with Nameable { } case class StageableOffset(val value : Any) object StageableOffsetNone extends StageableOffset(null) case class StageableKey(stageable: Stageable[Data], key : Any){ override def toString = { var name = stageable.getName() if(key != null) name = name + "_" + key name } }
對(duì)于Stageabel,我們可以傳入任何SpinalHDL下面定義的隸屬于Data的類(lèi)型,不同于我們?cè)陔娐防锷粋€(gè)電路對(duì)象:
vala=UInt(8bits)
此時(shí),電路對(duì)象是立即生命存在的,如果我們不對(duì)他進(jìn)行賦值會(huì)報(bào)錯(cuò)。而:
valb=Stageable(UInt(8bits))
此時(shí)b并未真正生成電路對(duì)象,即使不對(duì)他進(jìn)行賦值也并不會(huì)報(bào)錯(cuò)。
對(duì)于StageableKey,字如其名,其主要用作Key使用,用于建立Stageable映射時(shí)的key使用。
》Stage
借用上一篇文章中的圖:
Stage主要用于實(shí)現(xiàn)pipeline的功能實(shí)現(xiàn)。那么Stage則定義了這些功能的輸入、輸出:
val input = new{ val valid = Bool() varready : Bool = null } val output = newArea { val valid = Bool() varready : Bool = null }
以及一些列的內(nèi)部保存變量:
val arbitration = new{ varisRemoved : Bool = null varisFlushed : Bool = null varisThrown : Bool = null varisForked : Bool = null varisFlushingNext : Bool = null varisFlushingRoot : Bool = null varisHalted : Bool = null varisHaltedByOthers : Bool = null varpropagateReady = false } val request = new{ val halts = ArrayBuffer[Bool]() val throws = ArrayBuffer[Bool]() val throwsRoot = ArrayBuffer[Bool]() val forks = ArrayBuffer[Bool]() val spawns = ArrayBuffer[Bool]() val flush = ArrayBuffer[Bool]() val flushRoot = ArrayBuffer[Bool]() val flushNext = ArrayBuffer[Bool]() } val stageableToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableOverloadedToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableResultingToData = mutable.LinkedHashMap[StageableKey, Data]() val stageableTerminal = mutable.LinkedHashSet[StageableKey]()
這些變量暫時(shí)看不懂也沒(méi)關(guān)系,后續(xù)會(huì)通過(guò)例子逐一進(jìn)行講解。通過(guò)這些內(nèi)部變量,pipeline在構(gòu)建電路時(shí)處理Stage之間的依賴(lài)關(guān)系。
》Connection
顧名思義,Connection用于負(fù)責(zé)Stage之間的連接關(guān)系,即其負(fù)責(zé)處理上一級(jí)Stage的output與下一級(jí)Stage的input之間的連接。在Lib中,Connection定義了四種連接關(guān)系:
DIRECT:類(lèi)似一兩個(gè)Stream直接相連
M2S:類(lèi)似于Stream中的M2SPipe,對(duì)valid、payload進(jìn)行打拍輸出
S2M:類(lèi)似于Stream中的S2MPipe,對(duì)于ready進(jìn)行打拍輸出
乍看其實(shí)現(xiàn)你會(huì)發(fā)現(xiàn)其中有好多參數(shù)一時(shí)不知用途,無(wú)妨,先放一放,回頭逐一講解。
》pipeline
Pipeline中核心是一個(gè)build函數(shù)。當(dāng)我們描述完各Stage的功能之后,通過(guò)調(diào)用Pipeline的build函數(shù)即可構(gòu)建整個(gè)的流水線電路,其也是整個(gè)pipelines構(gòu)建的核心,直接上來(lái)看可能會(huì)略覺(jué)麻煩,后面通過(guò)例子一點(diǎn)點(diǎn)來(lái)理解。
》第一個(gè)例子
先有個(gè)概念之后,我們?cè)賮?lái)一個(gè)pipeline的第一個(gè)例子:
caseclassdemo() extendsComponent{ val io=newBundle{ val data_in=slave Flow(UInt(8bits)) val data_out=master Flow(UInt(8bits)) } noIoPrefix() val pip=newPipeline{ val paylaod=Stageable(UInt(8bits)) val stage0=newStage{ importinternals._ input.valid:=io.data_in.valid this(paylaod):=io.data_in.payload } val stage1=newStage(Connection.M2S()) val stage2=newStage(Connection.M2S()){ io.data_out.valid:=internals.output.valid io.data_out.payload:=this(paylaod) } } pip.build() }
這個(gè)例子的功能是將Flow data_in打兩拍輸出給data_out,一個(gè)最簡(jiǎn)單的流水線結(jié)構(gòu),不牽涉到任何halt、flush等相關(guān)操作。如果你看不懂,可以先看它生成的RTL代碼:
moduledemo ( input data_in_valid, input [7:0] data_in_payload, output data_out_valid, output [7:0] data_out_payload, input clk, input reset ); reg[7:0] pip_stage1_paylaod; reg[7:0] pip_stage2_paylaod; wire[7:0] pip_stage0_paylaod; wirepip_stage0_valid; regpip_stage1_valid; regpip_stage2_valid; assignpip_stage0_valid = data_in_valid; assignpip_stage0_paylaod = data_in_payload; assigndata_out_valid = pip_stage2_valid; assigndata_out_payload = pip_stage2_paylaod; always@(posedge clk or posedge reset) begin if(reset) begin pip_stage1_valid <= 1'b0; ??????pip_stage2_valid <= 1'b0; ????end?else begin ??????pip_stage1_valid <= pip_stage0_valid; ??????pip_stage2_valid?<= pip_stage1_valid; ????end ??end ??always @(posedge clk) begin ????pip_stage1_paylaod <= pip_stage0_paylaod; ????pip_stage2_paylaod?<= pip_stage1_paylaod; ??end endmodule
一眼看去,可能覺(jué)得很怪,有很多疑問(wèn)。比如說(shuō)data_in的valid信號(hào)是如何從stage0傳輸?shù)絪tage1的等等。
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
19395瀏覽量
230671 -
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59896 -
Pipeline
+關(guān)注
關(guān)注
0文章
28瀏覽量
9377 -
VaR
+關(guān)注
關(guān)注
0文章
39瀏覽量
11361 -
HDL語(yǔ)言
+關(guān)注
關(guān)注
0文章
47瀏覽量
8942
原文標(biāo)題:pipeline高端玩法(二)——成員一覽
文章出處:【微信號(hào):Spinal FPGA,微信公眾號(hào):Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論