Files
chipyard/tapeout/src/test/scala/transforms/retime/RetimeSpec.scala
2020-12-11 14:51:43 -08:00

113 lines
3.5 KiB
Scala

// See LICENSE for license details.
package barstools.tapeout.transforms.retime.test
import chisel3._
import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation}
import barstools.tapeout.transforms.retime.RetimeLib
import firrtl.FileUtils
import logger.Logger
import org.scalatest.{FlatSpec, Matchers}
class RetimeSpec extends FlatSpec with Matchers {
def normalized(s: String): String = {
require(!s.contains("\n"))
s.replaceAll("\\s+", " ").trim
}
def uniqueDirName[T](gen: => T, name: String): String = {
val genClassName = gen.getClass.getName
name + genClassName.hashCode.abs
}
def getLowFirrtl[T <: RawModule](gen: () => T, extraArgs: Array[String] = Array.empty): String = {
// generate low firrtl
(new ChiselStage).execute(
Array("-X", "low") ++ extraArgs,
Seq(ChiselGeneratorAnnotation(gen))
).collect {
case EmittedFirrtlCircuitAnnotation(a) => a
case EmittedFirrtlModuleAnnotation(a) => a
}.map(_.value)
.mkString("")
}
behavior of "retime library"
it should "pass simple retime module annotation" in {
val gen = () => new RetimeModule
val dir = uniqueDirName(gen, "RetimeModule")
Logger.makeScope(Seq.empty) {
val captor = new Logger.OutputCaptor
Logger.setOutput(captor.printStream)
// generate low firrtl
val firrtl = getLowFirrtl(gen,
Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info"))
firrtl.nonEmpty should be(true)
//Make sure we got the RetimeTransform scheduled
captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform")
}
val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
.map(normalized)
.mkString("\n")
lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation")
lines should include(""""target":"RetimeModule.RetimeModule"""")
}
it should "pass simple retime instance annotation" in {
val gen = () => new RetimeInstance
val dir = uniqueDirName(gen, "RetimeInstance")
Logger.makeScope(Seq.empty) {
val captor = new Logger.OutputCaptor
Logger.setOutput(captor.printStream)
// generate low firrtl
val firrtl = getLowFirrtl(gen,
Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info"))
firrtl.nonEmpty should be(true)
//Make sure we got the RetimeTransform scheduled
captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform")
}
val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
.map(normalized)
.mkString("\n")
lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation")
lines should include(""""target":"RetimeInstance.MyModule"""")
}
}
class RetimeModule extends Module with RetimeLib {
val io = IO(new Bundle {
val in = Input(UInt(15.W))
val out = Output(UInt(15.W))
})
io.out := io.in
retime(this)
}
class MyModule extends Module with RetimeLib {
val io = IO(new Bundle {
val in = Input(UInt(15.W))
val out = Output(UInt(15.W))
})
io.out := io.in
}
class RetimeInstance extends Module with RetimeLib {
val io = IO(new Bundle {
val in = Input(UInt(15.W))
val out = Output(UInt(15.W))
})
val instance = Module(new MyModule)
retime(instance)
instance.io.in := io.in
io.out := instance.io.out
}