summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/AnnotatingExample.scala
blob: dc0d0421b0d3a5be317bafebf9ce155141efd080 (plain)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// See LICENSE for license details.

package chiselTests

import chisel3._
import chisel3.core.Module
import chisel3.internal.Builder
import chisel3.internal.firrtl.{Emitter, Circuit}
import chisel3.testers.BasicTester
import org.scalatest._
import org.scalatest.prop._

import scala.util.DynamicVariable

class SomeSubMod extends Module {
  val io = new Bundle {
    val in = UInt(INPUT, 16)
    val out = SInt(OUTPUT, 32)
  }
  MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.in, AllRefs))  = "sub mod io.in"
  MyBuilder.myDynamicContext.annotationMap(AnnotationKey(io.out, JustThisRef)) = "sub mod io.out"
}

class AnnotatingExample extends Module {
  val io = new Bundle {
    val a  = UInt(INPUT, 32)
    val b  = UInt(INPUT, 32)
    val e  = Bool(INPUT)
    val z  = UInt(OUTPUT, 32)
    val v  = Bool(OUTPUT)
    val bun = new Bundle {
      val nested_1 = UInt(INPUT, 12)
      val nested_2 = Bool(OUTPUT)
    }
  }
  val x = Reg(UInt(width = 32))
  val y = Reg(UInt(width = 32))

  val subModule1 = Module(new SomeSubMod)
  val subModule2 = Module(new SomeSubMod)


  val annotate = MyBuilder.myDynamicContext.annotationMap

  annotate(AnnotationKey(x, JustThisRef)) = "I am register X"
  annotate(AnnotationKey(io.a, JustThisRef)) = "I am io.a"
  annotate(AnnotationKey(io.bun.nested_1, JustThisRef)) = "I am io.bun.nested_1"
  annotate(AnnotationKey(io.bun.nested_2, JustThisRef)) = "I am io.bun.nested_2"

  when (x > y)   { x := x -% y }
  .otherwise     { y := y -% x }
  when (io.e) { x := io.a; y := io.b }
  io.z := x
  io.v := y === UInt(0)
}

class AnnotatingExampleTester(a: Int, b: Int, z: Int) extends BasicTester {
  val dut = Module(new AnnotatingExample)
  val first = Reg(init=Bool(true))
  dut.io.a := UInt(a)
  dut.io.b := UInt(b)
  dut.io.e := first
  when(first) { first := Bool(false) }
  when(!first && dut.io.v) {
    assert(dut.io.z === UInt(z))
    stop()
  }
}

class AnnotatingExampleSpec extends ChiselPropSpec {

  property("show node info") {
    MyDriver.doStuff { () => new AnnotatingExampleTester(1, 2, 3) }
  }

}

trait AnnotationScope
case object Default extends AnnotationScope
case object AllRefs extends AnnotationScope
case object JustThisRef extends AnnotationScope

case class AnnotationKey(val component: Data, scope: AnnotationScope)

class MyDynamicContext {
  val annotationMap = new scala.collection.mutable.HashMap[AnnotationKey, String]
}

object MyBuilder {
  private val myDynamicContextVar = new DynamicVariable[Option[MyDynamicContext]](None)

  def myDynamicContext: MyDynamicContext =
    myDynamicContextVar.value getOrElse (new MyDynamicContext)

  def build[T <: Module](f: => T): Unit = {
    myDynamicContextVar.withValue(Some(new MyDynamicContext)) {
      Driver.emit(() => f)
      val list = myDynamicContextVar.value.get.annotationMap.map { case (k,v) =>
        k match {
          case (AnnotationKey(signal, JustThisRef)) =>
            f"Just this ref ${signal.pathName + signal.signalName}%60s -> $v%30s  component $signal"
          case (AnnotationKey(signal, AllRefs)) =>
            f"All refs      ${signal.signalName}%60s -> $v%30s  component $signal"
          case  _ =>
            s"Unknown annotation key $k"
        }
      }.toList.sorted
      println(list.mkString("\n"))
    }
  }
}

object MyDriver extends BackendCompilationUtilities {
  def doStuff[T <: Module](gen: () => T): Unit = MyBuilder.build(Module(gen()))
}