设计总离不开仿真,SpinalHDL已经集成了仿真环境,作为软件“半调子”,在仿真时关于数据的生成与转换推荐几个方法。
byteArray2BigInt
仿真时我们的数据激励来源往往来自于文件或者自己构造的随机数。不同于C、C++语言,无论是Scala还是Java,其都不支持无符号数。而在逻辑电路设计里往往无符号数随处可见。如果我们的电路里有一个接口定义为:
val a=in UInt(8 bits)
当我们在仿真中如果采用下面的激励注入方式:
dut.io.a#=-1
那么将会给我们报错,a不接受负数。
回归数据类型的本质,无论是有符号数还是无符号数,其本质都是bit的集合,而无符号数有符号数只不过是语言本身的限制罢了。
像Axi4、Stream这些大位宽总线接口,512bit位宽数据对应着64字节数据。在仿真时,如果我们的数据存在于文件中,那么可以按ByteArray形式从文件中读取激励数据,此时可以通过下面的方法用于生成接口上的数据激励:
def ByteArray2BigInt(data:Array[Byte])={
val buffer = data.reverse.toBuffer
buffer.prepend(0.toByte)
BigInt(buffer.toArray)
}
代码第二行做数组的reverse主要用于生成小尾端数据。如果需要大尾端则可以去掉reverse。第三行则避免生成的BigInt为负数。
通过上面的形式,可以很便捷的生成我们想要的数据格式:
IN:println(f"${ByteArray2BigInt(Array(-1,-2,-3).map(_.toByte))}%x")
Out:fdfeff
如此我们的测试源数据均可以按照ByteArray形式组织,通过该方法可以快速的生成测试激励数据。
BigInt2ByteArray
同样BigInt也可以生成对应的ByteArray:
def BigInt2ByteArray(data:BigInt,len:Int):Array[Byte]={
val dataArray=data.toByteArray.reverse
var length = scala.math.min(len, dataArray.length)
var result = Array.fill[Byte](len)(0.toByte)
for(i <- 0 until length)
result(i) = dataArray(i)
result
}
方法的len指定数据对应的长度。可用于读取测试单元输出数据。
IN:println(BigInt2ByteArray(BigInt("fdfeff",16),3).toBuffer)
Out:ArrayBuffer(-1, -2, -3)
BigIntToListBoolean
该方法为spinal.lib.tool中所提供,可用于BigIntl生成对应的Boolean列表。在像仿真Axi4总线时对keep信号的分析比较有用。
import spinal.lib.tools.BigIntToListBoolean
println(BigIntToListBoolean(BigInt("fe",16),8 bits))
将输出:
List(false, true, true, true, true, true, true, true)
Example
给出一个example:
DUT:
![Image]
testBench:
感兴趣的小伙伴不妨在此基础上添加下BigIntToListBoolean的使用测试
END
作者:玉骐
原文链接:https://mp.weixin.qq.com/s/276sSzvZqYO2NuVrQzSPKA
微信公众号:
推荐阅读
更多SpinalHDL技术干货请关注Spinal FPGA专栏。