risc-v中文社区

 找回密码
 立即注册
查看: 1392|回复: 0

[原创] chisel的测试

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-16 09:50:31 | 显示全部楼层 |阅读模式
chisel的测试有二种,一种是利用scalas的测试(assert)来验证chisel级别的代码逻辑有没有错误,另一种就是利用chisel库中的peek和poke,给module的端口加激励,查看信号值,并交给下游的verilator来仿真,产生波形,
这种方式比较简单,类似于verilog中的testbench,适合小型电路仿真,对于大型项目,还是生成verilog次给专业的EDA工具用UVM进行验证较好。结合上一帖的例子,我在此介绍第二种方法
先编写一个类AdderTests,它要接收一个待测试模块类型(c:Adder)的参数,并且extends PeekPokeTester(c),将AdderTests类的构造器参数c传给父类peekPokeTester。
查看源码:abstract class PeekPokeTester[+T <: MultiIOModule]{
...
def step(n:Int)...
def poke[T<:Elementokeable](signal:T,value:Int)....
def peek[T<:Elementokeable](singal:T):BigInt...
def expect[T<Elementokeable](signal:T,expected:BigInt,msg:=>String=""):Boolean...
...
可以看到PeekPokeTester类中有很多测试方法,但常用的是step/poke/peek/expect这四个。
1)poke(端口,激励值)的语法形式进行端口测试,比如帖子中的例子poke(c.io.A,rnd0),从源码中def poke的signal:T所属的参型限制T<:Elementokeable来看,val A = Input(UInt(n.W))的类型是UInt,UInt是Element的子类,
另外,在同一个chisel3.iotesters包下,object Pokeable中有隐式对象:implicit object RuntimePokeable extends Pokeable[IsRuntimePokeable],所以poke(c.io.A,rnd0)语法是正确的,功能是激励值为rnd0:Int,待测试端口是io.c.A,通过poke(c.io.A,rnd0)就将端口仿真数据设置成功。
2)step(n:Int)循环进行n步, 在每一步,寄存器和存储器都被推进,所有其他元素都重新计算(step最终还是InterpretiveTester的step循环执行FirrtlTerp的cycle方法。可以猜想出来:FirrtlTerp中cycle肯定是按照.fir文件进行执行,因为.fir文件最后还是由firrtl编译器编译出.v文件,所以从逻辑上来说就是对.v中代码进行仿真,至于说是不是一对一的step多少步,估计应该不是完全的一对一的关系)
3)expect方法在PeekPokeTester.scala中的源码是:def expect[T<:Elementokeable](signal:T,expected:BigInt,msg: =>String=""):Boolean...,它最终执行的是FirrtlTerpBackend中的expect(看源码可以发现采用的是match模式匹配的类型模式case port:Element,匹配成功之后会通过InterperetiveTester的peek(name)获取这个io端口的值,然后再判断与期待值expect是否一致,不一致的话则将msg显示出来),也就是说expect对一个Element类型的信号,期待其值与某个给定的BigInt类型的参考值是一样的,如果不一致则显示msg信息。
4)peek 获取某个信号的值:
最终也是执行InterpretiveTester中的peek:
  def peek(name: String): BigInt = {
    if(interpreter.checkStopped(s"peek($name)")) return 0

    interpreter.getValue(name) match {
      case ConcreteUInt(value, _, _) => value
      case ConcreteSInt(value, _, _) => value
      case _ =>
        fail(new InterpreterException(s"Error:peek($name) value not found"))
    }
  }
通过模式匹配中的构造模式获取待测试信号的值。








回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-27 15:58 , Processed in 0.014076 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表