/
ElaborationUtils.scala
65 lines (54 loc) · 2.1 KB
/
ElaborationUtils.scala
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
// See LICENSE for license details.
package midas.targetutils
import chisel3._
import chisel3.stage.ChiselStage
import firrtl.stage.{FirrtlPhase, FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation}
import org.scalatest.flatspec.AnyFlatSpec
trait ElaborationUtils { self: AnyFlatSpec =>
/**
* Elaborates the module returning the CHIRRTL for the circuit, and strictly
* the annotations produced as a side effect of elaboration.
*/
def elaborate(mod: =>Module): (firrtl.ir.Circuit, firrtl.AnnotationSeq) = ElaborateChiselSubCircuit(mod)
/**
* Our utitilies primarily generate new annotations. This method differs from
* upstream ChiselStage support in that this returns all annotations so that
* we may introspect on them and ensure the correctness of targetutils annotations
* after lowering and deduplication.
*/
def elaborateAndLower(mod: =>Module): Seq[firrtl.annotations.Annotation] = {
val (circuit, annos) = elaborate(mod)
val inputAnnos =
FirrtlCircuitAnnotation(circuit) ::
RunFirrtlTransformAnnotation(new firrtl.VerilogEmitter) ::
annos.toList
(new FirrtlPhase).transform(inputAnnos)
}
class AnnotateChiselTypeModule[T <: Data](gen: =>T, annotator: T => Unit) extends Module {
val io = IO(new Bundle {
val test = gen
annotator(test)
})
}
class AnnotateHardwareModule[T <: Data](gen: =>T, annotator: T => Unit) extends Module {
val io = IO(new Bundle {
val test = gen
})
annotator(io.test)
}
/**
* Instantiates a module with IO of the provided type twice, checking that the provided
* annotator croaks when used before the IO is still unbound, but not otherwise.
*
*/
def checkBehaviorOnUnboundTargets[T <: Data](gen: =>T, annotator: T => Unit) {
it should "elaborate and compile correctly when annotating HW types" in {
elaborate(new AnnotateHardwareModule(gen, annotator))
}
it should "reject unbound types at elaboration time" in {
assertThrows[ExpectedHardwareException] {
elaborate(new AnnotateChiselTypeModule(gen, annotator))
}
}
}
}