summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/LiteralExtractorSpec.scala
blob: 25979488225c55e64cae525273edf68fe15d64f8 (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
116
117
118
119
120
121
122
123
124
// See LICENSE for license details.

package chiselTests

import chisel3._
import chisel3.core.FixedPoint
import chisel3.experimental.RawModule
import chisel3.testers.BasicTester
import org.scalatest._

class LiteralExtractorSpec extends ChiselFlatSpec {
  "litValue" should "return the literal value" in {
    assert(0.U.litValue === BigInt(0))
    assert(1.U.litValue === BigInt(1))
    assert(42.U.litValue === BigInt(42))
    assert(42.U.litValue === 42.U.litValue)

    assert(0.S.litValue === BigInt(0))
    assert(-1.S.litValue === BigInt(-1))
    assert(-42.S.litValue === BigInt(-42))

    assert(true.B.litValue === BigInt(1))
    assert(false.B.litValue === BigInt(0))

    assert(1.25.F(2.BP).litValue === BigInt("101", 2))
    assert(2.25.F(2.BP).litValue === BigInt("1001", 2))

    assert(-1.25.F(2.BP).litValue === BigInt("-101", 2))
    assert(-2.25.F(2.BP).litValue === BigInt("-1001", 2))
  }

  "litToBoolean" should "return the literal value" in {
    assert(true.B.litToBoolean === true)
    assert(false.B.litToBoolean === false)

    assert(1.B.litToBoolean === true)
    assert(0.B.litToBoolean === false)
  }

  "litToDouble" should "return the literal value" in {
    assert(1.25.F(2.BP).litToDouble == 1.25)
    assert(2.25.F(2.BP).litToDouble == 2.25)

    assert(-1.25.F(2.BP).litToDouble == -1.25)
    assert(-2.25.F(2.BP).litToDouble == -2.25)

    // test rounding
    assert(1.24.F(1.BP).litToDouble == 1.0)
    assert(1.25.F(1.BP).litToDouble == 1.5)
  }

  "litOption" should "return None for non-literal hardware" in {
    elaborate { new RawModule {
      val a = Wire(UInt())
      assert(a.litOption == None)
    }}
  }


  "literals declared outside a builder context" should "compare with those inside builder context" in {
    class InsideBundle extends Bundle {
      val x = SInt(8.W)
      val y = FixedPoint(8.W, 4.BP)

      import chisel3.core.BundleLitBinding
      def Lit(aVal: SInt, bVal: FixedPoint): InsideBundle = { // scalastyle:ignore method.name
        val clone = cloneType
        clone.selfBind(BundleLitBinding(Map(
          clone.x -> litArgOfBits(aVal),
          clone.y -> litArgOfBits(bVal)
        )))
        clone
      }
    }

    class LitInsideOutsideTester(outsideLiteral: InsideBundle) extends BasicTester {
      val insideLiteral = (new InsideBundle).Lit(7.S, 6.125.F(4.BP))

      // the following errors with "assertion failed"

      println(outsideLiteral === insideLiteral) // scalastyle:ignore regex
      // chisel3.core.assert(outsideLiteral === insideLiteral)

      // the following lines of code error
      // with "chisel3.core.BundleLitBinding cannot be cast to chisel3.core.ElementLitBinding"

      chisel3.core.assert(outsideLiteral.x === insideLiteral.x)
      chisel3.core.assert(outsideLiteral.y === insideLiteral.y)
      chisel3.core.assert(outsideLiteral.x === 7.S)
      chisel3.core.assert(outsideLiteral.y === 6.125.F(4.BP))

      stop()
    }

    val outsideLiteral = (new InsideBundle).Lit(7.S, 6.125.F(4.BP))
    assertTesterPasses{ new LitInsideOutsideTester(outsideLiteral) }

  }


  "bundle literals" should "do the right thing" in {
    class MyBundle extends Bundle {
      val a = UInt(8.W)
      val b = Bool()

      // Bundle literal constructor code, which will be auto-generated using macro annotations in
      // the future.
      import chisel3.core.BundleLitBinding
      import chisel3.internal.firrtl.{ULit, Width}
      def Lit(aVal: UInt, bVal: Bool): MyBundle = { // scalastyle:ignore method.name
        val clone = cloneType
        clone.selfBind(BundleLitBinding(Map(
          clone.a -> litArgOfBits(aVal),
          clone.b -> litArgOfBits(bVal)
        )))
        clone
      }
    }
    val myBundleLiteral = (new MyBundle).Lit(42.U, true.B)
    assert(myBundleLiteral.a.litValue == 42)
    assert(myBundleLiteral.b.litValue == 1)
    assert(myBundleLiteral.b.litToBoolean == true)
  }
}