summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/BulkConnectSpec.scala
blob: 0a1616d3155cdcec6d2777e71c469582c59290e3 (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package chiselTests

import chisel3._
import chisel3.util.Decoupled
import chisel3.stage.ChiselStage
import chisel3.testers.BasicTester

class BulkConnectSpec extends ChiselPropSpec {
  property("Chisel connects should emit FIRRTL bulk connects when possible") {
    val chirrtl = ChiselStage.emitChirrtl(new Module {
      val io = IO(new Bundle {
        val inMono = Input(Vec(4, UInt(8.W)))
        val outMono = Output(Vec(4, UInt(8.W)))
        val inBi = Input(Vec(4, UInt(8.W)))
        val outBi = Output(Vec(4, UInt(8.W)))
      })
      io.outMono := io.inMono
      io.outBi <> io.inBi
    })
    chirrtl should include("io.outMono <= io.inMono")
    chirrtl should include("io.outBi <= io.inBi")
  }

  property("Chisel connects should not emit FIRRTL bulk connects for Stringly-typed connections") {
    object Foo {
      import Chisel._
      // Chisel._ bundle
      class BundleParent extends Bundle {
        val foo = UInt(width = 8)
      }
      class BundleChild extends BundleParent {
        val bar = UInt(width = 8)
      }
    }

    import Foo._

    // chisel3._ bundle
    class MyBundle(child: Boolean) extends Bundle {
      val fizz = UInt(8.W)
      val buzz = if (child) new BundleChild else new BundleParent
    }

    val chirrtl = ChiselStage.emitChirrtl(new Module {
      // Checking MonoConnect
      val in = IO(Input(new MyBundle(true)))
      val out = IO(Output(new MyBundle(false)))
      out := in

      // Checking BulkConnect (with Decoupled)
      val enq = IO(Flipped(Decoupled(new BundleChild)))
      val deq = IO(Decoupled(new BundleParent))
      deq <> enq
    })

    chirrtl should include("out.buzz.foo <= in.buzz.foo")
    chirrtl should include("out.fizz <= in.fizz")
    chirrtl should include("deq.bits <- enq.bits")
    chirrtl should include("deq.valid <= enq.valid")
    chirrtl should include("enq.ready <= deq.ready")

    chirrtl shouldNot include("deq <= enq")
    chirrtl shouldNot include("deq.bits.foo <= enq.bits.foo")
    chirrtl shouldNot include("deq.bits.foo <- enq.bits.foo")
    chirrtl shouldNot include("deq.bits.bar")
  }

  property("Chisel connects should not emit FIRRTL bulk connects between differing FIRRTL types") {
    val chirrtl = ChiselStage.emitChirrtl(new Module {
      val in = IO(Flipped(new Bundle {
        val foo = Flipped(new Bundle {
          val bar = Input(UInt(8.W))
        })
      }))
      val out = IO(Output(new Bundle {
        val foo = new Bundle {
          val bar = UInt(8.W)
        }
      }))
      // Both of these connections are legal in Chisel, but in and out do not have the same type
      out := in
      out <> in
    })
    // out <- in is illegal FIRRTL
    exactly(2, chirrtl.split('\n')) should include("out.foo.bar <= in.foo.bar")
    chirrtl shouldNot include("out <= in")
    chirrtl shouldNot include("out <- in")
  }

  property("Chisel connects should not emit a FIRRTL bulk connect for a bidirectional MonoConnect") {
    val chirrtl = ChiselStage.emitChirrtl(new Module {
      val enq = IO(Flipped(Decoupled(UInt(8.W))))
      val deq = IO(Decoupled(UInt(8.W)))

      // Implicitly create a MonoConnect from enq to a wire
      // enq is a Decoupled and so has input/output signals
      // We should not bulk connect in this case
      val wire = WireDefault(enq)
      dontTouch(wire)
      deq <> enq
    })

    chirrtl shouldNot include("wire <= enq")
    chirrtl should include("wire.bits <= enq.bits")
    chirrtl should include("wire.valid <= enq.valid")
    chirrtl should include("wire.ready <= enq.ready")
    chirrtl should include("deq <= enq")
  }

  property("Chisel connects should not emit a FIRRTL bulk connect for BlackBox IO Bundles") {
    class MyBundle extends Bundle {
      val O: Bool = Output(Bool())
      val I: Bool = Input(Bool())
    }

    val chirrtl = ChiselStage.emitChirrtl(new Module {
      val io: MyBundle = IO(Flipped(new MyBundle))

      val bb = Module(new BlackBox {
        val io: MyBundle = IO(Flipped(new MyBundle))
      })

      io <> bb.io
    })
    // There won't be a bb.io Bundle in FIRRTL, so connections have to be done element-wise
    chirrtl should include("bb.O <= io.O")
    chirrtl should include("io.I <= bb.I")
  }

  property("MonoConnect should bulk connect undirectioned internal wires") {
    val chirrtl = ChiselStage.emitChirrtl(new Module {
      val io = IO(new Bundle {})
      val w1 = Wire(Vec(2, UInt(8.W)))
      val w2 = Wire(Vec(2, UInt(8.W)))
      w2 := w1
    })
    chirrtl should include("w2 <= w1")
  }
}