1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// SPDX-License-Identifier: Apache-2.0
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 firrtl.{ChirrtlForm, CircuitState, LowFirrtlCompiler}
import firrtl.ir.Circuit
import org.junit.Assert
import org.junit.runner.RunWith
import java.io.{PrintWriter, StringWriter}
import edu.berkeley.cs.jqf.fuzz.Fuzz;
import edu.berkeley.cs.jqf.fuzz.JQF;
/** a GenMonad backed by [[com.pholser.junit.quickcheck.random.SourceOfRandomness SourceOfRandomness]]
*/
trait SourceOfRandomnessGen[A] {
def apply(): A
def flatMap[B](f: A => SourceOfRandomnessGen[B]): SourceOfRandomnessGen[B] =
SourceOfRandomnessGen { f(apply())() }
def map[B](f: A => B): SourceOfRandomnessGen[B] =
SourceOfRandomnessGen { f(apply()) }
def widen[B >: A]: SourceOfRandomnessGen[B] =
SourceOfRandomnessGen { apply() }
}
object SourceOfRandomnessGen {
implicit def sourceOfRandomnessGenGenMonadInstance(implicit r: SourceOfRandomness): GenMonad[SourceOfRandomnessGen] = new GenMonad[SourceOfRandomnessGen] {
import scala.collection.JavaConverters.seqAsJavaListConverter
type G[T] = SourceOfRandomnessGen[T]
def flatMap[A, B](a: G[A])(f: A => G[B]): G[B] = a.flatMap(f)
def map[A, B](a: G[A])(f: A => B): G[B] = a.map(f)
def choose(min: Int, max: Int): G[Int] = SourceOfRandomnessGen {
r.nextLong(min, max).toInt // use r.nextLong instead of r.nextInt because r.nextInt is exclusive of max
}
def oneOf[T](items: T*): G[T] = {
val arr = seqAsJavaListConverter(items)
const(arr.asJava).map(r.choose(_))
}
def const[T](c: T): G[T] = SourceOfRandomnessGen(c)
def widen[A, B >: A](ga: G[A]): G[B] = ga.widen[B]
def generate[A](ga: G[A]): A = ga.apply()
}
def apply[T](f: => T): SourceOfRandomnessGen[T] = new SourceOfRandomnessGen[T] {
def apply(): T = f
}
}
import ExprGen._
class FirrtlCompileCircuitGenerator extends SingleExpressionCircuitGenerator (
ExprGenParams(
maxDepth = 50,
maxWidth = 31,
generators = ExprGenParams.defaultGenerators
)
)
@RunWith(classOf[JQF])
class FirrtlCompileTests {
private val lowFirrtlCompiler = new LowFirrtlCompiler()
private val header = "=" * 50 + "\n"
private val footer = header
private def message(c: Circuit, t: Throwable): String = {
val sw = new StringWriter()
val pw = new PrintWriter(sw)
t.printStackTrace(pw)
pw.flush()
header + c.serialize + "\n" + sw.toString + footer
}
@Fuzz
def compileSingleModule(@From(value = classOf[FirrtlCompileCircuitGenerator]) c: Circuit) = {
compile(CircuitState(c, ChirrtlForm, Seq()))
}
// adapted from chisel3.Driver.execute and firrtl.Driver.execute
def compile(c: CircuitState) = {
val compiler = lowFirrtlCompiler
try {
val res = compiler.compile(c, Seq())
} catch {
case e: firrtl.CustomTransformException =>
Assert.assertTrue(message(c.circuit, e.cause), false)
case any : Throwable =>
Assert.assertTrue(message(c.circuit, any), false)
}
}
}
|