Использование ScalaCheck с PeekPokeTester

Вот тест chisel3, который использует ScalaCheck для проверки свойств простой комбинационной схемы.

package stackoverflow

import org.scalatest.{ Matchers, FlatSpec, GivenWhenThen}
import org.scalacheck.{ Properties, Gen, Arbitrary}
import org.scalacheck.Prop.{ forAll, AnyOperators, collect}

import chisel3._
import firrtl_interpreter.InterpretiveTester

object G {
  val width = 8
}

class Add extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(G.width.W))
    val b = Input(UInt(G.width.W))
    val o = Output(UInt(G.width.W))
  })
  io.o := io.a + io.b
}

class AddTester {
  val s = chisel3.Driver.emit( () => new Add)
  val tester = new InterpretiveTester( s)
  def run( a : Int, b : Int) = {
    val result = (a + b) & ((1 << G.width)-1)
    tester.poke( s"io_a", a)
    tester.poke( s"io_b", b)
    tester.peek( s"io_o") ?= result
  }
}

object AddTest extends Properties("Add") {
  val t = new AddTester
  val gen = Gen.choose(0,(1 << G.width)-1)
  property("Add") = forAll( gen, gen) {
    case (a:Int,b:Int) => t.run( a, b)
  }
}

Это использует интерпретатор firtl напрямую. Кто-нибудь знает, как сделать что-то подобное с помощью PeekPokeTester, чтобы я также мог использовать бэкэнды verilator и vcs?


person Steve Burns    schedule 03.05.2017    source источник


Ответы (1)


Это близко к тому, что вы имеете в виду? Это намного более scalatesty в форме. Мне не удалось заставить работать gen (там какое-то странное взаимодействие с chisel), и я больше знаком с FreeSpec, поэтому начал с него. Я также добавил printf и println, чтобы вы могли поверить, что это работает. Это работает и с бэкендом интерпретатора.

import org.scalatest.FreeSpec
import org.scalacheck.Prop.AnyOperators
import chisel3._
import chisel3.iotesters.PeekPokeTester

class Add2 extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(G.width.W))
    val b = Input(UInt(G.width.W))
    val o = Output(UInt(G.width.W))
  })
  io.o := io.a + io.b
  printf("%d = %d + %d\n", io.o, io.a, io.b)
}

class ScalaTestyTester extends FreeSpec {
  "scalatest verilator test" in {
    iotesters.Driver.execute(Array("--backend-name", "verilator"), () => new Add2) { c =>
      new PeekPokeTester(c) {
        for(_ <- 0 until 10) {
          val a = BigInt(G.width, scala.util.Random)
          val b = BigInt(G.width, scala.util.Random)
          println(s"testing a = $a b = $b")
          val result = (a + b) & ((1 << G.width) - 1)
          poke(c.io.a, a)
          poke(c.io.b, b)
          step(1)
          peek(c.io.o) ?= result
        }
      }
    }
  }
}
person Chick Markley    schedule 09.05.2017
comment
Я надеялся на решение в стиле scalacheck. Моя проблема в том, что я не могу получить тестовый класс как из свойств (бегун scalacheck), так и из PeekPokeTester. Делегирование работает с первым интерпретатором. Есть ли способ создать экземпляр PeekPokeTester (или какого-либо другого тестера на основе VCS), а затем выполнить вызовы метода peek/poke для этого экземпляра? - person Steve Burns; 10.05.2017