当前位置:网站首页>吃透Chisel语言.12.Chisel项目构建、运行和测试(四)——Chisel测试之ChiselTest
吃透Chisel语言.12.Chisel项目构建、运行和测试(四)——Chisel测试之ChiselTest
2022-07-04 12:49:00 【github-3rr0r】
Chisel项目构建、运行和测试(四)——Chisel测试之ChiselTest
上一篇文章我们介绍了ScalaTest,它是Scala和Java的测试工具。而现在Chisel模块最新的标准测试工具是ChiselTest,它是基于ScalaTest的,允许我们用于Chisel测试。为了使用ChiselTest,我们同样需要在build.sbt
里面包含chiseltest
的库:
libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "0.5.1" % "test"
或者这样:
libraryDependencies ++= Seq(
"edu.berkeley.cs" %% "chisel3" % chiselVersion,
"edu.berkeley.cs" %% "chiseltest" % "0.5.1" % "test"
),
Chisel-template的build.sbt
里面是默认包含了chiseltest
库的,所以我们可以不修改。用这种方法包含ChiselTest会自动包含对应版本的ScalaTest,所以上一篇文章中说的包含ScalaTest也是不需要的。
要使用ChiselTest的话,我们需要导入下面的这些包:
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
对电路进行测试需要包含至少两部分,一个是DUT(待测件),另一个是测试逻辑,也叫testbench。启动测试和ScalaTest是一样的,运行sbt test
命令就行了,不需要有个包含主函数的对象作为程序入口。
下面的代码是一个简单的DUT,它有两个输入端口和一个输出端口,都是二位无符号数信号,实现的功能是对输入a
和b
执行按位与操作,然后把结果输出到out
上:
class DeviceUnderTest extends Module {
val io = IO(new Bundle {
val a = Input(UInt(2.W))
val b = Input(UInt(2.W))
val out = Output(UInt(2.W))
})
io.out := io.a & io.b
}
虽然还没介绍模块的写法,但是这个代码也是很好懂的。现在我们给出这个DUT的testbench,它是从AnyFlatSpec
和ChiselScalatestTester
拓展来的,因此是具有ChiselTest功能的ScalaTest。而调用test()
方法时,以新创建的DUT的一个实例为参数,以测试代码为函数字面量(function literal)。代码如下:
class SimpleTest extends AnyFlatSpec with ChiselScalatestTester {
"DUT" should "pass" in {
test(new DeviceUnderTest) {
dut =>
dut.io.a.poke(0.U)
dut.io.b.poke(1.U)
dut.clock.step()
println("Result is: " + dut.io.out.peek().toString)
dut.io.a.poke(3.U)
dut.io.b.poke(2.U)
dut.clock.step()
println("Result is: " + dut.io.out.peek().toString)
}
}
}
DUT的实例的输入输出端口通过dut.io
来访问。我们可以通过在端口上调用poke
来给端口赋值,它接受的是端口对应的Chisel类型的值。而在输出端口上调用peek
可以把端口的输出给读取出来,返回值也是该端口对应的Chisel类型的值,再在该值上调用toString
可以将其转换为字符串,进而可以调用println()
函数在命令行输出。测试中调用dut.clock.step()
可以让时钟前进一个周期,以此让仿真前进。要是想要前进多个周期,我们可以给step()
提供一个参数。
运行sbt test
或者:
sbt "testOnly SimpleTest"
就可以在终端看到测试的结果:
结果表明,0
和1
按位与的结果为0
,3
和2
按位与的结果为2。当然信息不止有结果,我们还可以看到toString
方法还输出了结果的Chisel类型UInt<2>
,即二位无符号整数。
那我们人工核对输出结果肯定是不好的,但确实已经成功一半了。要想自动完成和预期结果的比较,我们可以通过在输出端口上调用expect(value)
来在testbench中给出预期值,预期值就是expect(value)
的参数value
。修改之后的测试如下:
class SimpleTestExpect extends AnyFlatSpec with ChiselScalatestTester {
"DUT" should "pass" in {
test(new DeviceUnderTest) {
dut =>
dut.io.a.poke(0.U)
dut.io.b.poke(1.U)
dut.clock.step()
dut.io.out.expect(0.U)
dut.io.a.poke(3.U)
dut.io.b.poke(2.U)
dut.clock.step()
dut.io.out.expect(2.U)
}
}
}
现在运行这个测试:
sbt "testOnly SimpleTestExpect"
这个测试不会输出任何来自硬件的结果,它自动在测试内完成了结果与预期值的比较,输出如下:
如果测试失败的话,比如DUT或者testbench里面有错误,导致实际结果和预期值不符,那就回生成一条错误信息来描述两者的差异。比如我们把testbench中最后一行的dut.io.out.expect(2.U)
改成dut.io.out.expect(1.U)
,输出结果就是这样的:
一片红色的报错,同时也给出了测试未通过的理由和具体差异在哪里,在调试的时候这些信息非常有用,所以说测试很重要。
结语
这一篇文章讲了如何用ChiselTest做简单的测试,可以看到很基础,同时也很方便。然而,更精髓的内容还没有体现出来,目前写的测试还没有发挥Scala的强大能力。比如说,上面的测试里面我们都是手动给出测试的输入和输出预期值的,而Scala可以用于写一个参考模型,也就是在另一个系列中说的黄金模型,这样测试就可以更自动化、更全面了。不过我们暂时还不会展开讲,得先把几个测试方法都讲完先,下一篇我们就讲讲用波形进行测试。
边栏推荐
- 学习项目是自己找的,成长机会是自己创造的
- C语言程序设计选题参考
- 面试拆解:系统上线后Cpu使用率飙升如何排查?
- Distributed base theory
- Getting started with microservices
- SQL language
- 30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
- Samsung's mass production of 3nm products has attracted the attention of Taiwan media: whether it can improve the input-output rate in the short term is the key to compete with TSMC
- FS4059C是5V输入升压充电12.6V1.2A给三节锂电池充电芯片 输入小电流不会拉死,温度60°建议1000-1100MA
- CVPR 2022 | 大幅减少零样本学习所需的人工标注,提出富含视觉信息的类别语义嵌入(源代码下载)...
猜你喜欢
硬件基础知识-二极管基础
国内酒店交易DDD应用与实践——代码篇
OPPO Find N2产品形态首曝:补齐各项短板
MySQL 45 lecture - learn the actual combat notes of MySQL in Geek time 45 lecture - 06 | global lock and table lock_ Why are there so many obstacles in adding a field to the table
一次 Keepalived 高可用的事故,让我重学了一遍它
Automatic filling of database public fields
自主工业软件的创新与发展
Doctoral application | West Lake University Learning and reasoning system laboratory recruits postdoctoral / doctoral / research internship, etc
Oracle 被 Ventana Research 评为数字创新奖总冠军
Node の MongoDB安装
随机推荐
2022危险化学品经营单位主要负责人练习题及模拟考试
华昊中天冲刺科创板:年亏2.8亿拟募资15亿 贝达药业是股东
2022kdd pre lecture | 11 first-class scholars take you to unlock excellent papers in advance
Openharmony application development how to create dayu200 previewer
Go 语言入门很简单:Go 实现凯撒密码
30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
FS7867S是一款应用于数字系统供电电源电压监控的电压检测芯片
担心“断气” 德国正修改《能源安全法》
MySQL45讲——学习极客时间MySQL实战45讲笔记—— 06 | 全局锁和表锁_给表加个字段怎么有这么多阻碍
C foundation in-depth study I
Huahao Zhongtian sprint Technology Innovation Board: perte annuelle de 280 millions de RMB, projet de collecte de fonds de 1,5 milliard de Beida Pharmaceutical est actionnaire
程序员转方向
Distributed base theory
Dgraph: large scale dynamic graph dataset
锐成芯微冲刺科创板:年营收3.67亿拟募资13亿 大唐电信是股东
Introduction to reverse debugging PE structure resource table 07/07
Install Trinity and solve error reporting
WS2818M是CPC8封装,是三通道LED驱动控制专用电路外置IC全彩双信号5V32灯可编程led灯带户外工程
MySQL 45 lecture - learn the actual combat notes of MySQL in Geek time 45 lecture - 06 | global lock and table lock_ Why are there so many obstacles in adding a field to the table
高质量软件架构的唯一核心指标