✎ 编 者 按
最近微信交流群里有小伙伴在讨论后端做memory时memory使用的大小不同例化时也需要使用不同的memory名称,这种情形往往采用BlackBox的形式来实现,来汇总下群里的结论,通过采用setblackname的形式来动态指定Blackbox模块名
同样的接口,不同的模块名
针对上面的场景,memory的接口信号列表名称往往是相同的,其差别点在于模块名不同。以下面的Spram为例:
case class Spram(depth:Int,width:Int) extends BlackBox{
addGeneric("DEPTH",depth)
addGeneric("WIDTH",width)
val io=new Bundle{
val clk=in Bool()
val addr=in UInt(log2Up(depth) bits)
val we=in Bool()
val din=in Bits(width bits)
val dout=out Bits(width bits)
}
noIoPrefix()
mapClockDomain(clock = io.clk)
}
众所周知,在SpinalHDL里默认情况下Blackbox的生命的类名称和所对应的Verilog模块名保持一致。而上面的场景则是:
- depth=512,width=32,所要例化使用的模块名为Spram_512x32
- depth=1024,width=16,所要例化使用的模块名为Spram_1024x16
这里面所有的接口列表都是一致的,唯一不同就是模块名称不同。如果说像Spram_512x32、Spram_1024x16这些每个都做一个Blackbox封装,也不是不可以,只是略微优显得蠢笨了~
setBlackBoxName
正常情况下,当我们例化Spram时:
case class SpramDemo() extends Component{
val io=new Bundle{
val addr0=in UInt(log2Up(512) bits)
val we0=in Bool()
val din0=in Bits(32 bits)
val dout0=out Bits(32 bits)
val addr1=in UInt(log2Up(1024) bits)
val we1=in Bool()
val din1=in Bits(16 bits)
val dout1=out Bits(16 bits)
}
noIoPrefix()
val spram0=Spram(512,32)
val spram1=Spram(1024,16)
spram0.io.addr<>io.addr0
spram0.io.we<>io.we0
spram0.io.din<>io.din0
spram0.io.dout<>io.dout0
spram1.io.addr<>io.addr1
spram1.io.we<>io.we1
spram1.io.din<>io.din1
spram1.io.dout<>io.dout1
}
这种情况下,最终生成的RTL代码会例化两个名为Spram的模块:
这里可以通过设置setBlackBoxName的形式来指定例化的模块名:
val spram0=Spram(512,32) setBlackBoxName("Spram_512x32") val spram1=Spram(1024,16) setBlackBoxName("Spram_1024x16")
如此,在最终生成RTL代码时便能达到我们的预期:
当然也可以通过setInlineVerilog直接动态生成所需要的代码,如下为群友的Demo:
setDefinitionName
上面所讨论的是针对BlackBox的模块名动态指定,对于Component,我们也可以通过setDefinitionName来设置模块名。如下所示:
object SpramDemoApp extends App{
SpinalSystemVerilog(SpramDemo().setDefinitionName("Demo"))
}
这里将SpramDemo模块在生成RTL时模块名更改为Demo
☆ END ☆
作者:玉骐
原文链接:Spinal FPGA
微信公众号:
推荐阅读
更多SpinalHDL技术干货请关注[Spinal FPGA]欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。