summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/CompileOptionsTest.scala
blob: cc0a966cf5e6e5782a4d30b8360974c51897488a (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
// See LICENSE for license details.

package chiselTests

import org.scalatest._
import chisel3._
import chisel3.core.Binding.BindingException
import chisel3.core.ExplicitCompileOptions
import chisel3.testers.BasicTester
import chisel3.core.CompileOptions

class CompileOptionsSpec extends ChiselFlatSpec {

  abstract class StrictModule extends Module()(chisel3.core.ExplicitCompileOptions.Strict)
  abstract class NotStrictModule extends Module()(chisel3.core.ExplicitCompileOptions.NotStrict)

  // Generate a set of options that do not have requireIOWrap enabled, in order to
  // ensure its definition comes from the implicit options passed to the Module constructor.
  object StrictWithoutIOWrap extends CompileOptions {
    val connectFieldsMustMatch = true
    val declaredTypeMustBeUnbound = true
    val requireIOWrap = false
    val dontTryConnectionsSwapped = true
    val dontAssumeDirectionality = true
    val deprecateOldDirectionMethods = true
    val checkSynthesizable = true
  }

  class SmallBundle extends Bundle {
    val f1 = UInt(4.W)
    val f2 = UInt(5.W)
    override def cloneType: this.type = (new SmallBundle).asInstanceOf[this.type]
  }
  class BigBundle extends SmallBundle {
    val f3 = UInt(6.W)
    override def cloneType: this.type = (new BigBundle).asInstanceOf[this.type]
  }

  "A Module with missing bundle fields when compiled with implicit Strict.CompileOption " should "throw an exception" in {
    a [ChiselException] should be thrownBy {
      import chisel3.core.ExplicitCompileOptions.Strict

      class ConnectFieldMismatchModule extends Module {
        val io = IO(new Bundle {
          val in = Input(new SmallBundle)
          val out = Output(new BigBundle)
        })
        io.out := io.in
      }
      elaborate { new ConnectFieldMismatchModule() }
    }
  }

  "A Module with missing bundle fields when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.NotStrict

    class ConnectFieldMismatchModule extends Module {
      val io = IO(new Bundle {
        val in = Input(new SmallBundle)
        val out = Output(new BigBundle)
      })
      io.out := io.in
    }
    elaborate { new ConnectFieldMismatchModule() }
  }

  "A Module in which a Reg is created with a bound type when compiled with implicit Strict.CompileOption " should "throw an exception" in {
    a [BindingException] should be thrownBy {
      import chisel3.core.ExplicitCompileOptions.Strict

      class CreateRegFromBoundTypeModule extends Module {
        val io = IO(new Bundle {
          val in = Input(new SmallBundle)
          val out = Output(new BigBundle)
        })
        val badReg = Reg(7.U(4.W))
      }
      elaborate { new CreateRegFromBoundTypeModule() }
    }
  }

  "A Module in which a Reg is created with a bound type when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.NotStrict

    class CreateRegFromBoundTypeModule extends Module {
      val io = IO(new Bundle {
        val in = Input(new SmallBundle)
        val out = Output(new BigBundle)
      })
      val badReg = Reg(7.U(4.W))
    }
    elaborate { new CreateRegFromBoundTypeModule() }
  }

  "A Module with wrapped IO when compiled with implicit Strict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.Strict

    class RequireIOWrapModule extends Module {
      val io = IO(new Bundle {
        val in = UInt(32.W).asInput
        val out = Bool().asOutput
      })
      io.out := io.in(1)
    }
    elaborate { new RequireIOWrapModule() }
}

  "A Module with unwrapped IO when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.NotStrict

    class RequireIOWrapModule extends Module {
      val io = new Bundle {
        val in = UInt(32.W).asInput
        val out = Bool().asOutput
      }
      io.out := io.in(1)
    }
      elaborate { new RequireIOWrapModule() }
  }

  "A Module with unwrapped IO when compiled with implicit Strict.CompileOption " should "throw an exception" in {
    a [BindingException] should be thrownBy {
      import chisel3.core.ExplicitCompileOptions.Strict

      class RequireIOWrapModule extends Module {
        val io = new Bundle {
          val in = UInt(32.W).asInput
          val out = Bool().asOutput
        }
        io.out := io.in(1)
      }
      elaborate {
        new RequireIOWrapModule()
      }
    }
  }

  "A Module connecting output as source to input as sink when compiled with implicit Strict.CompileOption " should "throw an exception" in {
    a [ChiselException] should be thrownBy {
      import chisel3.core.ExplicitCompileOptions.Strict

      class SimpleModule extends Module {
        val io = IO(new Bundle {
          val in = Input(UInt(3.W))
          val out = Output(UInt(4.W))
        })
      }
      class SwappedConnectionModule extends SimpleModule {
        val child = Module(new SimpleModule)
        io.in := child.io.out
      }
      elaborate { new SwappedConnectionModule() }
    }
  }

  "A Module connecting output as source to input as sink when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.NotStrict

    class SimpleModule extends Module {
      val io = IO(new Bundle {
        val in = Input(UInt(3.W))
        val out = Output(UInt(4.W))
      })
    }
    class SwappedConnectionModule extends SimpleModule {
      val child = Module(new SimpleModule)
      io.in := child.io.out
    }
    elaborate { new SwappedConnectionModule() }
  }

  "A Module with directionless connections when compiled with implicit Strict.CompileOption " should "throw an exception" in {
    a [ChiselException] should be thrownBy {
      // Verify we can suppress the inclusion of default compileOptions
      import Chisel.{defaultCompileOptions => _, _}
      import chisel3.core.ExplicitCompileOptions.Strict

      class SimpleModule extends Module {
        val io = IO(new Bundle {
          val in = Input(UInt(3.W))
          val out = Output(UInt(4.W))
        })
        val noDir = Wire(UInt(3.W))
      }

      class DirectionLessConnectionModule extends SimpleModule {
        val a = 0.U(3.W)
        val b = Wire(UInt(3.W))
        val child = Module(new SimpleModule)
        b := child.noDir
      }
      elaborate { new DirectionLessConnectionModule() }
    }
  }

  "A Module with directionless connections when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
    import chisel3.core.ExplicitCompileOptions.NotStrict

    class SimpleModule extends Module {
      val io = IO(new Bundle {
        val in = Input(UInt(3.W))
        val out = Output(UInt(4.W))
      })
      val noDir = Wire(UInt(3.W))
    }

    class DirectionLessConnectionModule extends SimpleModule {
      val a = 0.U(3.W)
      val b = Wire(UInt(3.W))
      val child = Module(new SimpleModule)
      b := child.noDir
    }
    elaborate { new DirectionLessConnectionModule() }
  }

  "A Module with wrapped IO when compiled with explicit Strict.CompileOption " should "not throw an exception" in {
    implicit val strictWithoutIOWrap = StrictWithoutIOWrap
    class RequireIOWrapModule extends StrictModule {
      val io = IO(new Bundle {
        val in = UInt(32.W).asInput
        val out = Bool().asOutput
      })
      io.out := io.in(1)
    }
    elaborate {
      new RequireIOWrapModule()
    }
  }

  "A Module with unwrapped IO when compiled with explicit NotStrict.CompileOption " should "not throw an exception" in {
    implicit val strictWithoutIOWrap = StrictWithoutIOWrap
    class RequireIOWrapModule extends NotStrictModule {
      val io = new Bundle {
        val in = UInt(32.W).asInput
        val out = Bool().asOutput
      }
      io.out := io.in(1)
    }
    elaborate {
      new RequireIOWrapModule()
    }
  }

  "A Module with unwrapped IO when compiled with explicit Strict.CompileOption " should "throw an exception" in {
    a [BindingException] should be thrownBy {
      implicit val strictWithoutIOWrap = StrictWithoutIOWrap
      class RequireIOWrapModule extends StrictModule {
        val io = new Bundle {
          val in = UInt(32.W).asInput
          val out = Bool().asOutput
        }
        io.out := io.in(1)
      }
      elaborate {
        new RequireIOWrapModule()
      }
    }
  }

  "A Module with unwrapped IO when compiled with an explicit requireIOWrap false " should "not throw an exception" in {

    object StrictNotIOWrap {

      implicit object CompileOptions extends CompileOptions {
        val connectFieldsMustMatch = true
        val declaredTypeMustBeUnbound = true
        val requireIOWrap = false
        val dontTryConnectionsSwapped = true
        val dontAssumeDirectionality = true
        val deprecateOldDirectionMethods = false
        val checkSynthesizable = true
      }

    }
    class NotIOWrapModule extends Module()(StrictNotIOWrap.CompileOptions) {
      val io = new Bundle {
        val in = UInt(32.W).asInput
        val out = Bool().asOutput
      }
    }
    elaborate {
      new NotIOWrapModule()
    }
  }
}