》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文章
7714浏览量
170852 -
仿真器
+关注
关注
14文章
1048浏览量
86761 -
Pipeline
+关注
关注
0文章
29浏览量
9911
原文标题:pipeline高端玩法(十一)—spawnIt
文章出处:【微信号:Spinal FPGA,微信公众号:Spinal FPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
扒一扒与无线网络相关的那些事
扒一扒我看过的那些Linux相关的书籍
扒渣机产品有哪些参数
扒一扒C语言hello world背后的内幕
扒一扒华为路由 A1 畅享版,如何做到便宜好用
美容仪哪个牌子好?来扒一扒令人眼花缭乱的日本美容仪
扒一扒好用的日本家用美容仪品牌,让你享受清洁肌肤的乐趣
扒店saas系统创新性服务平台的优势是什么
扒一扒中断为什么不能调printf?
扒一个超棒的stm32的开源usb-can项目,canable及PCAN固件

扒一扒pipeline中“spawn”的用法
评论