本系列适合新手在对Scala及SpinalHDL有初步了解后做练手使用。
题目
端口列表:针对多比特输入信号,对其中的比特位分组求异或值。
参数类:
case class config(bitsPerGroup:Int,
dataWidth:Int){
require(dataWidth%bitsPerGroup==0,"Invalid parameter")
val sigOutWidth=dataWidth/bitsPerGroup
}
这里将参数放置在一个class中,以便方便使用及统一的参数检查。
实现
case class config(bitsPerGroup:Int,
dataWidth:Int){
require(dataWidth%bitsPerGroup==0,"Invalid parameter")
val sigOutWidth=dataWidth/bitsPerGroup
}
case class example2(cfg:config) extends Component{
val io=new Bundle{
val sigIn=in UInt(cfg.dataWidth bits)
val sigOut=out UInt(cfg.sigOutWidth bits)
}
noIoPrefix()
val _=new Area{
io.sigOut:=io.sigIn.subdivideIn(cfg.bitsPerGroup bits).map(_.xorR).asBits().asUInt
}.setName("")
}
object example2App extends App{
val cfg=config(8,32)
SpinalSystemVerilog(example2(cfg)).printPruned()
}
Key:
- subdivideIn方法的使用
- Scala Collection中map函数的使用
进阶一
对每组比特安位取反,随后对每组比特累加求和.考虑到时序问题,在求和前添加一级寄存器
case class config(bitsPerGroup:Int,
dataWidth:Int){
require(dataWidth%bitsPerGroup==0,"Invalid parameter")
val sigOutWidth=dataWidth/bitsPerGroup
}
case class example2_1(cfg:config) extends Component{
val io=new Bundle{
val sigIn=in UInt(cfg.dataWidth bits)
val sigOut=out UInt(cfg.bitsPerGroup bits)
}
noIoPrefix()
val _=new Area{
io.sigOut:=(io.sigIn.subdivideIn(cfg.bitsPerGroup bits).map(~_).map(RegNext(_))).reduce(_+_)
}.setName("")
}
object example2App extends App{
val cfg=config(8,32)
SpinalSystemVerilog(example2_1(cfg)).printPruned()
}
Key:
- Scala Collection中reduce函数的使用
进阶二
在进阶一的基础上,当加法溢出时做饱和处理
case class config(bitsPerGroup:Int,
dataWidth:Int){
require(dataWidth%bitsPerGroup==0,"Invalid parameter")
val sigOutWidth=dataWidth/bitsPerGroup
}
case class example2_2(cfg:config) extends Component{
val io=new Bundle{
val sigIn=in UInt(cfg.dataWidth bits)
val sigOut=out UInt(cfg.bitsPerGroup bits)
}
noIoPrefix()
val _=new Area{
io.sigOut:=(io.sigIn.subdivideIn(cfg.bitsPerGroup bits).map(~_).map(RegNext(_))).reduce(_ +| _)
}.setName("")
}
object example2App extends App{
val cfg=config(8,32)
SpinalSystemVerilog(example2_2(cfg)).printPruned()
}
Key:
- SpinalHDL中UInt/SInt中“+|”操作符使用。
END
作者:玉骐
原文链接:https://mp.weixin.qq.com/s/s6Y4UUG4qmTQ2T\_fBfAaUA
微信公众号:
推荐阅读
更多SpinalHDL技术干货请关注Spinal FPGA专栏。