运行 特定测试并从基于凿子模板的凿子项目中获取 Verilog

Running specific tests and getting Verilog from a Chisel project based on the chisel-template

在深入了解各种 Chisel 的东西之后,我决定是时候尝试我自己的东西了。出乎意料的是,这个东西,一个简单的东西,但是,我基于 chisel-template 做的东西成功了。

我什至设法通过 运行 最简单的测试来确认这一点。它是一个虚拟的 32 位 ALU,其中包含(目前)用于按位运算的子模块。我根据现有的 GCD 测试编写了测试,因此我的测试文件 Alu32UnitTest.scala 包含以下重要行:

package alu32
import chisel3.iotesters
import chisel3.iotesters.{PeekPokeTester,Driver,ChiselFlatSpec}
class Alu32BoolTests(dut: Alu32) extends PeekPokeTester(dut) {
    for (i <- 0 until 9) {
        //first provide random values
        val a = rnd.nextInt(256)
        val b = rnd.nextInt(256)
        val f = rnd.nextInt(16)

        //decide what to expect based on opcode
        var output = 0
        if (f == 8) {
            output = a & b
        } else if (f == 14) {
            output = a | b
        } else if (f == 6) {
            output = a ^ b
        } else output = 0

        //connect the generated inputs to dut
        poke(dut.io.a, a)
        poke(dut.io.b, b)
        poke(dut.io.f, f)

        //clock
        step(1)

        //check if everything is where it should be
        expect(dut.io.y, output)
    }
}
}

class Alu32UnitTester extends ChiselFlatSpec {
    behavior of "Alu32"
    backends foreach {backend =>
    it should s"perform correct math operation on dynamic operand in $backend" 
    in {
      Driver(() => new Alu32, backend)((dut) => new Alu32BoolTests(dut)) should be (true)
    }
  }
}

我运行这个测试使用(在运行宁sbt之后):

> testOnly alu32.AluUnitTester

当它很好时它会正确地说 SUCCESS 并且当我更改 ALU 的内部结构时它会抱怨。我来到 testOnly 行,只是通过查看 chisel-template 的自述文件并在 testtestOnly 等之后按 [Tab] 键。

接下来我想做的是获取 Verilog 代码,所以我尝试 运行ning chisel-tutorial 提供的命令,我的意思是那些包括 run-main 的命令。当然,这会导致错误,因为我意识到,在我的 Alu32UnitTest.scala 中没有定义这样的测试所以我尝试调整 GCD 中找到的行,这让我注意到 tests/scala 中的另一个文件 - a GCDMain.scala。所以我继续将其改编为:

package alu32

import chisel3._

object Alu32Main extends App {
  iotesters.Driver.execute(args, () => new Alu32) {
    dut => new Alu32UnitTester(dut)
  }
}

object Alu32Repl extends App {
  iotesters.Driver.executeFirrtlRepl(args, () => new Alu32)
}

并将其命名为 Alu32Main.scala。创建了那个,现在什么都没有了:)

当我尝试那个有效的方法时:

> testOnly alu32.AluUnitTester

我现在得到以下回复:

[info] Compiling 1 Scala source to /home/apaj/ChiselProjects/alu32/target/scala-2.11/classes...
[warn] there were 8 feature warnings; re-run with -feature for details
[warn] one warning found
[info] Compiling 1 Scala source to /home/apaj/ChiselProjects/alu32/target/scala-2.11/test-classes...
[error] /home/apaj/ChiselProjects/alu32/src/test/scala/alu32/alu32Main.scala:7: too many arguments for constructor Alu32UnitTester: ()alu32.Alu32UnitTester
[error]     dut => new Alu32UnitTester(dut)
[error]            ^
[error] one error found
[error] (test:compileIncremental) Compilation failed
[error] Total time: 10 s, completed Jan 15, 2018 5:16:12 PM

我注意到它是如何抱怨有很多争论的。但是,如果删除参数 dut,它会抱怨类型不匹配。

有一次,不知何故,我不记得是如何重构的,我确实得到了类似于所提供的响应 ,但我真的不记得是如何重构的。

我确信这是一个初学者的问题,忽略了一些可能很明显的东西,所以我希望你能抽出时间来帮忙。

非常感谢。

我认为问题在于您打算参考您的 PeekPokeTester 实现 class Alu32BoolTests(dut: Alu32) 而不是 你的 scala 测试工具 class Alu32UnitTester.
具体来说,第 7 行应该是

dut => new Alu32BoolTests(dut)

而不是

dut => new Alu32UnitTester(dut)

这只是为了完整性,主要问题已由 Chick Marley 的回答解决。但是,由于问题的第二部分是关于获取 Verilog,因此需要添加到 alu32UnitTests.scala:

class Alu32Tester extends ChiselFlatSpec {
  private val backendNames = if(firrtl.FileUtils.isCommandAvailable("verilator")) {
    Array("firrtl", "verilator")
  }
  else {
    Array("firrtl")
  }
  for ( backendName <- backendNames ) {
    "Alu32" should s"calculate proper greatest common denominator (with $backendName)" in {
      Driver(() => new Alu32, backendName) {
        c => new Alu32BoolTests(c)
      } should be (true)
    }
  }

  "Basic test using Driver.execute" should "be used as an alternative way to run specification" in {
    iotesters.Driver.execute(Array(), () => new Alu32) {
      c => new Alu32BoolTests(c)
    } should be (true)
  }

  "using --backend-name verilator" should "be an alternative way to run using verilator" in {
    if(backendNames.contains("verilator")) {
      iotesters.Driver.execute(Array("--backend-name", "verilator"), () => new Alu32) {
        c => new Alu32BoolTests(c)
      } should be(true)
    }
  }

  "running with --is-verbose" should "show more about what's going on in your tester" in {
    iotesters.Driver.execute(Array("--is-verbose"), () => new Alu32) {
      c => new Alu32BoolTests(c)
    } should be(true)
  }

  "running with --fint-write-vcd" should "create a vcd file from your test" in {
    iotesters.Driver.execute(Array("--fint-write-vcd"), () => new Alu32) {
      c => new Alu32BoolTests(c)
    } should be(true)
  }

  "using --help" should s"show the many options available" in {
    iotesters.Driver.execute(Array("--help"), () => new Alu32) {
      c => new Alu32BoolTests(c)
    } should be (true)
  }
}

保存编译后得到Verilog如下:

test:runMain alu32.Alu32Main --backend-name=verilator