diff options
Diffstat (limited to 'fuzzer/src')
| -rw-r--r-- | fuzzer/src/main/scala/firrtl/ExprGenParams.scala | 65 | ||||
| -rw-r--r-- | fuzzer/src/main/scala/firrtl/FirrtlCompileTests.scala | 54 | ||||
| -rw-r--r-- | fuzzer/src/main/scala/firrtl/FirrtlEquivalenceTest.scala | 59 |
3 files changed, 117 insertions, 61 deletions
diff --git a/fuzzer/src/main/scala/firrtl/ExprGenParams.scala b/fuzzer/src/main/scala/firrtl/ExprGenParams.scala index ddaec00d..4c11b860 100644 --- a/fuzzer/src/main/scala/firrtl/ExprGenParams.scala +++ b/fuzzer/src/main/scala/firrtl/ExprGenParams.scala @@ -1,5 +1,8 @@ package firrtl.fuzzer +import com.pholser.junit.quickcheck.generator.{Generator, GenerationStatus} +import com.pholser.junit.quickcheck.random.SourceOfRandomness + import firrtl.{Namespace, Utils} import firrtl.ir._ @@ -17,15 +20,15 @@ sealed trait ExprGenParams { */ def maxWidth: Int - /** A list of frequency/expression generator pairs + /** A mapping of expression generator to frequency * * The frequency number determines the probability that the corresponding - * generator will be chosen. i.e. for sequece Seq(1 -> A, 2 -> B, 3 -> C), - * the probabilities for A, B, and C are 1/6, 2/6, and 3/6 respectively. - * This sequency must be non-empty and all frequency numbers must be greater - * than zero. + * generator will be chosen. i.g. for Map(A -> 1, B -> 2, C -> B), the + * probabilities for A, B, and C are 1/6, 2/6, and 3/6 respectively. This + * map must be non-empty and all frequency numbers must be greater than + * zero. */ - def generators: Seq[(Int, ExprGen[_ <: Expression])] + def generators: Map[ExprGen[_ <: Expression], Int] /** The set of generated references that don't have a corresponding declaration */ @@ -102,10 +105,46 @@ sealed trait ExprGenParams { object ExprGenParams { + val defaultGenerators: Map[ExprGen[_ <: Expression], Int] = { + import ExprGen._ + Map( + AddDoPrimGen -> 1, + SubDoPrimGen -> 1, + MulDoPrimGen -> 1, + DivDoPrimGen -> 1, + LtDoPrimGen -> 1, + LeqDoPrimGen -> 1, + GtDoPrimGen -> 1, + GeqDoPrimGen -> 1, + EqDoPrimGen -> 1, + NeqDoPrimGen -> 1, + PadDoPrimGen -> 1, + ShlDoPrimGen -> 1, + ShrDoPrimGen -> 1, + DshlDoPrimGen -> 1, + CvtDoPrimGen -> 1, + NegDoPrimGen -> 1, + NotDoPrimGen -> 1, + AndDoPrimGen -> 1, + OrDoPrimGen -> 1, + XorDoPrimGen -> 1, + AndrDoPrimGen -> 1, + OrrDoPrimGen -> 1, + XorrDoPrimGen -> 1, + CatDoPrimGen -> 1, + BitsDoPrimGen -> 1, + HeadDoPrimGen -> 1, + TailDoPrimGen -> 1, + AsUIntDoPrimGen -> 1, + AsSIntDoPrimGen -> 1, + MuxGen -> 1 + ) + } + private case class ExprGenParamsImp( maxDepth: Int, maxWidth: Int, - generators: Seq[(Int, ExprGen[_ <: Expression])], + generators: Map[ExprGen[_ <: Expression], Int], protected val unboundRefs: Set[Reference], protected val namespace: Namespace) extends ExprGenParams { @@ -119,7 +158,7 @@ object ExprGenParams { def apply( maxDepth: Int, maxWidth: Int, - generators: Seq[(Int, ExprGen[_ <: Expression])] + generators: Map[ExprGen[_ <: Expression], Int] ): ExprGenParams = { require(maxWidth > 0, "maxWidth must be greater than zero") ExprGenParamsImp( @@ -190,7 +229,8 @@ object ExprGenParams { ))(tpe).map(e => e.get) // should be safe because leaf generators are defined for all types val branchGen: Type => StateGen[ExprGenParams, G, Expression] = (tpe: Type) => { - combineExprGens(s.generators)(tpe).flatMap { + val gens = s.generators.toSeq.map { case (gen, freq) => (freq, gen) } + combineExprGens(gens)(tpe).flatMap { case None => leafGen(tpe) case Some(e) => StateGen.pure(e) } @@ -211,3 +251,10 @@ object ExprGenParams { } } } + +abstract class SingleExpressionCircuitGenerator(val params: ExprGenParams) extends Generator[Circuit](classOf[Circuit]) { + override def generate(random: SourceOfRandomness, status: GenerationStatus): Circuit = { + implicit val r = random + params.generateSingleExprCircuit[SourceOfRandomnessGen]() + } +} diff --git a/fuzzer/src/main/scala/firrtl/FirrtlCompileTests.scala b/fuzzer/src/main/scala/firrtl/FirrtlCompileTests.scala index 9ee8e52b..3091e4d6 100644 --- a/fuzzer/src/main/scala/firrtl/FirrtlCompileTests.scala +++ b/fuzzer/src/main/scala/firrtl/FirrtlCompileTests.scala @@ -53,50 +53,14 @@ object SourceOfRandomnessGen { } } - -class FirrtlSingleModuleGenerator extends Generator[Circuit](classOf[Circuit]) { - override def generate(random: SourceOfRandomness, status: GenerationStatus): Circuit = { - implicit val r = random - import ExprGen._ - - val params = ExprGenParams( - maxDepth = 50, - maxWidth = 31, - generators = Seq( - 1 -> AddDoPrimGen, - 1 -> SubDoPrimGen, - 1 -> MulDoPrimGen, - 1 -> DivDoPrimGen, - 1 -> LtDoPrimGen, - 1 -> LeqDoPrimGen, - 1 -> GtDoPrimGen, - 1 -> GeqDoPrimGen, - 1 -> EqDoPrimGen, - 1 -> NeqDoPrimGen, - 1 -> PadDoPrimGen, - 1 -> ShlDoPrimGen, - 1 -> ShrDoPrimGen, - 1 -> DshlDoPrimGen, - 1 -> CvtDoPrimGen, - 1 -> NegDoPrimGen, - 1 -> NotDoPrimGen, - 1 -> AndDoPrimGen, - 1 -> OrDoPrimGen, - 1 -> XorDoPrimGen, - 1 -> AndrDoPrimGen, - 1 -> OrrDoPrimGen, - 1 -> XorrDoPrimGen, - 1 -> CatDoPrimGen, - 1 -> BitsDoPrimGen, - 1 -> HeadDoPrimGen, - 1 -> TailDoPrimGen, - 1 -> AsUIntDoPrimGen, - 1 -> AsSIntDoPrimGen - ) - ) - params.generateSingleExprCircuit[SourceOfRandomnessGen]() - } -} +import ExprGen._ +class FirrtlCompileCircuitGenerator extends SingleExpressionCircuitGenerator ( + ExprGenParams( + maxDepth = 50, + maxWidth = 31, + generators = ExprGenParams.defaultGenerators + ) +) @RunWith(classOf[JQF]) class FirrtlCompileTests { @@ -112,7 +76,7 @@ class FirrtlCompileTests { } @Fuzz - def compileSingleModule(@From(value = classOf[FirrtlSingleModuleGenerator]) c: Circuit) = { + def compileSingleModule(@From(value = classOf[FirrtlCompileCircuitGenerator]) c: Circuit) = { compile(CircuitState(c, ChirrtlForm, Seq())) } diff --git a/fuzzer/src/main/scala/firrtl/FirrtlEquivalenceTest.scala b/fuzzer/src/main/scala/firrtl/FirrtlEquivalenceTest.scala index e0aa1707..822744c2 100644 --- a/fuzzer/src/main/scala/firrtl/FirrtlEquivalenceTest.scala +++ b/fuzzer/src/main/scala/firrtl/FirrtlEquivalenceTest.scala @@ -1,17 +1,19 @@ package firrtl.fuzzer import com.pholser.junit.quickcheck.From +import com.pholser.junit.quickcheck.generator.{Generator, GenerationStatus} +import com.pholser.junit.quickcheck.random.SourceOfRandomness -import edu.berkeley.cs.jqf.fuzz.Fuzz; -import edu.berkeley.cs.jqf.fuzz.JQF; +import edu.berkeley.cs.jqf.fuzz.{Fuzz, JQF}; import firrtl._ import firrtl.annotations.{Annotation, CircuitTarget, ModuleTarget, Target} import firrtl.ir.Circuit +import firrtl.options.Dependency import firrtl.stage.{FirrtlCircuitAnnotation, InfoModeAnnotation, OutputFileAnnotation, TransformManager} import firrtl.stage.Forms.{VerilogMinimumOptimized, VerilogOptimized} import firrtl.stage.phases.WriteEmitted -import firrtl.transforms.ManipulateNames +import firrtl.transforms.{InlineBooleanExpressions, ManipulateNames} import firrtl.util.BackendCompilationUtilities import java.io.{File, FileWriter, PrintWriter, StringWriter} @@ -89,6 +91,32 @@ object FirrtlEquivalenceTestUtils { } } +import ExprGen._ +class InlineBooleanExprsCircuitGenerator extends SingleExpressionCircuitGenerator ( + ExprGenParams( + maxDepth = 50, + maxWidth = 31, + generators = ExprGenParams.defaultGenerators ++ Map( + LtDoPrimGen -> 10, + LeqDoPrimGen -> 10, + GtDoPrimGen -> 10, + GeqDoPrimGen -> 10, + EqDoPrimGen -> 10, + NeqDoPrimGen -> 10, + AndDoPrimGen -> 10, + OrDoPrimGen -> 10, + XorDoPrimGen -> 10, + AndrDoPrimGen -> 10, + OrrDoPrimGen -> 10, + XorrDoPrimGen -> 10, + BitsDoPrimGen -> 10, + HeadDoPrimGen -> 10, + TailDoPrimGen -> 10, + MuxGen -> 10 + ) + ) +) + @RunWith(classOf[JQF]) class FirrtlEquivalenceTests { private val lowFirrtlCompiler = new LowFirrtlCompiler() @@ -103,8 +131,7 @@ class FirrtlEquivalenceTests { } private val baseTestDir = new File("fuzzer/test_run_dir") - @Fuzz - def compileSingleModule(@From(value = classOf[FirrtlSingleModuleGenerator]) c: Circuit) = { + private def runTest(c: Circuit, referenceCompiler: TransformManager, customCompiler: TransformManager) = { val testDir = new File(baseTestDir, f"${c.hashCode}%08x") testDir.mkdirs() val fileWriter = new FileWriter(new File(testDir, s"${c.main}.fir")) @@ -113,9 +140,9 @@ class FirrtlEquivalenceTests { val passed = try { FirrtlEquivalenceTestUtils.firrtlEquivalenceTestPass( circuit = c, - referenceCompiler = new TransformManager(VerilogMinimumOptimized), + referenceCompiler = referenceCompiler, referenceAnnos = Seq(), - customCompiler = new TransformManager(VerilogOptimized), + customCompiler = customCompiler, customAnnos = Seq(), testDir = testDir ) @@ -131,4 +158,22 @@ class FirrtlEquivalenceTests { s"not equivalent to reference compiler on input ${testDir}:\n${c.serialize}\n", false) } } + + @Fuzz + def testOptimized(@From(value = classOf[FirrtlCompileCircuitGenerator]) c: Circuit) = { + runTest( + c = c, + referenceCompiler = new TransformManager(VerilogMinimumOptimized), + customCompiler = new TransformManager(VerilogOptimized) + ) + } + + @Fuzz + def testInlineBooleanExpressions(@From(value = classOf[InlineBooleanExprsCircuitGenerator]) c: Circuit) = { + runTest( + c = c, + referenceCompiler = new TransformManager(VerilogMinimumOptimized), + customCompiler = new TransformManager(VerilogMinimumOptimized :+ Dependency[InlineBooleanExpressions]) + ) + } } |
