》spawn
在Stage中,關于spawn,定義了下面的兩個API:
defspawnIt()(implicit loc: Location):Unit = spawnIt(ConditionalContext.isTrue) defspawnIt(cond : Bool)(implicit loc: Location):Unit = internals.request.spawns += nameFromLocation(CombInit(cond), "spawnRequest")
spawn的調用,最終會把觸發條件cond存儲至internals.request.spawns中去。
而在Pipeline中,internal.request.spawns僅使用在了Internal Connection中:
//Internal connections
for(s <- stagesSet){
??????s.output.valid := s.input.valid
??????if(s.request.spawns.nonEmpty){
????????when(s.request.spawns.orR){
??????????s.output.valid := True
????????}
??????}
可以看到,對于Stage內部,若果spawns非空,則spawns中只要有一個條件成立那么其output.valid即會設置為True,相當于對output.valid進行了擴展多個時鐘周期。
值得注意的是,其僅對valid進行了擴展,而并沒有處理input.ready信號。
看到這里,對于spawnIt的用法諸君應該能大體看明白,其就是為了對Stage中的output.valid進行延展。
》example
由于spawnIt并沒有對input.ready進行處理,故如果pipeline中如果有ready信號時使用需謹慎,這里給出一個pipeline中不使用ready的example:
caseclass SpawnTest() extends Component{
val io=newBundle{
val data_in= slave (Flow(UInt(8bits)))
val data_out= master(Flow(UInt(8bits)))
}
noIoPrefix()
val cycle_num=Stageable(UInt(8bits))
val pip=newPipeline{
val stage0=newStage{
importinternals._
input.valid:=io.data_in.valid
cycle_num:=io.data_in.payload
}
val stage1=newStage(Connection.M2S()){}
val stage2=newStage(Connection.M2S()){
io.data_out.valid:=internals.output.valid
val cycle_cnt=Reg(UInt(8bits)) init(0)
when(internals.input.valid){
cycle_cnt:=(cycle_num===1)?cycle_cnt|(cycle_num-1)
io.data_out.payload:=cycle_num
}otherwise{
cycle_cnt:= (cycle_cnt.orR)? (cycle_cnt-1)|cycle_cnt
io.data_out.payload:=cycle_cnt
}
spawnIt(cycle_cnt=/=0)
}
}
pip.build()
}
這個例子中pipeline存在三個Stage,對于data_in,在stage2中會對根據data_in.payload的值展開相應的拍數(兩個data_in有效數據確保有足夠的間隔),示例波形如下:



可以看到,當data_in_payload為1時,data_out_payload輸出一拍,數據為1.當data_in_payload為2時,data_out_payload輸出兩拍,數據分別為2,1.當data_in_payload為3時,data_out_payload輸出三拍,數據分別為1,2,3.實現data_in.valid的擴展。
附上仿真代碼:
importspinal.core.sim._ object SpawnTestSim extends App{ SimConfig.withFstWave.compile(SpawnTest()).doSim{dut=> dut.io.data_in.valid#=false dut.clockDomain.forkStimulus(10) dut.clockDomain.waitSampling(10) dut.io.data_in.valid#=true dut.io.data_in.payload#=1 dut.clockDomain.waitSampling() dut.io.data_in.valid#=false for(index<-0?until?10){ ??????dut.io.data_in.payload#=index ??????dut.clockDomain.waitSampling() ????} ????dut.io.data_in.valid#=true ????dut.io.data_in.payload#=2 ????dut.clockDomain.waitSampling() ????dut.io.data_in.valid#=false ????for(index<-0?until?10){ ??????dut.io.data_in.payload#=index ??????dut.clockDomain.waitSampling() ????} ????dut.io.data_in.valid#=true ????dut.io.data_in.payload#=3 ????dut.clockDomain.waitSampling() ????dut.io.data_in.valid#=false ????for(index<-0?until?10){ ??????dut.io.data_in.payload#=index ??????dut.clockDomain.waitSampling() ????} ??} }
審核編輯:劉清
-
存儲器
+關注
關注
39文章
7738瀏覽量
171654 -
仿真器
+關注
關注
14文章
1051瀏覽量
87263 -
Pipeline
+關注
關注
0文章
29瀏覽量
9960
原文標題:pipeline高端玩法(十一)—spawnIt
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
扒一扒與無線網絡相關的那些事
扒一扒我看過的那些Linux相關的書籍
扒渣機產品有哪些參數
扒一扒C語言hello world背后的內幕
華為P10這么早被扒光,目的只有一個!懟肛小米6
扒一扒華為路由 A1 暢享版,如何做到便宜好用
美容儀哪個牌子好?來扒一扒令人眼花繚亂的日本美容儀
扒一扒好用的日本家用美容儀品牌,讓你享受清潔肌膚的樂趣
扒店saas系統創新性服務平臺的優勢是什么
扒一扒中斷為什么不能調printf?
扒一個超棒的stm32的開源usb-can項目,canable及PCAN固件
扒一扒pipeline中“spawn”的用法
評論